# (C) 2003 XDA Developers  itsme@xs4all.nl
#
# $Header$
#
out=../build
obj=../build/w32

ifneq ($(wildcard /sbin/bsdlabel),)
OSTYPE=freebsd
endif
ifneq ($(wildcard /System/Library/Extensions/AppleFileSystemDriver.kext),)
OSTYPE=darwin
endif
ifneq ($(wildcard /sbin/modprobe),)
OSTYPE=linux
endif

include ../local.mak

ccdefs=/D WIN32 /D NDEBUG /D _CONSOLE
ccdefs+=/D _CRT_SECURE_NO_WARNINGS /D _SECURE_SCL=0 /D _HAS_ITERATOR_DEBUGGING=0 /D NOMINMAX
ccdefs+=-wo4365 -wd4571

ccincs=/I "$(mssdk)\include" /I "$(vc8)/include" /I "$(ActiveSyncSupport)/inc" /I "../dll" /I "../include" /I "../common" /I "$(boost)" /I "../include/msvc"

#   - add '/Zi' when debugging is needed
#   vc8:  /analyze
cflags=/nologo /Wall /wd4710 /wd4217 /wd4668 /wd4820 /wd4619 /EHsc /wd4127 /wd4061 /wd4711 /wd4555 /wd4702 /wd4917 /wd4548 /wd4826 /wd4512 /wd4625 /wd4626
#  4626 : 'boost::date_time::date_facet<date_type,CharT>' : assignment operator could not be generated because a base class assignment operator is inaccessible
#  4625 : 'boost::date_time::date_facet<date_type,CharT>' : copy constructor could not be generated because a base class copy constructor is inaccessible
#  4512 : 'boost::thread::thread_data<T>' : assignment operator could not be generated
#  4127 : conditional expression is constant
#  4061 : enumerate .. in switch not explicitly handled
#  4711 : function selected for automatic inline expansion
#  4826 : Conversion from '*' to '* __ptr64' is sign-extended. This may cause unexpected runtime behavior.
#  4548 : expression before comma has no effect; expected expression with side-effect
#   - add '/debug' when debugging is needed
ldflags=/nologo /incremental:no
ifdef DEBUG
#ccdefs+=/D _DEBUG
ldflags+=/debug /map
cflags+=/Zi /MTd /Od
obj=../build/w32dbg
else
cflags+=/O2 /Zi /MT
ldflags+=/debug
endif
ifdef UNICODE
ccdefs+=/D _UNICODE /D UNICODE
obj=../build/w32uni
endif
cflags+=-Gy

libpaths= /libpath:"$(mssdk)/lib" /libpath:"$(vc8)/lib" /libpath:"$(ActiveSyncSupport)/lib" /libpath:"$(boost)/lib-x86"
extralibs=user32.lib  advapi32.lib crypt32.lib

# these are used by all rapi based itsutils
rapibase=ConfigApi.obj FileFunctions.obj appunlock.obj checkdll.obj debug.obj streammultiplex.obj stringutils.obj findcert.obj
urapibase=uConfigApi.obj uFileFunctions.obj appunlock.obj ucheckdll.obj udebug.obj streammultiplex.obj ustringutils.obj findcert.obj

norapibase=FileFunctions.obj debugnorapi.obj streammultiplex.obj stringutils.obj findcert.obj
unorapibase=uFileFunctions.obj udebugnorapi.obj streammultiplex.obj ustringutils.obj findcert.obj

.SUFFIXES:
.SUFFIXES: .cpp .obj .exe

define compile
	@"$(w32cc)" $(cflags) $(cflags_$(basename $(notdir $1))) /c $(ccdefs) $(ccincs) $2 /Fo"$1"
endef
$(obj)/%.obj: %.cpp
	$(call compile,$@,$<)
$(obj)/%.obj: ../common/%.cpp
	$(call compile,$@,$<)

$(out)/%.exe: $(obj)/%.obj
	@"$(w32ld)" $(ldflags) $(ldflags_$(basename $(notdir $@))) $(libpaths) $(if $(norapi_$(basename $(notdir $@))),,rapi.lib) $(extralibs) $^ /out:$@


ifeq ($(OSTYPE),darwin)
osx:
	$(MAKE) -f Makefile.osx
endif


all: $(obj) all2

nn=$(subst .cpp,,$(n))
debug:
ifeq ($(nn),)
	make DEBUG=1
