1########################################################################
2#
3# Copyright (c) 2009-2011, Secure Endpoints Inc.
4# All rights reserved.
5# 
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 
10# - Redistributions of source code must retain the above copyright
11#   notice, this list of conditions and the following disclaimer.
12# 
13# - Redistributions in binary form must reproduce the above copyright
14#   notice, this list of conditions and the following disclaimer in
15#   the documentation and/or other materials provided with the
16#   distribution.
17# 
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29# POSSIBILITY OF SUCH DAMAGE.
30# 
31
32all::
33
34clean::
35
36test::
37
38prep::
39
40all:: prep
41
42!include <Win32.Mak>
43
44!ifdef NODEBUG
45BUILD=rel
46!else
47BUILD=dbg
48!endif
49
50!if exist($(MAKEDIR)\windows\NTMakefile.w32)
51SRC=$(MAKEDIR)
52!elseif exist($(MAKEDIR)\..\windows\NTMakefile.w32)
53SRC=$(MAKEDIR)\..
54!elseif exist($(MAKEDIR)\..\..\windows\NTMakefile.w32)
55SRC=$(MAKEDIR)\..\..
56!elseif exist($(MAKEDIR)\..\..\..\windows\NTMakefile.w32)
57SRC=$(MAKEDIR)\..\..\..
58!elseif exist($(MAKEDIR)\..\..\..\..\windows\NTMakefile.w32)
59SRC=$(MAKEDIR)\..\..\..\..
60!else
61!  error Cant determine source directory
62!endif
63
64!  if "$(CPU)"=="i386" || "$(CPU)"=="x86"
65MCPU=x86
66!  elseif "$(CPU)"=="AMD64"
67MCPU=amd64
68!  else
69!    error Unknown CPU
70!  endif
71
72!include "NTMakefile.config"
73
74#----------------------------------------------------------------
75# Directory macros
76
77DESTDIR		=$(SRC)\out\dest_$(CPU)
78OBJDIR		=$(SRC)\out\obj_$(CPU)
79
80INCDIR		=$(DESTDIR)\inc
81LIBDIR		=$(DESTDIR)\lib
82BINDIR		=$(DESTDIR)\bin
83PLUGINDIR	=$(BINDIR)\plugin\krb5
84DOCDIR		=$(DESTDIR)\doc
85SBINDIR		=$(BINDIR)
86LIBEXECDIR	=$(BINDIR)
87ASMDIR		=$(BINDIR)
88INSTDIR		=$(DESTDIR)\install
89SDKDIR		=$(SRC)\out\sdk
90SDKINCDIR	=$(SDKDIR)\inc
91SDKLIBDIR	=$(SDKDIR)\lib\$(CPU)
92SDKSRCDIR	=$(SDKDIR)\src
93SDKREDISTDIR	=$(SDKDIR)\redist\$(CPU)
94
95!ifdef RELDIR
96SRCDIR =$(SRC)\$(RELDIR)
97OBJ    =$(OBJDIR)\$(RELDIR)
98!else
99OBJ    =$(OBJDIR)
100!endif
101
102# For tests:
103PATH=$(PATH);$(BINDIR)
104
105#----------------------------------------------------------------
106# Command macros
107
108RMAKE=nmake /nologo /f NTMakefile RECURSE=1
109MKDIR=md
110CP=copy /Y
111LINK=link
112LM=lib
113RM=del /q
114ECHO=echo
115RC=rc
116
117#----------------------------------------------------------------
118# Program macros
119
120AWK_CMD=gawk.exe
121YACC_CMD=bison.exe
122LEX_CMD=flex.exe
123PYTHON=python.exe
124PERL=perl.exe
125CMP=cmp.exe
126SIGNTOOL=signtool.exe
127MAKECAT=makecat.exe
128HHC=hhc.exe
129MAKEINFO=makeinfo.exe
130SED=sed.exe
131
132CANDLE_CMD=candle.exe
133LIGHT_CMD=light.exe
134
135# Only used for tests
136SH=sh.exe
137
138# Commands
139AWK=$(AWK_CMD)
140YACC=$(YACC_CMD) -y
141LEX=$(LEX_CMD)
142CANDLE=$(CANDLE_CMD) -nologo
143LIGHT=$(LIGHT_CMD) -nologo
144
145#----------------------------------------------------------------
146# External dependencies
147
148# For pthread support to be enabled, both PTHREAD_INC and PTHREAD_LIB
149# should be defined.  PTHREAD_INC should be the include directory
150# where pthread.h is to be found (i.e. $(PTHREAD_INC)\pthread.h should
151# exist), and PTHREAD_LIB is the full path to the pthread import
152# library.
153#
154# Note that both paths should not contain any whitespace.
155
156!ifdef PTHREAD_INC
157pthreadinc= -I$(PTHREAD_INC)
158!endif
159
160#----------------------------------------------------------------
161# Build options
162
163cincdirs=$(cincdirs) -I$(INCDIR) -I$(INCDIR)\krb5 $(pthreadinc)
164cdefines=$(cdefines) -DHAVE_CONFIG_H
165cdebug=$(cdebug) /Zi
166ldebug=$(ldebug) /DEBUG
167
168# Disable warnings:
169#
170# C4996: 'function' was declared deprecated
171# C4127: Conditional expression is constant
172# C4244: Conversion from 'type1' to 'type2', possible loss of data
173# C4100: 'identifier': unreferenced formal parameter
174# C4706: Assignment within conditional expression
175# C4214: Nonstandard extension used
176# C4267: '': Conversion from 'type1' to 'type2', possible loss of data
177# C4018: '': Signed/unsigned mismatch
178# C4204: Nonstandard extension used: non-constant aggregate initializer
179# C4221: Nonstandard extension used: 'v1': cannot be initialized using address of automatic variable 'v2'
180# C4295: '': Array is too small to include a terminating null character
181# C4146: Unary minus operator applied to unsigned type, result still unsigned.
182#
183cwarn=$(cwarn) -D_CRT_SECURE_NO_WARNINGS -wd4996 -wd4127 -wd4244 -wd4100 -wd4706
184cwarn=$(cwarn) -wd4214 -wd4267 -wd4018 -wd4389 -wd4204 -wd4221 -wd4295 -wd4146
185
186!if "$(CPU)"=="i386"
187libmach=/machine:X86
188!elseif "$(CPU)"=="AMD64"
189libmach=/machine:X64
190!else
191!  error Unknown CPU value
192!endif
193
194!ifdef NO_MP
195MPOPT=
196!else
197MPOPT=/MP
198!endif
199
200!ifndef STATICRUNTIME
201
202C2OBJ_C = $(CC) $(cdebug) $(cflags) $(cvarsdll) $(AUXCFLAGS) $(intcflags) $(cdefines) $(cincdirs) $(cwarn)
203EXECONLINK_C = $(LINK) $(ldebug) $(conlflags) $(conlibsdll) $(libmach)
204EXEGUILINK_C = $(LINK) $(ldebug) $(guilflags) $(guilibsdll) $(libmach)
205DLLCONLINK_C = $(LINK) $(ldebug) $(dlllflags) $(conlibsdll) $(libmach)
206DLLGUILINK_C = $(LINK) $(ldebug) $(dlllflags) $(guilibsdll) $(libmach)
207
208!else # STATICRUNTIME
209
210C2OBJ_C = $(CC) $(cdebug) $(cflags) $(cvarsmt) $(AUXCFLAGS) $(intcflags) $(cdefines) $(cincdirs) $(cwarn)
211EXECONLINK_C = $(LINK) $(ldebug) $(conlflags) $(conlibsmt) $(libmach)
212EXEGUILINK_C = $(LINK) $(ldebug) $(guilflags) $(guilibsmt) $(libmach)
213DLLCONLINK_C = $(LINK) $(ldebug) $(dlllflags) $(conlibsmt) $(libmach)
214DLLGUILINK_C = $(LINK) $(ldebug) $(dlllflags) $(guilibsmt) $(libmach)
215
216!endif
217
218LIBGUI_C = $(LM) /nologo $(libmach) /SUBSYSTEM:WINDOWS
219LIBCON_C = $(LM) /nologo $(libmach) /SUBSYSTEM:CONSOLE
220
221C2OBJ = $(C2OBJ_C) -Fo$@ -Fd$(@D)\ $**
222C2OBJ_NP = $(C2OBJ_C) $(MPOPT) $<
223C2OBJ_P = $(C2OBJ_NP) -Fo$(OBJ)\ -Fd$(OBJ)\ #
224EXECONLINK = $(EXECONLINK_C) -OUT:$@ $**
225EXEGUILINK = $(EXEGUILINK_C) -OUT:$@ $**
226DLLCONLINK = $(DLLCONLINK_C) -OUT:$@ $**
227DLLGUILINK = $(DLLGUILINK_C) -OUT:$@ $**
228LIBGUI = $(LIBGUI_C) /OUT:$@ $**
229LIBCON = $(LIBCON_C) /OUT:$@ $**
230
231# Preprocess files to stdout using config.h
232CPREPROCESSOUT = $(CC) /EP /FI$(INCDIR)\config.h /TC /DCPP_ONLY=1
233
234# Resources
235
236RC2RES_C = $(RC) $(cincdirs) $(AUXRCFLAGS)
237RC2RES = $(RC2RES_C) -fo $@ $**
238
239#----------------------------------------------------------------------
240# If this is the initial invocation, we check if all the build
241# utilities are there.  Also show the commands macros.
242
243!ifndef RECURSE
244
245REQUIRED_TOOLS= \
246	"$(AWK_CMD)" "$(YACC_CMD)" "$(LEX_CMD)" "$(PYTHON)" "$(PERL)" \
247	"$(CMP)" "$(SED)" "$(SIGNTOOL)" "$(MAKECAT)" "$(MAKEINFO)" "$(HHC)"
248
249!ifdef BUILD_INSTALLERS
250REQUIRED_TOOLS=$(REQUIRED_TOOLS) "$(CANDLE_CMD)" "$(LIGHT_CMD)"
251!endif
252
253OPTIONAL_TOOLS="$(SH)" 
254
255check-utils:
256	@for %%g in ( $(REQUIRED_TOOLS) ) do @( \
257	for /f %%f in ( "%%g" ) do @( \
258		if exist %%f @( \
259			echo Found %%f \
260		) else if "%%~$$PATH:f"=="" @( \
261			echo Could not find %%f in PATH && \
262			exit /b 1 \
263		) else @( \
264			echo Found %%~$$PATH:f \
265		) \
266	) \
267	)
268	@for %%g in ( $(OPTIONAL_TOOLS) ) do @( \
269	for /f %%f in ( "%%g" ) do @( \
270		if exist %%f @( \
271			echo Found %%f \
272		) else if "%%~$$PATH:f"=="" @( \
273			echo Could not find %%f in PATH && \
274			echo Optional targets may fail. \
275		) else @( \
276			echo Found %%~$$PATH:f \
277		) \
278	) \
279	)
280
281
282prep:: check-utils
283
284show-cmds:
285	@$(ECHO) C2OBJ=$(C2OBJ_C:\=\\)
286	@$(ECHO).
287	@$(ECHO) EXECONLINK=$(EXECONLINK_C)
288	@$(ECHO).
289	@$(ECHO) EXEGUILINK=$(EXEGUILINK_C)
290	@$(ECHO).
291	@$(ECHO) DLLCONLINK=$(DLLCONLINK_C)
292	@$(ECHO).
293	@$(ECHO) DLLGUILINK=$(DLLGUILINK_C)
294	@$(ECHO).
295	@$(ECHO) LIBGUI=$(LIBGUI_C)
296	@$(ECHO).
297	@$(ECHO) LIBCON=$(LIBCON_C)
298
299prep:: show-cmds
300
301!endif				# RECURSE
302
303{}.c{$(OBJ)}.obj::
304	$(C2OBJ_C) /Fd$(OBJ)\ /Fo$(OBJ)\ $(localcflags) $(MPOPT) @<<
305$<
306<<
307
308{$(OBJ)}.c{$(OBJ)}.obj::
309	$(C2OBJ_C) /Fd$(OBJ)\ /Fo$(OBJ)\ $(extcflags) $(MPOPT) @<<
310$<
311<<
312
313{}.cpp{$(OBJ)}.obj::
314	$(C2OBJ_C) /Fd$(OBJ)\ /Fo$(OBJ)\ $(localcflags) $(MPOPT) @<<
315$<
316<<
317
318{$(OBJ)}.cpp{$(OBJ)}.obj::
319	$(C2OBJ_C) /Fd$(OBJ)\ /Fo$(OBJ)\ $(extcflags) $(MPOPT) @<<
320$<
321<<
322
323{}.hin{$(INCDIR)}.h:
324	$(CP) $< $@
325
326{}.h{$(INCDIR)}.h:
327	$(CP) $< $@
328
329{}.h{$(INCDIR)\krb5}.h:
330	$(CP) $< $@
331
332{$(OBJ)}.h{$(INCDIR)}.h:
333	$(CP) $< $@
334
335{$(OBJ)}.x{$(OBJ)}.c:
336	$(CP) $< $@
337
338{$(OBJ)}.hx{$(INCDIR)}.h:
339	$(CP) $< $@
340
341{$(OBJ)}.hx{$(OBJ)}.h:
342	$(CP) $< $@
343
344{}.rc{$(OBJ)}.res:
345	$(RC2RES)
346
347#----------------------------------------------------------------------
348# Announce the build directory
349
350!ifdef RELDIR
351all:: announce
352
353all-tools:: announce-tools
354
355test:: announce
356
357clean:: announce
358
359announce:
360	@echo.
361	@echo --------- Entering $(RELDIR:\= ):
362
363announce-tools:
364	@echo.
365	@echo --------- Entering $(RELDIR:\= ) tools:
366!endif
367
368#----------------------------------------------------------------------
369# Create any required directories if they don't already exist
370
371prep:: mkdirs
372
373mkdirs:
374!  if !exist($(OBJ))
375	$(MKDIR) $(OBJ)
376!  endif
377!  if !exist($(DESTDIR))
378	$(MKDIR) $(DESTDIR)
379!  endif
380!  if !exist($(LIBDIR))
381	$(MKDIR) $(LIBDIR)
382!  endif
383!  if !exist($(BINDIR))
384	$(MKDIR) $(BINDIR)
385!  endif
386!  if !exist($(PLUGINDIR))
387	$(MKDIR) $(PLUGINDIR)
388!  endif
389!  if !exist($(INCDIR))
390	$(MKDIR) $(INCDIR)
391!  endif
392!  if !exist($(DOCDIR))
393	$(MKDIR) $(DOCDIR)
394!  endif
395!  if !exist($(INCDIR)\gssapi)
396	$(MKDIR) $(INCDIR)\gssapi
397!  endif
398!  if !exist($(INCDIR)\hcrypto)
399	$(MKDIR) $(INCDIR)\hcrypto
400!  endif
401!  if !exist($(INCDIR)\kadm5)
402	$(MKDIR) $(INCDIR)\kadm5
403!  endif
404!  if !exist($(INCDIR)\krb5)
405	$(MKDIR) $(INCDIR)\krb5
406!  endif
407
408#----------------------------------------------------------------------
409# If SUBDIRS is defined, we should recurse into the subdirectories
410
411!ifdef SUBDIRS
412subdirs:
413	@for %%f in ( $(SUBDIRS) ) do @ (pushd %%f && $(RMAKE) && popd) || exit /b 1
414
415clean-subdirs:
416	@for %%f in ( $(SUBDIRS) ) do @ (pushd %%f && $(RMAKE) clean && popd) || exit /b 1
417
418test-subdirs:
419	@for %%f in ( $(SUBDIRS) ) do @ (pushd %%f && $(RMAKE) test && popd) || exit /b 1
420
421all:: subdirs
422
423clean:: clean-subdirs
424
425test:: test-subdirs
426
427!endif
428
429#----------------------------------------------------------------------
430# Clean targets
431
432!ifdef CLEANFILES
433clean::
434	-$(RM) $(CLEANFILES)
435!endif
436!ifdef RELDIR
437clean::
438	-$(RM) $(OBJ)\*.*
439!endif
440
441.SUFFIXES: .c .cpp .hin .h .x .hx
442
443#----------------------------------------------------------------------
444# Manifest handling
445#
446# Starting with Visual Studio 8, the C compiler and the linker
447# generate manifests so that the applications will link with the
448# correct side-by-side DLLs at run-time.  These are required for
449# correct operation under Windows XP and later.  We also have custom
450# manifests which need to be merged with the manifests that VS
451# creates.
452#
453# The syntax for invoking the _VC_MANIFEST_EMBED_FOO macro is:
454# $(_VC_MANIFEST_EMBED_???) <additional manifests>
455#
456
457MT=mt.exe -nologo
458
459_VC_MANIFEST_EMBED_EXE= \
460( if exist $@.manifest $(MT) -outputresource:$@;1 -manifest $@.manifest $(APPMANIFEST) )
461
462_VC_MANIFEST_EMBED_EXE_NOHEIM= \
463( if exist $@.manifest $(MT) -outputresource:$@;1 -manifest $@.manifest )
464
465_VC_MANIFEST_EMBED_DLL= \
466( if exist $@.manifest $(MT) -outputresource:$@;2 -manifest $@.manifest )
467
468_MERGE_MANIFEST_DLL= \
469( $(MT) -inputresource:$@;2 -manifest $(APPMANIFEST) -outputresource:$@;2 )
470
471_INSERT_APPMANIFEST_DLL= \
472( $(MT) -manifest $(APPMANIFEST) -outputresource:$@;2 )
473
474# Note that if you are merging manifests, then the VS generated
475# manifest should be cleaned up after calling _VC_MANIFEST_EMBED_???.
476# This ensures that even if the DLL or EXE is executed in-place, the
477# embedded manifest will be used.  Otherwise the $@.manifest file will
478# be used.
479
480_VC_MANIFEST_CLEAN= \
481( if exist $@.manifest $(RM) $@.manifest )
482
483# End of manifest handling
484
485#----------------------------------------------------------------------
486# Code and assembly signing
487#
488# SIGNTOOL_C is any set of options required for certificate/private
489# key selection for code signging.
490#
491# SIGNTOOL_O is any set of additional options to signtool.exe
492#
493# SIGNTOOL_T is the timestamp option
494
495!ifdef CODESIGN
496_CODESIGN=( $(CODESIGN) $@ )
497!else
498
499!ifdef SIGNTOOL_C
500
501!ifndef SIGNTOOL_T
502SIGNTOOL_T=/t http://timestamp.verisign.com/scripts/timstamp.dll
503!endif
504
505_CODESIGN=( $(SIGNTOOL) sign $(SIGNTOOL_O) $(SIGNTOOL_T) $(SIGNTOOL_C) /v $@ )
506!else
507_CODESIGN=( echo Skipping code sign )
508!endif
509
510!endif
511
512#----------------------------------------------------------------------
513# Convenience macros for preparing EXEs and DLLs.  These are multiline
514# macros that deal with manifests and code signing.  Unless we need to
515# include custom manifests, these are what we should be using to
516# prepare binaries.
517
518EXEPREP=\
519( $(_VC_MANIFEST_EMBED_EXE) && $(_VC_MANIFEST_CLEAN) && $(_CODESIGN) ) || ( $(RM) $@ && exit /b 1 )
520
521EXEPREP_NOHEIM=\
522( $(_VC_MANIFEST_EMBED_EXE_NOHEIM) && $(_VC_MANIFEST_CLEAN) && $(_CODESIGN) ) || ( $(RM) $@ && exit /b 1 )
523
524EXEPREP_NODIST=\
525( $(_VC_MANIFEST_EMBED_EXE_NOHEIM) && $(_VC_MANIFEST_CLEAN) ) || ( $(RM) $@ && exit /b 1 )
526
527DLLPREP=\
528( $(_VC_MANIFEST_EMBED_DLL) && $(_VC_MANIFEST_CLEAN) && $(_CODESIGN) ) || ( $(RM) $@ && exit /b 1 )
529
530DLLPREP_NODIST=\
531( $(_VC_MANIFEST_EMBED_DLL) && $(_VC_MANIFEST_CLEAN) ) || ( $(RM) $@ && exit /b 1 )
532
533DLLPREP_MERGE=\
534( ( $(_MERGE_MANIFEST_DLL) || $(_INSERT_APPMANIFEST_DLL) ) && $(_CODESIGN) ) || ( $(RM) $@ && exit /b 1 )
535
536#----------------------------------------------------------------------
537# Convenience macros for import libraries and assemblies
538#
539
540LIBASN1	    =$(LIBDIR)\libasn1.lib
541LIBCOMERR   =$(LIBDIR)\libcom_err.lib
542LIBEDITLINE =$(LIBDIR)\libeditline.lib
543LIBGSSAPI   =$(LIBDIR)\libgssapi.lib
544LIBHCRYPTO  =$(LIBDIR)\libhcrypto.lib
545LIBHDB	    =$(LIBDIR)\libhdb.lib
546LIBHEIMBASE =$(LIBDIR)\libheimbase.lib
547LIBHEIMDAL  =$(LIBDIR)\heimdal.lib
548LIBHEIMIPCC =$(LIBDIR)\libheim-ipcc.lib
549LIBHEIMIPCS =$(LIBDIR)\libheim-ipcs.lib
550LIBHEIMNTLM =$(LIBDIR)\libheimntlm.lib
551LIBHX509    =$(LIBDIR)\libhx509.lib
552LIBKADM5CLNT=$(LIBDIR)\libkadm5clnt.lib
553LIBKADM5SRV =$(LIBDIR)\libkadm5srv.lib
554LIBKDC	    =$(LIBDIR)\libkdc.lib
555LIBLTM	    =$(LIBDIR)\libltm.lib
556LIBKRB5	    =$(LIBDIR)\libkrb5.lib
557LIBRFC3961  =$(LIBDIR)\librfc3961.lib
558LIBROKEN    =$(LIBDIR)\libroken.lib
559LIBSL	    =$(LIBDIR)\libsl.lib
560LIBSQLITE   =$(LIBDIR)\libsqlite.lib
561LIBVERS	    =$(LIBDIR)\libvers.lib
562LIBWIND	    =$(LIBDIR)\libwind.lib
563
564ASMKRBNAME  =Heimdal.Kerberos
565ASMGSSNAME  =Heimdal.GSSAPI
566APPMANIFEST =$(INCDIR)\Heimdal.Application.$(MCPU).manifest
567
568