!IF "$(APPVEYOR_REPO_COMMIT)" != ""
BUILD_INFO="-DWATCHMAN_BUILD_INFO=""$(APPVEYOR_REPO_COMMIT) $(APPVEYOR_REPO_COMMIT_TIMESTAMP)"""
!ENDIF

# Strict compilation, but suppress deprecation of POSIX and a couple of
# warnings that get generated by the system headers
#PEDANTIC=/Wall /wd4555 /wd4221 /wd4210 /wd4152 /wd4204 /wd4127 /wd4996 /wd4820 /wd4255 /wd4668 /wd4201 /wd4232 /wd4710 /wd4214
CFLAGS=/nologo /MP /WX /Zi /Zo /Oi /MT /I $(MAKEDIR)\winbuild /I $(MAKEDIR) /I $(MAKEDIR)\thirdparty\jansson /FS $(BUILD_INFO)

CXXFLAGS=$(CFLAGS) /EHsc
LIBS=shlwapi.lib advapi32.lib dbghelp.lib
LINKER=link /nologo /out:$@ /debug /incremental:no /opt:ref /opt:icf /pdb:$(@:.exe=.pdb)

JSON_SRCS=\
	thirdparty\jansson\dump.cpp \
	thirdparty\jansson\error.cpp \
	thirdparty\jansson\load.cpp \
	thirdparty\jansson\memory.cpp \
	thirdparty\jansson\pack_unpack.cpp \
	thirdparty\jansson\strbuffer.cpp \
	thirdparty\jansson\strconv.cpp \
	thirdparty\jansson\utf.cpp \
	thirdparty\jansson\value.cpp

SRCS_C=\
	thirdparty\wildmatch\wildmatch.c \

SRCS_CPP=\
	$(JSON_SRCS) \
	ChildProcess.cpp \
	ContentHash.cpp \
	CookieSync.cpp \
	FileDescriptor.cpp \
	FileInformation.cpp \
	InMemoryView.cpp \
	Pipe.cpp \
	PubSub.cpp \
	ThreadPool.cpp \
	QueryableView.cpp \
	winbuild\errmap.cpp \
	winbuild\pathmap.cpp \
	winbuild\mkdir.cpp \
	winbuild\dir.cpp \
	winbuild\asprintf.cpp \
	winbuild\hostname.cpp \
	winbuild\time.cpp \
	winbuild\backtrace.cpp \
	winbuild\getopt_long.cpp \
	winbuild\posix_spawn.cpp \
	ignore.cpp \
	spawn.cpp \
	opt.cpp \
	cfg.cpp \
	clockspec.cpp \
	checksock.cpp \
	error_category.cpp \
	fstype.cpp     \
	log.cpp        \
	json.cpp       \
	bser.cpp       \
	expflags.cpp   \
	hash.cpp       \
	ioprio.cpp     \
	opendir.cpp    \
	pending.cpp    \
	perf.cpp       \
	stream.cpp     \
	stream_win.cpp \
	stream_stdout.cpp \
	cmds\find.cpp     \
	cmds\info.cpp     \
	cmds\log.cpp      \
	cmds\query.cpp    \
	cmds\since.cpp    \
	cmds\reg.cpp      \
	cmds\state.cpp    \
	cmds\subscribe.cpp    \
	cmds\trigger.cpp  \
	cmds\watch.cpp    \
	cmds\debug.cpp    \
	query\base.cpp       \
	query\parse.cpp      \
	query\dirname.cpp    \
	query\eval.cpp       \
	query\glob.cpp       \
	query\type.cpp       \
	query\suffix.cpp     \
	query\match.cpp      \
	query\pcre.cpp       \
	query\name.cpp       \
	query\fieldlist.cpp  \
	query\intcompare.cpp  \
	query\since.cpp      \
	query\empty.cpp      \
	watcher\auto.cpp \
	watcher\win32.cpp \
	listener.cpp   \
	listener-user.cpp   \
	clientmode.cpp \
	main.cpp       \
	root\ageout.cpp       \
	root\crawler.cpp       \
	root\dir.cpp       \
	root\file.cpp       \
	root\init.cpp       \
	root\iothread.cpp       \
	root\notifythread.cpp       \
	root\poison.cpp       \
	root\reap.cpp       \
	root\resolve.cpp       \
	root\stat.cpp       \
	root\symlink.cpp       \
	root\sync.cpp       \
	root\threading.cpp       \
	root\vcs.cpp       \
	root\warnerr.cpp       \
	root\watchlist.cpp       \
	scm\Mercurial.cpp \
	scm\SCM.cpp \
	state.cpp      \
	string.cpp     \
	time.cpp