else
	$(RM) ../build/$(nn).exe
	mkdir -p ../build/w32dbg/
	make ../build/$(nn).exe DEBUG=1
endif

$(obj):
	mkdir -p $(obj)

define compilerule

$(obj)/$1: $2
	$$(call compile,$$@,$$<)
endef

# special rules


#################################

define buildtarget

APPLIST+=$1
CLEANLIST+=$(out)/$1
CLEANLIST+=$(basename $(out)/$1).pdb
CLEANLIST+=$(basename $(out)/$1).map
CLEANLIST+=$(addprefix $(obj)/,$2)

$(out)/$1: $(addprefix $(obj)/,$2)

endef
define buildnptarget

NPAPPLIST+=$1
CLEANLIST+=$(out)/$1
CLEANLIST+=$(basename $(out)/$1).pdb
CLEANLIST+=$(basename $(out)/$1).map
CLEANLIST+=$(addprefix $(obj)/,$2)

$(out)/$1: $(addprefix $(obj)/,$2)

endef


define copyfile

APPLIST+=$1
CLEANLIST+=$(out)/$1

$(out)/$1: $(out)/$2
	cp $$^ $$@

endef



#$(call buildtarget,tstaudio.exe, tstaudio.obj debug.obj stringutils.obj winmm.lib)
define buildrules

$(call compilerule,debugnorapi.obj,../common/debug.cpp)
cflags_debugnorapi=/D_NO_RAPI 
$(call compilerule,udebugnorapi.obj,../common/debug.cpp)
cflags_udebugnorapi=/D_NO_RAPI /D_UNICODE /DUNICODE
$(call compilerule,ustringutils.obj,../common/stringutils.cpp)
cflags_ustringutils=/D_UNICODE /DUNICODE
$(call compilerule,ucsidlpaths.obj,csidlpaths.cpp)
cflags_ucsidlpaths=/D_UNICODE /DUNICODE
$(call compilerule,ucheckdll.obj,checkdll.cpp)
cflags_ucheckdll=/D_UNICODE /DUNICODE
$(call compilerule,udebug.obj,../common/debug.cpp)
cflags_udebug=/D_UNICODE /DUNICODE
$(call compilerule,uConfigApi.obj,ConfigApi.cpp)
cflags_uConfigApi=/D_UNICODE /DUNICODE
$(call compilerule,uFileFunctions.obj,../common/FileFunctions.cpp)
cflags_uFileFunctions=/D_UNICODE /DUNICODE

$(call compilerule,ppostmsg.obj,ppostmsg.cpp)
cflags_ppostmsg=/DWINCEPOSTMSG 
$(call compilerule,postmsg.obj,ppostmsg.cpp)
cflags_postmsg=/DWIN32POSTMSG 
$(call compilerule,pmemdump.obj,pmemdump.cpp)
cflags_pmemdump=/DWINCEMEMDMP 
$(call compilerule,memdump.obj,pmemdump.cpp)
cflags_memdump=/DWIN32MEMDMP 

$(call compilerule,pregutl.obj,pregutl.cpp)
cflags_pregutl=/DWINCEREGUTL 
$(call compilerule,regutl.obj,pregutl.cpp)
cflags_regutl=/D_UNICODE /DUNICODE /DWIN32REGUTL 
$(call compilerule,sdread.obj,psdread.cpp)
cflags_sdread=/D_NO_RAPI 
$(call compilerule,psetmem.obj,psetmem.cpp)
cflags_psetmem=/DWINCESETMEM 
$(call compilerule,setmem.obj,psetmem.cpp)
cflags_setmem=/DWIN32SETMEM 


$(call copyfile,pget.exe,pput.exe)
$(call copyfile,pdocwrite.exe,pdocread.exe)
$(call copyfile,psdwrite.exe,psdread.exe)
$(call copyfile,sdwrite.exe,sdread.exe)
$(call copyfile,pflashrom.exe,pnewbootloader.exe)
$(call buildtarget,dump.exe, dump.obj $(norapibase))
cflags_dump=/I C:/local/winOpenSSL/include -D_USE_OPENSSL
ldflags_dump=/libpath:c:/local/winOpenSSL/lib/VC  libeay32MTd.lib ssleay32MTd.lib
norapi_dump=1
$(call buildtarget,tstimg.exe, tstimg.obj debug.obj stringutils.obj)
ldflags_tstimg=imagehlp.lib

