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