TEST_SRCS_C=\
	thirdparty\wildmatch\wildmatch.c

TEST_SRCS_CPP=\
	thirdparty\tap.cpp \
	winbuild\asprintf.cpp \
	winbuild\time.cpp \
	winbuild\backtrace.cpp \
	winbuild\errmap.cpp \
	$(JSON_SRCS)

TEST_DIR_SRCS=

TEST_DIR_SRCS_CPP=\
	tests\art_test.cpp \
	tests\bser.cpp \
	tests\childproc.cpp \
	tests\ResultTest.cpp \
	tests\ignore_test.cpp \
	tests\log_stub.cpp \
	tests\log.cpp

OBJS=$(SRCS_CPP:.cpp=.obj) $(SRCS_C:.c=.obj)
TEST_OBJS=$(TEST_SRCS_CPP:.cpp=.obj) $(TEST_SRCS_C:.c=.obj)
TEST_DIR_OBJS=$(TEST_DIR_SRCS:.c=.obj) $(TEST_DIR_SRCS_CPP:.cpp=.obj)
TESTS=tests\log.exe tests\bser.exe tests\wildmatch_test.exe \
			tests\art.exe tests\ignore.exe tests\pending.exe \
			tests\string.exe tests\childproc.exe tests\result.exe \
			tests\future.exe tests\cache.exe

{}.cpp{}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:.\ /c $<

{tests}.c{tests}.obj::
	@echo CC $<
	$(CC) $(CFLAGS) $(PEDANTIC) /Fo:tests\ /c $<

{tests}.cpp{tests}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:tests\ /c $<

{winbuild}.cpp{winbuild}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:winbuild\ /c $<

{cmds}.cpp{cmds}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:cmds\ /c $<

{query}.cpp{query}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:query\ /c $<

{watcher}.cpp{watcher}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:watcher\ /c $<

{root}.cpp{root}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:root\ /c $<

{scm}.cpp{scm}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) $(PEDANTIC) /Fo:scm\ /c $<

{thirdparty\wildmatch}.c{thirdparty\wildmatch}.obj::
	@echo CC $<
	$(CC) $(CFLAGS) /Fo:thirdparty\wildmatch\ /c $<

{thirdparty\jansson}.cpp{thirdparty\jansson}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) /Fo:thirdparty\jansson\ /c $<

{thirdparty}.cpp{thirdparty}.obj::
	@echo CXX $<
	$(CC) $(CXXFLAGS) /Fo:thirdparty\ /c $<

all: remove-config-h watchman.exe build-tests susres.exe

remove-config-h:
	-del config.h watchman

# problems with vcvarsall.bat? http://stackoverflow.com/a/10558328/149111
# The Visual Studio 2015 image on AppVeyor includes Visual Studio for Python
# and that MUST be used to compile the python extension.  The build system
# that we use locally does not have this installed, so we use our installed
# compiler.  To allow AppVeyor to use the python specific compiler without
# getting confused by our 2015 environment, we clear out the compiler
# related environment when we're running in AppVeyor.
py-build:
	if defined APPVEYOR set INCLUDE=
	if defined APPVEYOR set LIB=
	if defined APPVEYOR set LIBPATH=
	if defined APPVEYOR set VS90COMNTOOLS=
	cd python && python ./setup.py clean build_py -c -d . build_ext -i