$(call buildtarget,pps.exe, pps.obj $(rapibase))
$(call buildtarget,pkill.exe, pkill.obj $(rapibase))
$(call buildtarget,psynctime.exe, psynctime.obj $(rapibase))
$(call buildtarget,preboot.exe, preboot.obj $(rapibase))
$(call buildtarget,pcoldboot.exe, pcoldboot.obj $(rapibase))
$(call buildtarget,ppostmsg.exe, ppostmsg.obj $(rapibase) vectorutils.obj)
$(call buildtarget,postmsg.exe, postmsg.obj $(norapibase) vectorutils.obj)
norapi_postmsg=1
$(call buildtarget,pdel.exe, pdel.obj csidlpaths.obj $(rapibase))
$(call buildtarget,pmemdump.exe, pmemdump.obj $(rapibase))
$(call buildtarget,memdump.exe, memdump.obj $(norapibase) sysint-physmem.obj)
norapi_memdump=1
$(call buildnptarget,pcalladdr.exe, pcalladdr.obj $(rapibase))
$(call buildnptarget,pgsmbuf.exe, pgsmbuf.obj $(rapibase))
$(call buildtarget,pgsmdump.exe, pgsmdump.obj $(rapibase))
$(call buildtarget,pdblist.exe, pdblist.obj $(rapibase))
$(call buildtarget,pcontacts.exe, pcontacts.obj $(rapibase) vectorutils.obj)
$(call buildtarget,pdir.exe, pdir.obj ucsidlpaths.obj $(urapibase))
cflags_pdir=/D_UNICODE /DUNICODE
#$ call buildtarget,getsigningcert.exe, getsigningcert.obj  $(rapibase)
$(call buildtarget,psendsms.exe, psendsms.obj stringutils.obj $(rapibase))
$(call buildtarget,pdial.exe, pdial.obj stringutils.obj $(rapibase))
$(call buildtarget,pmkdir.exe, pmkdir.obj csidlpaths.obj $(rapibase))
$(call buildtarget,pmv.exe, pmv.obj csidlpaths.obj $(rapibase))
$(call buildtarget,pchmod.exe, pchmod.obj csidlpaths.obj $(rapibase))
$(call buildtarget,pput.exe, pput.obj ucsidlpaths.obj $(urapibase))
cflags_pput=/D_UNICODE /DUNICODE
$(call buildtarget,pregdmp.exe, pregdmp.obj $(rapibase))
$(call buildtarget,pregutl.exe, pregutl.obj $(rapibase) vectorutils.obj)
$(call buildtarget,regutl.exe, regutl.obj $(unorapibase) vectorutils.obj)
norapi_regutl=1
$(call buildtarget,prun.exe, prun.obj csidlpaths.obj $(rapibase))
$(call buildtarget,prapi.exe, prapi.obj $(rapibase))
$(call buildtarget,pmemmap.exe, pmemmap.obj $(rapibase))
$(call buildtarget,phandle.exe, phandle.obj $(rapibase))
$(call buildtarget,pdebug.exe, pdebug.obj $(rapibase))
#cflags_pdebug=/D_BOOST_LITE
$(call buildtarget,pdocread.exe, pdocread.obj $(rapibase))
$(call buildtarget,psdread.exe, psdread.obj $(rapibase))
$(call buildtarget,sdread.exe, sdread.obj $(norapibase))
norapi_sdread=1
$(call buildtarget,psetmem.exe, psetmem.obj $(rapibase) vectorutils.obj)
$(call buildtarget,setmem.exe, setmem.obj $(rapibase) vectorutils.obj sysint-physmem.obj)
$(call buildtarget,pcmon.exe, pcmon.obj debug.obj stringutils.obj)
$(call buildtarget,pnewbmp.exe, pnewbmp.obj $(rapibase))
$(call buildtarget,xda2dmp.exe, xda2dmp.obj debug.obj stringutils.obj crc32.obj)
$(call buildtarget,pnewbootloader.exe, pnewbootloader.obj $(rapibase))

endef

$(eval $(buildrules))

all2:  $(addprefix $(out)/,$(APPLIST))
np:  $(addprefix $(out)/,$(NPAPPLIST))


clean:
	rm -f $(CLEANLIST)
ifndef DEBUG
	make clean DEBUG=1
endif


dump.obj: dump.cpp dump_crc32.h dump_hash.h