py-integration: py-build
	python -u runtests.py --keep-if-fail --concurrency=1

# helper for suspending/resuming a target process
susres.exe: winbuild\susres.cpp
	$(CC) /Fesusres.exe winbuild\susres.cpp

integration: build-tests susres.exe py-integration

integration-win7: build-tests susres.exe py-build
	python -u runtests.py --keep-if-fail --concurrency=1 --win7

build-tests: $(TESTS)

watchman.exe: $(OBJS)
	@echo LINK $@
	$(LINKER) $(OBJS) $(LIBS)

tests\argv.exe: tests\argv.obj $(TEST_OBJS) \
	tests\log_stub.obj \
	PubSub.obj \
	argv.obj \
	string.obj \
	hash.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\art.exe: tests\art_test.obj $(TEST_OBJS) \
  	log.obj \
	tests\log_stub.obj \
	PubSub.obj \
	string.obj \
	hash.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\ignore.exe: tests\ignore_test.obj $(TEST_OBJS) \
		hash.obj \
		ignore.obj \
		string.obj \
		log.obj \
		PubSub.obj \
		tests\log_stub.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\string.exe: tests\string_test.obj $(TEST_OBJS) \
		hash.obj \
		string.obj \
		log.obj \
		PubSub.obj \
		tests\log_stub.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\pending.exe: tests\pending_test.obj $(TEST_OBJS) \
		hash.obj \
		ignore.obj \
		pending.obj \
		expflags.obj \
		opendir.obj \
		cfg.obj \
		time.obj \
		string.obj \
		stream_win.obj \
		stream.obj \
		log.obj \
		FileDescriptor.obj \
		PubSub.obj \
		FileInformation.obj \
		tests\log_stub.obj \
		winbuild\pathmap.obj \
		winbuild\mkdir.obj \
		winbuild\dir.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\bser.exe: tests\bser.obj bser.obj $(TEST_OBJS) \
	tests\log_stub.obj  \
	string.obj \
	hash.obj \
	PubSub.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\cache.exe: tests\CacheTest.obj $(TEST_OBJS) \
	tests\log_stub.obj  \
	string.obj \
	hash.obj \
	PubSub.obj \
	ThreadPool.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\future.exe: tests\FutureTest.obj $(TEST_OBJS) \
	tests\log_stub.obj  \
	string.obj \
	hash.obj \
	PubSub.obj \
	ThreadPool.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\result.exe: tests\ResultTest.obj $(TEST_OBJS) \
	tests\log_stub.obj  \
	string.obj \
	hash.obj \
	PubSub.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\childproc.exe: tests\childproc.obj $(TEST_OBJS) \
	tests\log_stub.obj  \
	ChildProcess.obj \
	winbuild\posix_spawn.obj \
	winbuild\pathmap.obj \
	Pipe.obj \
	FileDescriptor.obj \
	FileInformation.obj \
	string.obj \
	stream_win.obj \
	hash.obj \
	PubSub.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\log.exe: tests\log.obj log.obj $(TEST_OBJS) \
	PubSub.obj \
	string.obj \
	hash.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

tests\wildmatch_test.exe: tests\wildmatch_test.obj $(TEST_OBJS) \
	tests\log_stub.obj  \
	PubSub.obj \
	string.obj \
	hash.obj \
	log.obj
	@echo LINK $@
	$(LINKER) $** $(LIBS)

dist:
	-mkdir Watchman
	copy watchman.exe Watchman
	copy watchman.pdb Watchman
	copy LICENSE Watchman\LICENSE.txt
	copy README.markdown Watchman

clean:
	-del $(OBJS) $(TEST_OBJS) $(TEST_DIR_OBJS) *.exe

distclean: clean
