rules.vc 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  1. #------------------------------------------------------------- -*- makefile -*-
  2. # rules.vc --
  3. #
  4. # Part of the nmake based build system for Tcl and its extensions.
  5. # This file does all the hard work in terms of parsing build options,
  6. # compiler switches, defining common targets and macros. The Tcl makefile
  7. # directly includes this. Extensions include it via "rules-ext.vc".
  8. #
  9. # See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for
  10. # detailed documentation.
  11. #
  12. # See the file "license.terms" for information on usage and redistribution
  13. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  14. #
  15. # Copyright (c) 2001-2003 David Gravereaux.
  16. # Copyright (c) 2003-2008 Patrick Thoyts
  17. # Copyright (c) 2017 Ashok P. Nadkarni
  18. #------------------------------------------------------------------------------
  19. !ifndef _RULES_VC
  20. _RULES_VC = 1
  21. # The following macros define the version of the rules.vc nmake build system
  22. # For modifications that are not backward-compatible, you *must* change
  23. # the major version.
  24. RULES_VERSION_MAJOR = 1
  25. RULES_VERSION_MINOR = 10
  26. # The PROJECT macro must be defined by parent makefile.
  27. !if "$(PROJECT)" == ""
  28. !error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
  29. !endif
  30. !if "$(PRJ_PACKAGE_TCLNAME)" == ""
  31. PRJ_PACKAGE_TCLNAME = $(PROJECT)
  32. !endif
  33. # Also special case Tcl and Tk to save some typing later
  34. DOING_TCL = 0
  35. DOING_TK = 0
  36. !if "$(PROJECT)" == "tcl"
  37. DOING_TCL = 1
  38. !elseif "$(PROJECT)" == "tk"
  39. DOING_TK = 1
  40. !endif
  41. !ifndef NEED_TK
  42. # Backwards compatibility
  43. !ifdef PROJECT_REQUIRES_TK
  44. NEED_TK = $(PROJECT_REQUIRES_TK)
  45. !else
  46. NEED_TK = 0
  47. !endif
  48. !endif
  49. !ifndef NEED_TCL_SOURCE
  50. NEED_TCL_SOURCE = 0
  51. !endif
  52. !ifdef NEED_TK_SOURCE
  53. !if $(NEED_TK_SOURCE)
  54. NEED_TK = 1
  55. !endif
  56. !else
  57. NEED_TK_SOURCE = 0
  58. !endif
  59. ################################################################
  60. # Nmake is a pretty weak environment in syntax and capabilities
  61. # so this file is necessarily verbose. It's broken down into
  62. # the following parts.
  63. #
  64. # 0. Sanity check that compiler environment is set up and initialize
  65. # any built-in settings from the parent makefile
  66. # 1. First define the external tools used for compiling, copying etc.
  67. # as this is independent of everything else.
  68. # 2. Figure out our build structure in terms of the directory, whether
  69. # we are building Tcl or an extension, etc.
  70. # 3. Determine the compiler and linker versions
  71. # 4. Build the nmakehlp helper application
  72. # 5. Determine the supported compiler options and features
  73. # 6. Parse the OPTS macro value for user-specified build configuration
  74. # 7. Parse the STATS macro value for statistics instrumentation
  75. # 8. Parse the CHECKS macro for additional compilation checks
  76. # 9. Extract Tcl, and possibly Tk, version numbers from the headers
  77. # 10. Based on this selected configuration, construct the output
  78. # directory and file paths
  79. # 11. Construct the paths where the package is to be installed
  80. # 12. Set up the actual options passed to compiler and linker based
  81. # on the information gathered above.
  82. # 13. Define some standard build targets and implicit rules. These may
  83. # be optionally disabled by the parent makefile.
  84. # 14. (For extensions only.) Compare the configuration of the target
  85. # Tcl and the extensions and warn against discrepancies.
  86. #
  87. # One final note about the macro names used. They are as they are
  88. # for historical reasons. We would like legacy extensions to
  89. # continue to work with this make include file so be wary of
  90. # changing them for consistency or clarity.
  91. # 0. Sanity check compiler environment
  92. # Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
  93. # VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
  94. !if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
  95. MSG = ^
  96. Visual C++ compiler environment not initialized.
  97. !error $(MSG)
  98. !endif
  99. # We need to run from the directory the parent makefile is located in.
  100. # nmake does not tell us what makefile was used to invoke it so parent
  101. # makefile has to set the MAKEFILEVC macro or we just make a guess and
  102. # warn if we think that is not the case.
  103. !if "$(MAKEFILEVC)" == ""
  104. !if exist("$(PROJECT).vc")
  105. MAKEFILEVC = $(PROJECT).vc
  106. !elseif exist("makefile.vc")
  107. MAKEFILEVC = makefile.vc
  108. !endif
  109. !endif # "$(MAKEFILEVC)" == ""
  110. !if !exist("$(MAKEFILEVC)")
  111. MSG = ^
  112. You must run nmake from the directory containing the project makefile.^
  113. If you are doing that and getting this message, set the MAKEFILEVC^
  114. macro to the name of the project makefile.
  115. !message WARNING: $(MSG)
  116. !endif
  117. ################################################################
  118. # 1. Define external programs being used
  119. #----------------------------------------------------------
  120. # Set the proper copy method to avoid overwrite questions
  121. # to the user when copying files and selecting the right
  122. # "delete all" method.
  123. #----------------------------------------------------------
  124. RMDIR = rmdir /S /Q
  125. CPY = xcopy /i /y >NUL
  126. CPYDIR = xcopy /e /i /y >NUL
  127. COPY = copy /y >NUL
  128. MKDIR = mkdir
  129. ######################################################################
  130. # 2. Figure out our build environment in terms of what we're building.
  131. #
  132. # (a) Tcl itself
  133. # (b) Tk
  134. # (c) a Tcl extension using libraries/includes from an *installed* Tcl
  135. # (d) a Tcl extension using libraries/includes from Tcl source directory
  136. #
  137. # This last is needed because some extensions still need
  138. # some Tcl interfaces that are not publicly exposed.
  139. #
  140. # The fragment will set the following macros:
  141. # ROOT - root of this module sources
  142. # COMPATDIR - source directory that holds compatibility sources
  143. # DOCDIR - source directory containing documentation files
  144. # GENERICDIR - platform-independent source directory
  145. # WIN_DIR - Windows-specific source directory
  146. # TESTDIR - directory containing test files
  147. # TOOLSDIR - directory containing build tools
  148. # _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
  149. # when building Tcl itself.
  150. # _INSTALLDIR - native form of the installation path. For Tcl
  151. # this will be the root of the Tcl installation. For extensions
  152. # this will be the lib directory under the root.
  153. # TCLINSTALL - set to 1 if _TCLDIR refers to
  154. # headers and libraries from an installed Tcl, and 0 if built against
  155. # Tcl sources. Not set when building Tcl itself. Yes, not very well
  156. # named.
  157. # _TCL_H - native path to the tcl.h file
  158. #
  159. # If Tk is involved, also sets the following
  160. # _TKDIR - native form Tk installation OR Tk source. Not set if building
  161. # Tk itself.
  162. # TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
  163. # _TK_H - native path to the tk.h file
  164. # Root directory for sources and assumed subdirectories
  165. ROOT = $(MAKEDIR)\..
  166. # The following paths CANNOT have spaces in them as they appear on the
  167. # left side of implicit rules.
  168. !ifndef COMPATDIR
  169. COMPATDIR = $(ROOT)\compat
  170. !endif
  171. !ifndef DOCDIR
  172. DOCDIR = $(ROOT)\doc
  173. !endif
  174. !ifndef GENERICDIR
  175. GENERICDIR = $(ROOT)\generic
  176. !endif
  177. !ifndef TOOLSDIR
  178. TOOLSDIR = $(ROOT)\tools
  179. !endif
  180. !ifndef TESTDIR
  181. TESTDIR = $(ROOT)\tests
  182. !endif
  183. !ifndef LIBDIR
  184. !if exist("$(ROOT)\library")
  185. LIBDIR = $(ROOT)\library
  186. !else
  187. LIBDIR = $(ROOT)\lib
  188. !endif
  189. !endif
  190. !ifndef DEMODIR
  191. !if exist("$(LIBDIR)\demos")
  192. DEMODIR = $(LIBDIR)\demos
  193. !else
  194. DEMODIR = $(ROOT)\demos
  195. !endif
  196. !endif # ifndef DEMODIR
  197. # Do NOT use WINDIR because it is Windows internal environment
  198. # variable to point to c:\windows!
  199. WIN_DIR = $(ROOT)\win
  200. !ifndef RCDIR
  201. !if exist("$(WIN_DIR)\rc")
  202. RCDIR = $(WIN_DIR)\rc
  203. !else
  204. RCDIR = $(WIN_DIR)
  205. !endif
  206. !endif
  207. RCDIR = $(RCDIR:/=\)
  208. # The target directory where the built packages and binaries will be installed.
  209. # INSTALLDIR is the (optional) path specified by the user.
  210. # _INSTALLDIR is INSTALLDIR using the backslash separator syntax
  211. !ifdef INSTALLDIR
  212. ### Fix the path separators.
  213. _INSTALLDIR = $(INSTALLDIR:/=\)
  214. !else
  215. ### Assume the normal default.
  216. _INSTALLDIR = $(HOMEDRIVE)\Tcl
  217. !endif
  218. !if $(DOING_TCL)
  219. # BEGIN Case 2(a) - Building Tcl itself
  220. # Only need to define _TCL_H
  221. _TCL_H = ..\generic\tcl.h
  222. # END Case 2(a) - Building Tcl itself
  223. !elseif $(DOING_TK)
  224. # BEGIN Case 2(b) - Building Tk
  225. TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
  226. !if "$(TCLDIR)" == ""
  227. !if [echo TCLDIR = \> nmakehlp.out] \
  228. || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
  229. !error *** Could not locate Tcl source directory.
  230. !endif
  231. !include nmakehlp.out
  232. !endif # TCLDIR == ""
  233. _TCLDIR = $(TCLDIR:/=\)
  234. _TCL_H = $(_TCLDIR)\generic\tcl.h
  235. !if !exist("$(_TCL_H)")
  236. !error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
  237. !endif
  238. _TK_H = ..\generic\tk.h
  239. # END Case 2(b) - Building Tk
  240. !else
  241. # BEGIN Case 2(c) or (d) - Building an extension other than Tk
  242. # If command line has specified Tcl location through TCLDIR, use it
  243. # else default to the INSTALLDIR setting
  244. !if "$(TCLDIR)" != ""
  245. _TCLDIR = $(TCLDIR:/=\)
  246. !if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
  247. TCLINSTALL = 1
  248. _TCL_H = $(_TCLDIR)\include\tcl.h
  249. !elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
  250. TCLINSTALL = 0
  251. _TCL_H = $(_TCLDIR)\generic\tcl.h
  252. !endif
  253. !else # # Case 2(c) for extensions with TCLDIR undefined
  254. # Need to locate Tcl depending on whether it needs Tcl source or not.
  255. # If we don't, check the INSTALLDIR for an installed Tcl first
  256. !if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
  257. TCLINSTALL = 1
  258. TCLDIR = $(_INSTALLDIR)\..
  259. # NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
  260. # later so the \.. accounts for the /lib
  261. _TCLDIR = $(_INSTALLDIR)\..
  262. _TCL_H = $(_TCLDIR)\include\tcl.h
  263. !else # exist(...) && !$(NEED_TCL_SOURCE)
  264. !if [echo _TCLDIR = \> nmakehlp.out] \
  265. || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
  266. !error *** Could not locate Tcl source directory.
  267. !endif
  268. !include nmakehlp.out
  269. TCLINSTALL = 0
  270. TCLDIR = $(_TCLDIR)
  271. _TCL_H = $(_TCLDIR)\generic\tcl.h
  272. !endif # exist(...) && !$(NEED_TCL_SOURCE)
  273. !endif # TCLDIR
  274. !ifndef _TCL_H
  275. MSG =^
  276. Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
  277. !error $(MSG)
  278. !endif
  279. # Now do the same to locate Tk headers and libs if project requires Tk
  280. !if $(NEED_TK)
  281. !if "$(TKDIR)" != ""
  282. _TKDIR = $(TKDIR:/=\)
  283. !if exist("$(_TKDIR)\include\tk.h")
  284. TKINSTALL = 1
  285. _TK_H = $(_TKDIR)\include\tk.h
  286. !elseif exist("$(_TKDIR)\generic\tk.h")
  287. TKINSTALL = 0
  288. _TK_H = $(_TKDIR)\generic\tk.h
  289. !endif
  290. !else # TKDIR not defined
  291. # Need to locate Tcl depending on whether it needs Tcl source or not.
  292. # If we don't, check the INSTALLDIR for an installed Tcl first
  293. !if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
  294. TKINSTALL = 1
  295. # NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
  296. # later so the \.. accounts for the /lib
  297. _TKDIR = $(_INSTALLDIR)\..
  298. _TK_H = $(_TKDIR)\include\tk.h
  299. TKDIR = $(_TKDIR)
  300. !else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
  301. !if [echo _TKDIR = \> nmakehlp.out] \
  302. || [nmakehlp -L generic\tk.h >> nmakehlp.out]
  303. !error *** Could not locate Tk source directory.
  304. !endif
  305. !include nmakehlp.out
  306. TKINSTALL = 0
  307. TKDIR = $(_TKDIR)
  308. _TK_H = $(_TKDIR)\generic\tk.h
  309. !endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
  310. !endif # TKDIR
  311. !ifndef _TK_H
  312. MSG =^
  313. Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
  314. !error $(MSG)
  315. !endif
  316. !endif # NEED_TK
  317. !if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
  318. MSG = ^
  319. *** Warning: This extension requires the source distribution of Tcl.^
  320. *** Please set the TCLDIR macro to point to the Tcl sources.
  321. !error $(MSG)
  322. !endif
  323. !if $(NEED_TK_SOURCE)
  324. !if $(TKINSTALL)
  325. MSG = ^
  326. *** Warning: This extension requires the source distribution of Tk.^
  327. *** Please set the TKDIR macro to point to the Tk sources.
  328. !error $(MSG)
  329. !endif
  330. !endif
  331. # If INSTALLDIR set to Tcl installation root dir then reset to the
  332. # lib dir for installing extensions
  333. !if exist("$(_INSTALLDIR)\include\tcl.h")
  334. _INSTALLDIR=$(_INSTALLDIR)\lib
  335. !endif
  336. # END Case 2(c) or (d) - Building an extension
  337. !endif # if $(DOING_TCL)
  338. ################################################################
  339. # 3. Determine compiler version and architecture
  340. # In this section, we figure out the compiler version and the
  341. # architecture for which we are building. This sets the
  342. # following macros:
  343. # VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
  344. # This is also printed by the compiler in dotted form 19.10 etc.
  345. # VCVER - the "marketing version", for example Visual C++ 6 for internal
  346. # compiler version 1200. This is kept only for legacy reasons as it
  347. # does not make sense for recent Microsoft compilers. Only used for
  348. # output directory names.
  349. # ARCH - set to IX86, ARM64 or AMD64 depending on 32- or 64-bit target
  350. # NATIVE_ARCH - set to IX86, ARM64 or AMD64 for the host machine
  351. # MACHINE - same as $(ARCH) - legacy
  352. # _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
  353. cc32 = $(CC) # built-in default.
  354. link32 = link
  355. lib32 = lib
  356. rc32 = $(RC) # built-in default.
  357. #----------------------------------------------------------------
  358. # Figure out the compiler architecture and version by writing
  359. # the C macros to a file, preprocessing them with the C
  360. # preprocessor and reading back the created file
  361. _HASH=^#
  362. _VC_MANIFEST_EMBED_EXE=
  363. _VC_MANIFEST_EMBED_DLL=
  364. VCVER=0
  365. !if ![echo VCVERSION=_MSC_VER > vercl.x] \
  366. && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
  367. && ![echo ARCH=IX86 >> vercl.x] \
  368. && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
  369. && ![echo ARCH=AMD64 >> vercl.x] \
  370. && ![echo $(_HASH)elif defined(_M_ARM64) >> vercl.x] \
  371. && ![echo ARCH=ARM64 >> vercl.x] \
  372. && ![echo $(_HASH)endif >> vercl.x] \
  373. && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
  374. !include vercl.i
  375. !if $(VCVERSION) < 1900
  376. !if ![echo VCVER= ^\> vercl.vc] \
  377. && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
  378. !include vercl.vc
  379. !endif
  380. !else
  381. # The simple calculation above does not apply to new Visual Studio releases
  382. # Keep the compiler version in its native form.
  383. VCVER = $(VCVERSION)
  384. !endif
  385. !endif
  386. !if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
  387. !endif
  388. #----------------------------------------------------------------
  389. # The MACHINE macro is used by legacy makefiles so set it as well
  390. !ifdef MACHINE
  391. !if "$(MACHINE)" == "x86"
  392. !undef MACHINE
  393. MACHINE = IX86
  394. !elseif "$(MACHINE)" == "arm64"
  395. !undef MACHINE
  396. MACHINE = ARM64
  397. !elseif "$(MACHINE)" == "x64"
  398. !undef MACHINE
  399. MACHINE = AMD64
  400. !endif
  401. !if "$(MACHINE)" != "$(ARCH)"
  402. !error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
  403. !endif
  404. !else
  405. MACHINE=$(ARCH)
  406. !endif
  407. #---------------------------------------------------------------
  408. # The PLATFORM_IDENTIFY macro matches the values returned by
  409. # the Tcl platform::identify command
  410. !if "$(MACHINE)" == "AMD64"
  411. PLATFORM_IDENTIFY = win32-x86_64
  412. !elseif "$(MACHINE)" == "ARM64"
  413. PLATFORM_IDENTIFY = win32-arm
  414. !else
  415. PLATFORM_IDENTIFY = win32-ix86
  416. !endif
  417. # The MULTIPLATFORM macro controls whether binary extensions are installed
  418. # in platform-specific directories. Intended to be set/used by extensions.
  419. !ifndef MULTIPLATFORM_INSTALL
  420. MULTIPLATFORM_INSTALL = 0
  421. !endif
  422. #------------------------------------------------------------
  423. # Figure out the *host* architecture by reading the registry
  424. !if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
  425. NATIVE_ARCH=IX86
  426. !elseif ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i ARM | findstr /i 64-bit]
  427. NATIVE_ARCH=ARM64
  428. !else
  429. NATIVE_ARCH=AMD64
  430. !endif
  431. # Since MSVC8 we must deal with manifest resources.
  432. !if $(VCVERSION) >= 1400
  433. _VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
  434. _VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
  435. !endif
  436. ################################################################
  437. # 4. Build the nmakehlp program
  438. # This is a helper app we need to overcome nmake's limiting
  439. # environment. We will call out to it to get various bits of
  440. # information about supported compiler options etc.
  441. #
  442. # Tcl itself will always use the nmakehlp.c program which is
  443. # in its own source. It will be kept updated there.
  444. #
  445. # Extensions built against an installed Tcl will use the installed
  446. # copy of Tcl's nmakehlp.c if there is one and their own version
  447. # otherwise. In the latter case, they would also be using their own
  448. # rules.vc. Note that older versions of Tcl do not install nmakehlp.c
  449. # or rules.vc.
  450. #
  451. # Extensions built against Tcl sources will use the one from the Tcl source.
  452. #
  453. # When building an extension using a sufficiently new version of Tcl,
  454. # rules-ext.vc will define NMAKEHLPC appropriately to point to the
  455. # copy of nmakehlp.c to be used.
  456. !ifndef NMAKEHLPC
  457. # Default to the one in the current directory (the extension's own nmakehlp.c)
  458. NMAKEHLPC = nmakehlp.c
  459. !if !$(DOING_TCL)
  460. !if $(TCLINSTALL)
  461. !if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
  462. NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
  463. !endif
  464. !else # !$(TCLINSTALL)
  465. !if exist("$(_TCLDIR)\win\nmakehlp.c")
  466. NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
  467. !endif
  468. !endif # $(TCLINSTALL)
  469. !endif # !$(DOING_TCL)
  470. !endif # NMAKEHLPC
  471. # We always build nmakehlp even if it exists since we do not know
  472. # what source it was built from.
  473. !if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
  474. !if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
  475. !endif
  476. !else
  477. !if [copy $(NMAKEHLPC:nmakehlp.c=x86_64-w64-mingw32-nmakehlp.exe) nmakehlp.exe >NUL]
  478. !endif
  479. !endif
  480. ################################################################
  481. # 5. Test for compiler features
  482. # Visual C++ compiler options have changed over the years. Check
  483. # which options are supported by the compiler in use.
  484. #
  485. # The following macros are set:
  486. # OPTIMIZATIONS - the compiler flags to be used for optimized builds
  487. # DEBUGFLAGS - the compiler flags to be used for debug builds
  488. # LINKERFLAGS - Flags passed to the linker
  489. #
  490. # Note that these are the compiler settings *available*, not those
  491. # that will be *used*. The latter depends on the OPTS macro settings
  492. # which we have not yet parsed.
  493. #
  494. # Also note that some of the flags in OPTIMIZATIONS are not really
  495. # related to optimization. They are placed there only for legacy reasons
  496. # as some extensions expect them to be included in that macro.
  497. # -Op improves float consistency. Note only needed for older compilers
  498. # Newer compilers do not need or support this option.
  499. !if [nmakehlp -c -Op]
  500. FPOPTS = -Op
  501. !endif
  502. # Strict floating point semantics - present in newer compilers in lieu of -Op
  503. !if [nmakehlp -c -fp:strict]
  504. FPOPTS = $(FPOPTS) -fp:strict
  505. !endif
  506. !if "$(MACHINE)" == "IX86"
  507. ### test for pentium errata
  508. !if [nmakehlp -c -QI0f]
  509. !message *** Compiler has 'Pentium 0x0f fix'
  510. FPOPTS = $(FPOPTS) -QI0f
  511. !else
  512. !message *** Compiler does not have 'Pentium 0x0f fix'
  513. !endif
  514. !endif
  515. ### test for optimizations
  516. # /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
  517. # documentation. Note we do NOT want /Gs as that inserts a _chkstk
  518. # stack probe at *every* function entry, not just those with more than
  519. # a page of stack allocation resulting in a performance hit. However,
  520. # /O2 documentation is misleading as its stack probes are simply the
  521. # default page size locals allocation probes and not what is implied
  522. # by an explicit /Gs option.
  523. OPTIMIZATIONS = $(FPOPTS)
  524. !if [nmakehlp -c -O2]
  525. OPTIMIZING = 1
  526. OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
  527. !else
  528. # Legacy, really. All modern compilers support this
  529. !message *** Compiler does not have 'Optimizations'
  530. OPTIMIZING = 0
  531. !endif
  532. # Checks for buffer overflows in local arrays
  533. !if [nmakehlp -c -GS]
  534. OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
  535. !endif
  536. # Link time optimization. Note that this option (potentially) makes
  537. # generated libraries only usable by the specific VC++ version that
  538. # created it. Requires /LTCG linker option
  539. !if [nmakehlp -c -GL]
  540. OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
  541. CC_GL_OPT_ENABLED = 1
  542. !else
  543. # In newer compilers -GL and -YX are incompatible.
  544. !if [nmakehlp -c -YX]
  545. OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
  546. !endif
  547. !endif # [nmakehlp -c -GL]
  548. DEBUGFLAGS = $(FPOPTS)
  549. # Run time error checks. Not available or valid in a release, non-debug build
  550. # RTC is for modern compilers, -GZ is legacy
  551. !if [nmakehlp -c -RTC1]
  552. DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
  553. !elseif [nmakehlp -c -GZ]
  554. DEBUGFLAGS = $(DEBUGFLAGS) -GZ
  555. !endif
  556. #----------------------------------------------------------------
  557. # Linker flags
  558. # LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
  559. # if the linker supports a specific option. Without these flags link will
  560. # return "LNK1561: entry point must be defined" error compiling from VS-IDE:
  561. # They are not passed through to the actual application / extension
  562. # link rules.
  563. !ifndef LINKER_TESTFLAGS
  564. LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
  565. !endif
  566. LINKERFLAGS =
  567. # If compiler has enabled link time optimization, linker must too with -ltcg
  568. !ifdef CC_GL_OPT_ENABLED
  569. !if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
  570. LINKERFLAGS = $(LINKERFLAGS) -ltcg
  571. !endif
  572. !endif
  573. ################################################################
  574. # 6. Extract various version numbers from headers
  575. # For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
  576. # respectively. For extensions, versions are extracted from the
  577. # configure.in or configure.ac from the TEA configuration if it
  578. # exists, and unset otherwise.
  579. # Sets the following macros:
  580. # TCL_MAJOR_VERSION
  581. # TCL_MINOR_VERSION
  582. # TCL_RELEASE_SERIAL
  583. # TCL_PATCH_LEVEL
  584. # TCL_PATCH_LETTER
  585. # TCL_VERSION
  586. # TK_MAJOR_VERSION
  587. # TK_MINOR_VERSION
  588. # TK_RELEASE_SERIAL
  589. # TK_PATCH_LEVEL
  590. # TK_PATCH_LETTER
  591. # TK_VERSION
  592. # DOTVERSION - set as (for example) 2.5
  593. # VERSION - set as (for example 25)
  594. #--------------------------------------------------------------
  595. !if [echo REM = This file is generated from rules.vc > versions.vc]
  596. !endif
  597. !if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
  598. && [nmakehlp -V "$(_TCL_H)" "define TCL_MAJOR_VERSION" >> versions.vc]
  599. !endif
  600. !if [echo TCL_MINOR_VERSION = \>> versions.vc] \
  601. && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
  602. !endif
  603. !if [echo TCL_RELEASE_SERIAL = \>> versions.vc] \
  604. && [nmakehlp -V "$(_TCL_H)" TCL_RELEASE_SERIAL >> versions.vc]
  605. !endif
  606. !if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
  607. && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
  608. !endif
  609. !if defined(_TK_H)
  610. !if [echo TK_MAJOR_VERSION = \>> versions.vc] \
  611. && [nmakehlp -V $(_TK_H) "define TK_MAJOR_VERSION" >> versions.vc]
  612. !endif
  613. !if [echo TK_MINOR_VERSION = \>> versions.vc] \
  614. && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
  615. !endif
  616. !if [echo TK_RELEASE_SERIAL = \>> versions.vc] \
  617. && [nmakehlp -V "$(_TK_H)" TK_RELEASE_SERIAL >> versions.vc]
  618. !endif
  619. !if [echo TK_PATCH_LEVEL = \>> versions.vc] \
  620. && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
  621. !endif
  622. !endif # _TK_H
  623. !include versions.vc
  624. TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
  625. TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
  626. !if [nmakehlp -f $(TCL_PATCH_LEVEL) "a"]
  627. TCL_PATCH_LETTER = a
  628. !elseif [nmakehlp -f $(TCL_PATCH_LEVEL) "b"]
  629. TCL_PATCH_LETTER = b
  630. !else
  631. TCL_PATCH_LETTER = .
  632. !endif
  633. !if defined(_TK_H)
  634. TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
  635. TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
  636. !if [nmakehlp -f $(TK_PATCH_LEVEL) "a"]
  637. TK_PATCH_LETTER = a
  638. !elseif [nmakehlp -f $(TK_PATCH_LEVEL) "b"]
  639. TK_PATCH_LETTER = b
  640. !else
  641. TK_PATCH_LETTER = .
  642. !endif
  643. !endif
  644. # Set DOTVERSION and VERSION
  645. !if $(DOING_TCL)
  646. DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
  647. VERSION = $(TCL_VERSION)
  648. !elseif $(DOING_TK)
  649. DOTVERSION = $(TK_DOTVERSION)
  650. VERSION = $(TK_VERSION)
  651. !else # Doing a non-Tk extension
  652. # If parent makefile has not defined DOTVERSION, try to get it from TEA
  653. # first from a configure.in file, and then from configure.ac
  654. !ifndef DOTVERSION
  655. !if [echo DOTVERSION = \> versions.vc] \
  656. || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
  657. !if [echo DOTVERSION = \> versions.vc] \
  658. || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
  659. !error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
  660. !endif
  661. !endif
  662. !include versions.vc
  663. !endif # DOTVERSION
  664. VERSION = $(DOTVERSION:.=)
  665. !endif # $(DOING_TCL) ... etc.
  666. # Windows RC files have 3 version components. Ensure this irrespective
  667. # of how many components the package has specified. Basically, ensure
  668. # minimum 4 components by appending 4 0's and then pick out the first 4.
  669. # Also take care of the fact that DOTVERSION may have "a" or "b" instead
  670. # of "." separating the version components.
  671. DOTSEPARATED=$(DOTVERSION:a=.)
  672. DOTSEPARATED=$(DOTSEPARATED:b=.)
  673. !if [echo RCCOMMAVERSION = \> versions.vc] \
  674. || [for /f "tokens=1,2,3,4,5* delims=." %a in ("$(DOTSEPARATED).0.0.0.0") do echo %a,%b,%c,%d >> versions.vc]
  675. !error *** Could not generate RCCOMMAVERSION ***
  676. !endif
  677. !include versions.vc
  678. ########################################################################
  679. # 7. Parse the OPTS macro to work out the requested build configuration.
  680. # Based on this, we will construct the actual switches to be passed to the
  681. # compiler and linker using the macros defined in the previous section.
  682. # The following macros are defined by this section based on OPTS
  683. # STATIC_BUILD - 0 -> Tcl is to be built as a shared library
  684. # 1 -> build as a static library and shell
  685. # TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
  686. # DEBUG - 1 -> debug build, 0 -> release builds
  687. # SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
  688. # PROFILE - 1 -> generate profiling info, 0 -> no profiling
  689. # PGO - 1 -> profile based optimization, 0 -> no
  690. # MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
  691. # 0 -> link to static C runtime for static Tcl build.
  692. # Does not impact shared Tcl builds (STATIC_BUILD == 0)
  693. # Default: 1 for Tcl 8.7 and up, 0 otherwise.
  694. # TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
  695. # in the Tcl and Wish shell. 0 -> keep them as shared libraries. Does
  696. # not impact shared Tcl builds. Implied by STATIC_BUILD since Tcl 8.7.
  697. # USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
  698. # 0 -> Use the non-thread allocator.
  699. # UNCHECKED - 1 -> when doing a debug build with symbols, use the release
  700. # C runtime, 0 -> use the debug C runtime.
  701. # USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
  702. # CONFIG_CHECK - 1 -> check current build configuration against Tcl
  703. # configuration (ignored for Tcl itself)
  704. # _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build
  705. # (CRT library should support this, not needed for Tcl 9.x)
  706. # TCL_UTF_MAX=3 - forces a build using UTF-16 internally (not recommended).
  707. # Further, LINKERFLAGS are modified based on above.
  708. # Default values for all the above
  709. STATIC_BUILD = 0
  710. TCL_THREADS = 1
  711. DEBUG = 0
  712. SYMBOLS = 0
  713. PROFILE = 0
  714. PGO = 0
  715. MSVCRT = 1
  716. TCL_USE_STATIC_PACKAGES = 0
  717. USE_THREAD_ALLOC = 1
  718. UNCHECKED = 0
  719. CONFIG_CHECK = 1
  720. !if $(DOING_TCL)
  721. USE_STUBS = 0
  722. !else
  723. USE_STUBS = 1
  724. !endif
  725. # If OPTS is not empty AND does not contain "none" which turns off all OPTS
  726. # set the above macros based on OPTS content
  727. !if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
  728. # OPTS are specified, parse them
  729. !if [nmakehlp -f $(OPTS) "static"]
  730. !message *** Doing static
  731. STATIC_BUILD = 1
  732. !endif
  733. !if [nmakehlp -f $(OPTS) "nostubs"]
  734. !message *** Not using stubs
  735. USE_STUBS = 0
  736. !endif
  737. !if [nmakehlp -f $(OPTS) "nomsvcrt"]
  738. !message *** Doing nomsvcrt
  739. MSVCRT = 0
  740. !else
  741. !if [nmakehlp -f $(OPTS) "msvcrt"]
  742. !message *** Doing msvcrt
  743. !else
  744. !if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7 && $(STATIC_BUILD)
  745. MSVCRT = 0
  746. !endif
  747. !endif
  748. !endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
  749. !if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
  750. !message *** Doing staticpkg
  751. TCL_USE_STATIC_PACKAGES = 1
  752. !endif
  753. !if [nmakehlp -f $(OPTS) "nothreads"]
  754. !message *** Compile explicitly for non-threaded tcl
  755. TCL_THREADS = 0
  756. USE_THREAD_ALLOC= 0
  757. !endif
  758. !if $(TCL_MAJOR_VERSION) == 8
  759. !if [nmakehlp -f $(OPTS) "time64bit"]
  760. !message *** Force 64-bit time_t
  761. _USE_64BIT_TIME_T = 1
  762. !endif
  763. !if [nmakehlp -f $(OPTS) "utf16"]
  764. !message *** Force UTF-16 internally
  765. TCL_UTF_MAX = 3
  766. !endif
  767. !endif
  768. # Yes, it's weird that the "symbols" option controls DEBUG and
  769. # the "pdbs" option controls SYMBOLS. That's historical.
  770. !if [nmakehlp -f $(OPTS) "symbols"]
  771. !message *** Doing symbols
  772. DEBUG = 1
  773. !else
  774. DEBUG = 0
  775. !endif
  776. !if [nmakehlp -f $(OPTS) "pdbs"]
  777. !message *** Doing pdbs
  778. SYMBOLS = 1
  779. !else
  780. SYMBOLS = 0
  781. !endif
  782. !if [nmakehlp -f $(OPTS) "profile"]
  783. !message *** Doing profile
  784. PROFILE = 1
  785. !else
  786. PROFILE = 0
  787. !endif
  788. !if [nmakehlp -f $(OPTS) "pgi"]
  789. !message *** Doing profile guided optimization instrumentation
  790. PGO = 1
  791. !elseif [nmakehlp -f $(OPTS) "pgo"]
  792. !message *** Doing profile guided optimization
  793. PGO = 2
  794. !else
  795. PGO = 0
  796. !endif
  797. !if [nmakehlp -f $(OPTS) "loimpact"]
  798. !message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
  799. !endif
  800. # TBD - should get rid of this option
  801. !if [nmakehlp -f $(OPTS) "thrdalloc"]
  802. !message *** Doing thrdalloc
  803. USE_THREAD_ALLOC = 1
  804. !endif
  805. !if [nmakehlp -f $(OPTS) "tclalloc"]
  806. USE_THREAD_ALLOC = 0
  807. !endif
  808. !if [nmakehlp -f $(OPTS) "unchecked"]
  809. !message *** Doing unchecked
  810. UNCHECKED = 1
  811. !else
  812. UNCHECKED = 0
  813. !endif
  814. !if [nmakehlp -f $(OPTS) "noconfigcheck"]
  815. CONFIG_CHECK = 1
  816. !else
  817. CONFIG_CHECK = 0
  818. !endif
  819. !endif # "$(OPTS)" != "" && ... parsing of OPTS
  820. # Set linker flags based on above
  821. !if $(PGO) > 1
  822. !if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
  823. LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
  824. !else
  825. MSG=^
  826. This compiler does not support profile guided optimization.
  827. !error $(MSG)
  828. !endif
  829. !elseif $(PGO) > 0
  830. !if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
  831. LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
  832. !else
  833. MSG=^
  834. This compiler does not support profile guided optimization.
  835. !error $(MSG)
  836. !endif
  837. !endif
  838. ################################################################
  839. # 8. Parse the STATS macro to configure code instrumentation
  840. # The following macros are set by this section:
  841. # TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
  842. # 0 -> disables
  843. # TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
  844. # 0 -> disables
  845. # Default both are off
  846. TCL_MEM_DEBUG = 0
  847. TCL_COMPILE_DEBUG = 0
  848. !if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
  849. !if [nmakehlp -f $(STATS) "memdbg"]
  850. !message *** Doing memdbg
  851. TCL_MEM_DEBUG = 1
  852. !else
  853. TCL_MEM_DEBUG = 0
  854. !endif
  855. !if [nmakehlp -f $(STATS) "compdbg"]
  856. !message *** Doing compdbg
  857. TCL_COMPILE_DEBUG = 1
  858. !else
  859. TCL_COMPILE_DEBUG = 0
  860. !endif
  861. !endif
  862. ####################################################################
  863. # 9. Parse the CHECKS macro to configure additional compiler checks
  864. # The following macros are set by this section:
  865. # WARNINGS - compiler switches that control the warnings level
  866. # TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
  867. # 0 -> enable deprecated functions
  868. # Defaults - Permit deprecated functions and warning level 3
  869. TCL_NO_DEPRECATED = 0
  870. WARNINGS = -W3
  871. !if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
  872. !if [nmakehlp -f $(CHECKS) "nodep"]
  873. !message *** Doing nodep check
  874. TCL_NO_DEPRECATED = 1
  875. !endif
  876. !if [nmakehlp -f $(CHECKS) "fullwarn"]
  877. !message *** Doing full warnings check
  878. WARNINGS = -W4
  879. !if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
  880. LINKERFLAGS = $(LINKERFLAGS) -warn:3
  881. !endif
  882. !endif
  883. !if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
  884. !message *** Doing 64bit portability warnings
  885. WARNINGS = $(WARNINGS) -Wp64
  886. !endif
  887. !endif
  888. ################################################################
  889. # 10. Construct output directory and file paths
  890. # Figure-out how to name our intermediate and output directories.
  891. # In order to avoid inadvertent mixing of object files built using
  892. # different compilers, build configurations etc.,
  893. #
  894. # Naming convention (suffixes):
  895. # t = full thread support. (Not used for Tcl >= 8.7)
  896. # s = static library (as opposed to an import library)
  897. # g = linked to the debug enabled C run-time.
  898. # x = special static build when it links to the dynamic C run-time.
  899. #
  900. # The following macros are set in this section:
  901. # SUFX - the suffix to use for binaries based on above naming convention
  902. # BUILDDIRTOP - the toplevel default output directory
  903. # is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
  904. # TMP_DIR - directory where object files are created
  905. # OUT_DIR - directory where output executables are created
  906. # Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
  907. # parent makefile (or command line). The default values are
  908. # based on BUILDDIRTOP.
  909. # STUBPREFIX - name of the stubs library for this project
  910. # PRJIMPLIB - output path of the generated project import library
  911. # PRJLIBNAME - name of generated project library
  912. # PRJLIB - output path of generated project library
  913. # PRJSTUBLIBNAME - name of the generated project stubs library
  914. # PRJSTUBLIB - output path of the generated project stubs library
  915. # RESFILE - output resource file (only if not static build)
  916. SUFX = tsgx
  917. !if $(DEBUG)
  918. BUILDDIRTOP = Debug
  919. !else
  920. BUILDDIRTOP = Release
  921. !endif
  922. !if "$(MACHINE)" != "IX86"
  923. BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
  924. !endif
  925. !if $(VCVER) > 6
  926. BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
  927. !endif
  928. !if !$(DEBUG) || $(TCL_VERSION) > 86 || $(DEBUG) && $(UNCHECKED)
  929. SUFX = $(SUFX:g=)
  930. !endif
  931. TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
  932. !if !$(STATIC_BUILD)
  933. TMP_DIRFULL = $(TMP_DIRFULL:Static=)
  934. SUFX = $(SUFX:s=)
  935. EXT = dll
  936. TMP_DIRFULL = $(TMP_DIRFULL:X=)
  937. SUFX = $(SUFX:x=)
  938. !else
  939. TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
  940. EXT = lib
  941. !if !$(MSVCRT)
  942. TMP_DIRFULL = $(TMP_DIRFULL:X=)
  943. SUFX = $(SUFX:x=)
  944. !endif
  945. !endif
  946. !if !$(TCL_THREADS) || $(TCL_VERSION) > 86
  947. TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
  948. SUFX = $(SUFX:t=)
  949. !endif
  950. !ifndef TMP_DIR
  951. TMP_DIR = $(TMP_DIRFULL)
  952. !ifndef OUT_DIR
  953. OUT_DIR = .\$(BUILDDIRTOP)
  954. !endif
  955. !else
  956. !ifndef OUT_DIR
  957. OUT_DIR = $(TMP_DIR)
  958. !endif
  959. !endif
  960. # Relative paths -> absolute
  961. !if [echo OUT_DIR = \> nmakehlp.out] \
  962. || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
  963. !error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
  964. !endif
  965. !if [echo TMP_DIR = \>> nmakehlp.out] \
  966. || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
  967. !error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
  968. !endif
  969. !include nmakehlp.out
  970. # The name of the stubs library for the project being built
  971. STUBPREFIX = $(PROJECT)stub
  972. #
  973. # Set up paths to various Tcl executables and libraries needed by extensions
  974. #
  975. # TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc
  976. TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
  977. TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip
  978. !if $(DOING_TCL)
  979. TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe
  980. TCLSH = $(OUT_DIR)\$(TCLSHNAME)
  981. TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
  982. TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
  983. TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
  984. TCLSCRIPTZIP = $(OUT_DIR)\$(TCLSCRIPTZIPNAME)
  985. TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
  986. TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
  987. TCL_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
  988. !else # !$(DOING_TCL)
  989. !if $(TCLINSTALL) # Building against an installed Tcl
  990. # When building extensions, we need to locate tclsh. Depending on version
  991. # of Tcl we are building against, this may or may not have a "t" suffix.
  992. # Try various possibilities in turn.
  993. TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
  994. !if !exist("$(TCLSH)")
  995. TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
  996. !endif
  997. TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
  998. TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
  999. # When building extensions, may be linking against Tcl that does not add
  1000. # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
  1001. !if !exist("$(TCLIMPLIB)")
  1002. TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib
  1003. !endif
  1004. TCL_LIBRARY = $(_TCLDIR)\lib
  1005. TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
  1006. TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
  1007. TCLSCRIPTZIP = $(_TCLDIR)\lib\$(TCLSCRIPTZIPNAME)
  1008. TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
  1009. TCL_INCLUDES = -I"$(_TCLDIR)\include"
  1010. !else # Building against Tcl sources
  1011. TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
  1012. !if !exist($(TCLSH))
  1013. TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
  1014. !endif
  1015. TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
  1016. TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
  1017. # When building extensions, may be linking against Tcl that does not add
  1018. # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
  1019. !if !exist("$(TCLIMPLIB)")
  1020. TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib
  1021. !endif
  1022. TCL_LIBRARY = $(_TCLDIR)\library
  1023. TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
  1024. TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
  1025. TCLSCRIPTZIP = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCLSCRIPTZIPNAME)
  1026. TCLTOOLSDIR = $(_TCLDIR)\tools
  1027. TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
  1028. !endif # TCLINSTALL
  1029. tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
  1030. !endif # $(DOING_TCL)
  1031. # We need a tclsh that will run on the host machine as part of the build.
  1032. # IX86 runs on all architectures.
  1033. !ifndef TCLSH_NATIVE
  1034. !if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
  1035. TCLSH_NATIVE = $(TCLSH)
  1036. !else
  1037. !error You must explicitly set TCLSH_NATIVE for cross-compilation
  1038. !endif
  1039. !endif
  1040. # Do the same for Tk and Tk extensions that require the Tk libraries
  1041. !if $(DOING_TK) || $(NEED_TK)
  1042. WISHNAMEPREFIX = wish
  1043. WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
  1044. TKLIBNAME8 = tk$(TK_VERSION)$(SUFX).$(EXT)
  1045. TKLIBNAME9 = tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
  1046. !if $(TCL_MAJOR_VERSION) == 8
  1047. TKLIBNAME = tk$(TK_VERSION)$(SUFX).$(EXT)
  1048. TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
  1049. !else
  1050. TKLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
  1051. TKIMPLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).lib
  1052. !endif
  1053. TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
  1054. !if $(DOING_TK)
  1055. WISH = $(OUT_DIR)\$(WISHNAME)
  1056. TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
  1057. TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
  1058. TKLIB = $(OUT_DIR)\$(TKLIBNAME)
  1059. TK_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
  1060. TKSCRIPTZIP = $(OUT_DIR)\$(TKSCRIPTZIPNAME)
  1061. !else # effectively NEED_TK
  1062. !if $(TKINSTALL) # Building against installed Tk
  1063. WISH = $(_TKDIR)\bin\$(WISHNAME)
  1064. TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
  1065. TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
  1066. # When building extensions, may be linking against Tk that does not add
  1067. # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
  1068. !if !exist("$(TKIMPLIB)")
  1069. TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
  1070. TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
  1071. !endif
  1072. TK_INCLUDES = -I"$(_TKDIR)\include"
  1073. TKSCRIPTZIP = $(_TKDIR)\lib\$(TKSCRIPTZIPNAME)
  1074. !else # Building against Tk sources
  1075. WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
  1076. TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
  1077. TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
  1078. # When building extensions, may be linking against Tk that does not add
  1079. # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
  1080. !if !exist("$(TKIMPLIB)")
  1081. TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
  1082. TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
  1083. !endif
  1084. TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
  1085. TKSCRIPTZIP = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSCRIPTZIPNAME)
  1086. !endif # TKINSTALL
  1087. tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
  1088. !endif # $(DOING_TK)
  1089. !endif # $(DOING_TK) || $(NEED_TK)
  1090. # Various output paths
  1091. PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
  1092. PRJLIBNAME8 = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
  1093. PRJLIBNAME9 = tcl9$(PROJECT)$(VERSION)$(SUFX).$(EXT)
  1094. !if $(TCL_MAJOR_VERSION) == 8
  1095. PRJLIBNAME = $(PRJLIBNAME8)
  1096. !else
  1097. PRJLIBNAME = $(PRJLIBNAME9)
  1098. !endif
  1099. PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
  1100. PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
  1101. PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
  1102. # If extension parent makefile has not defined a resource definition file,
  1103. # we will generate one from standard template.
  1104. !if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
  1105. !ifdef RCFILE
  1106. RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
  1107. !else
  1108. RESFILE = $(TMP_DIR)\$(PROJECT).res
  1109. !endif
  1110. !endif
  1111. ###################################################################
  1112. # 11. Construct the paths for the installation directories
  1113. # The following macros get defined in this section:
  1114. # LIB_INSTALL_DIR - where libraries should be installed
  1115. # BIN_INSTALL_DIR - where the executables should be installed
  1116. # DOC_INSTALL_DIR - where documentation should be installed
  1117. # SCRIPT_INSTALL_DIR - where scripts should be installed
  1118. # INCLUDE_INSTALL_DIR - where C include files should be installed
  1119. # DEMO_INSTALL_DIR - where demos should be installed
  1120. # PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
  1121. !if $(DOING_TCL) || $(DOING_TK)
  1122. LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
  1123. BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
  1124. DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
  1125. !if $(DOING_TCL)
  1126. SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
  1127. MODULE_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(TCL_MAJOR_VERSION)
  1128. !else # DOING_TK
  1129. SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
  1130. !endif
  1131. DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
  1132. INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
  1133. !else # extension other than Tk
  1134. PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
  1135. !if $(MULTIPLATFORM_INSTALL)
  1136. LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY)
  1137. BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY)
  1138. !else
  1139. LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
  1140. BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
  1141. !endif
  1142. DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
  1143. SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
  1144. DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
  1145. INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\..\include
  1146. !endif
  1147. ###################################################################
  1148. # 12. Set up actual options to be passed to the compiler and linker
  1149. # Now we have all the information we need, set up the actual flags and
  1150. # options that we will pass to the compiler and linker. The main
  1151. # makefile should use these in combination with whatever other flags
  1152. # and switches are specific to it.
  1153. # The following macros are defined, names are for historical compatibility:
  1154. # OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
  1155. # COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
  1156. # crt - Compiler switch that selects the appropriate C runtime
  1157. # cdebug - Compiler switches related to debug AND optimizations
  1158. # cwarn - Compiler switches that set warning levels
  1159. # cflags - complete compiler switches (subsumes cdebug and cwarn)
  1160. # ldebug - Linker switches controlling debug information and optimization
  1161. # lflags - complete linker switches (subsumes ldebug) except subsystem type
  1162. # dlllflags - complete linker switches to build DLLs (subsumes lflags)
  1163. # conlflags - complete linker switches for console program (subsumes lflags)
  1164. # guilflags - complete linker switches for GUI program (subsumes lflags)
  1165. # baselibs - minimum Windows libraries required. Parent makefile can
  1166. # define PRJ_LIBS before including rules.rc if additional libs are needed
  1167. OPTDEFINES = /DSTDC_HEADERS /DUSE_NMAKE=1
  1168. !if $(VCVERSION) > 1600
  1169. OPTDEFINES = $(OPTDEFINES) /DHAVE_STDINT_H=1
  1170. !else
  1171. OPTDEFINES = $(OPTDEFINES) /DMP_NO_STDINT=1
  1172. !endif
  1173. !if $(VCVERSION) >= 1800
  1174. OPTDEFINES = $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1
  1175. !endif
  1176. !if $(TCL_MEM_DEBUG)
  1177. OPTDEFINES = $(OPTDEFINES) /DTCL_MEM_DEBUG
  1178. !endif
  1179. !if $(TCL_COMPILE_DEBUG)
  1180. OPTDEFINES = $(OPTDEFINES) /DTCL_COMPILE_DEBUG /DTCL_COMPILE_STATS
  1181. !endif
  1182. !if $(TCL_THREADS) && $(TCL_VERSION) < 87
  1183. OPTDEFINES = $(OPTDEFINES) /DTCL_THREADS=1
  1184. !if $(USE_THREAD_ALLOC) && $(TCL_VERSION) < 87
  1185. OPTDEFINES = $(OPTDEFINES) /DUSE_THREAD_ALLOC=1
  1186. !endif
  1187. !endif
  1188. !if $(STATIC_BUILD)
  1189. OPTDEFINES = $(OPTDEFINES) /DSTATIC_BUILD
  1190. !elseif $(TCL_VERSION) > 86
  1191. OPTDEFINES = $(OPTDEFINES) /DTCL_WITH_EXTERNAL_TOMMATH
  1192. !if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
  1193. OPTDEFINES = $(OPTDEFINES) /DMP_64BIT
  1194. !endif
  1195. !endif
  1196. !if $(TCL_NO_DEPRECATED)
  1197. OPTDEFINES = $(OPTDEFINES) /DTCL_NO_DEPRECATED
  1198. !endif
  1199. !if $(USE_STUBS)
  1200. # Note we do not define USE_TCL_STUBS even when building tk since some
  1201. # test targets in tk do not use stubs
  1202. !if !$(DOING_TCL)
  1203. USE_STUBS_DEFS = /DUSE_TCL_STUBS /DUSE_TCLOO_STUBS
  1204. !if $(NEED_TK)
  1205. USE_STUBS_DEFS = $(USE_STUBS_DEFS) /DUSE_TK_STUBS
  1206. !endif
  1207. !endif
  1208. !endif # USE_STUBS
  1209. !if !$(DEBUG)
  1210. OPTDEFINES = $(OPTDEFINES) /DNDEBUG
  1211. !if $(OPTIMIZING)
  1212. OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
  1213. !endif
  1214. !endif
  1215. !if $(PROFILE)
  1216. OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_PROFILED
  1217. !endif
  1218. !if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
  1219. OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_DO64BIT
  1220. !endif
  1221. !if $(VCVERSION) < 1300
  1222. OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64=1
  1223. !endif
  1224. !if $(TCL_MAJOR_VERSION) == 8
  1225. !if "$(_USE_64BIT_TIME_T)" == "1"
  1226. OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
  1227. !endif
  1228. # _ATL_XP_TARGETING - Newer SDK's need this to build for XP
  1229. COMPILERFLAGS = /D_ATL_XP_TARGETING
  1230. !endif
  1231. !if "$(TCL_UTF_MAX)" == "3"
  1232. OPTDEFINES = $(OPTDEFINES) /DTCL_UTF_MAX=3
  1233. !endif
  1234. # Like the TEA system only set this non empty for non-Tk extensions
  1235. # Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
  1236. # so we pass both
  1237. !if !$(DOING_TCL) && !$(DOING_TK)
  1238. PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
  1239. /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
  1240. /DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
  1241. /DMODULE_SCOPE=extern
  1242. !endif
  1243. # crt picks the C run time based on selected OPTS
  1244. !if $(MSVCRT)
  1245. !if $(DEBUG) && !$(UNCHECKED)
  1246. crt = -MDd
  1247. !else
  1248. crt = -MD
  1249. !endif
  1250. !else
  1251. !if $(DEBUG) && !$(UNCHECKED)
  1252. crt = -MTd
  1253. !else
  1254. crt = -MT
  1255. !endif
  1256. !endif
  1257. # cdebug includes compiler options for debugging as well as optimization.
  1258. !if $(DEBUG)
  1259. # In debugging mode, optimizations need to be disabled
  1260. cdebug = -Zi -Od $(DEBUGFLAGS)
  1261. !else
  1262. cdebug = $(OPTIMIZATIONS)
  1263. !if $(SYMBOLS)
  1264. cdebug = $(cdebug) -Zi
  1265. !endif
  1266. !endif # $(DEBUG)
  1267. # cwarn includes default warning levels, also C4090 (buggy) and C4146 is useless.
  1268. cwarn = $(WARNINGS) -wd4090 -wd4146
  1269. !if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
  1270. # Disable pointer<->int warnings related to cast between different sizes
  1271. # There are a gadzillion of these due to use of ClientData and
  1272. # clutter up compiler
  1273. # output increasing chance of a real warning getting lost. So disable them.
  1274. # Eventually some day, Tcl will be 64-bit clean.
  1275. cwarn = $(cwarn) -wd4311 -wd4312
  1276. !endif
  1277. ### Common compiler options that are architecture specific
  1278. !if "$(MACHINE)" == "ARM"
  1279. carch = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
  1280. !else
  1281. carch =
  1282. !endif
  1283. # cpuid is only available on intel machines
  1284. !if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "AMD64"
  1285. carch = $(carch) /DHAVE_CPUID=1
  1286. !endif
  1287. !if $(DEBUG)
  1288. # Turn warnings into errors
  1289. cwarn = $(cwarn) -WX
  1290. !endif
  1291. INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
  1292. !if !$(DOING_TCL) && !$(DOING_TK)
  1293. INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)"
  1294. !endif
  1295. # These flags are defined roughly in the order of the pre-reform
  1296. # rules.vc/makefile.vc to help visually compare that the pre- and
  1297. # post-reform build logs
  1298. # cflags contains generic flags used for building practically all object files
  1299. cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
  1300. # appcflags contains $(cflags) and flags for building the application
  1301. # object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
  1302. # flags used for building shared object files The two differ in the
  1303. # BUILD_$(PROJECT) macro which should be defined only for the shared
  1304. # library *implementation* and not for its caller interface
  1305. appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
  1306. appcflags = $(appcflags_nostubs) $(USE_STUBS_DEFS)
  1307. pkgcflags = $(appcflags) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT)
  1308. pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT)
  1309. # stubscflags contains $(cflags) plus flags used for building a stubs
  1310. # library for the package. Note: /DSTATIC_BUILD is defined in
  1311. # $(OPTDEFINES) only if the OPTS configuration indicates a static
  1312. # library. However the stubs library is ALWAYS static hence included
  1313. # here irrespective of the OPTS setting.
  1314. #
  1315. # TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
  1316. # without stating why. Tcl itself compiled stubs libs with this flag.
  1317. # so we do not remove it from cflags. -GL may prevent extensions
  1318. # compiled with one VC version to fail to link against stubs library
  1319. # compiled with another VC version. Check for this and fix accordingly.
  1320. stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) /Zl /GL- /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS)
  1321. # Link flags
  1322. !if $(DEBUG)
  1323. ldebug = -debug -debugtype:cv
  1324. !else
  1325. ldebug = -release -opt:ref -opt:icf,3
  1326. !if $(SYMBOLS)
  1327. ldebug = $(ldebug) -debug -debugtype:cv
  1328. !endif
  1329. !endif
  1330. # Note: Profiling is currently only possible with the Visual Studio Enterprise
  1331. !if $(PROFILE)
  1332. ldebug= $(ldebug) -profile
  1333. !endif
  1334. ### Declarations common to all linker versions
  1335. lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
  1336. !if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
  1337. lflags = $(lflags) -nodefaultlib:libucrt.lib
  1338. !endif
  1339. dlllflags = $(lflags) -dll
  1340. conlflags = $(lflags) -subsystem:console
  1341. guilflags = $(lflags) -subsystem:windows
  1342. # Libraries that are required for every image.
  1343. # Extensions should define any additional libraries with $(PRJ_LIBS)
  1344. winlibs = kernel32.lib advapi32.lib
  1345. !if $(NEED_TK)
  1346. winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
  1347. !endif
  1348. # Avoid 'unresolved external symbol __security_cookie' errors.
  1349. # c.f. http://support.microsoft.com/?id=894573
  1350. !if "$(MACHINE)" == "AMD64"
  1351. !if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
  1352. winlibs = $(winlibs) bufferoverflowU.lib
  1353. !endif
  1354. !endif
  1355. baselibs = $(winlibs) $(PRJ_LIBS)
  1356. !if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
  1357. baselibs = $(baselibs) ucrt.lib
  1358. !endif
  1359. ################################################################
  1360. # 13. Define standard commands, common make targets and implicit rules
  1361. CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
  1362. CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
  1363. CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
  1364. LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
  1365. DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
  1366. CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
  1367. GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
  1368. RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
  1369. $(TCL_INCLUDES) \
  1370. /DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
  1371. /DCOMMAVERSION=$(RCCOMMAVERSION) \
  1372. /DDOTVERSION=\"$(DOTVERSION)\" \
  1373. /DVERSION=\"$(VERSION)\" \
  1374. /DSUFX=\"$(SUFX)\" \
  1375. /DPROJECT=\"$(PROJECT)\" \
  1376. /DPRJLIBNAME=\"$(PRJLIBNAME)\"
  1377. !ifndef DEFAULT_BUILD_TARGET
  1378. DEFAULT_BUILD_TARGET = $(PROJECT)
  1379. !endif
  1380. default-target: $(DEFAULT_BUILD_TARGET)
  1381. !if $(MULTIPLATFORM_INSTALL)
  1382. default-pkgindex:
  1383. @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
  1384. @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
  1385. [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
  1386. @echo } else { >> $(OUT_DIR)\pkgIndex.tcl
  1387. @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
  1388. [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
  1389. @echo } >> $(OUT_DIR)\pkgIndex.tcl
  1390. !else
  1391. default-pkgindex:
  1392. @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
  1393. @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
  1394. [list load [file join $$dir $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
  1395. @echo } else { >> $(OUT_DIR)\pkgIndex.tcl
  1396. @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
  1397. [list load [file join $$dir $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
  1398. @echo } >> $(OUT_DIR)\pkgIndex.tcl
  1399. !endif
  1400. default-pkgindex-tea:
  1401. @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
  1402. @PACKAGE_VERSION@ $(DOTVERSION)
  1403. @PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
  1404. @PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
  1405. @PKG_LIB_FILE@ $(PRJLIBNAME)
  1406. @PKG_LIB_FILE8@ $(PRJLIBNAME8)
  1407. @PKG_LIB_FILE9@ $(PRJLIBNAME9)
  1408. <<
  1409. default-install: default-install-binaries default-install-libraries
  1410. !if $(SYMBOLS)
  1411. default-install: default-install-pdbs
  1412. !endif
  1413. # Again to deal with historical brokenness, there is some confusion
  1414. # in terminlogy. For extensions, the "install-binaries" was used to
  1415. # locate target directory for *binary shared libraries* and thus
  1416. # the appropriate macro is LIB_INSTALL_DIR since BIN_INSTALL_DIR is
  1417. # for executables (exes). On the other hand the "install-libraries"
  1418. # target is for *scripts* and should have been called "install-scripts".
  1419. default-install-binaries: $(PRJLIB)
  1420. @echo Installing binaries to '$(LIB_INSTALL_DIR)'
  1421. @if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
  1422. @$(CPY) $(PRJLIB) "$(LIB_INSTALL_DIR)" >NUL
  1423. # Alias for default-install-scripts
  1424. default-install-libraries: default-install-scripts
  1425. default-install-scripts: $(OUT_DIR)\pkgIndex.tcl
  1426. @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
  1427. @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
  1428. @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
  1429. @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
  1430. default-install-stubs:
  1431. @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
  1432. @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
  1433. @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
  1434. default-install-pdbs:
  1435. @echo Installing PDBs to '$(LIB_INSTALL_DIR)'
  1436. @if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
  1437. @$(CPY) "$(OUT_DIR)\*.pdb" "$(LIB_INSTALL_DIR)\"
  1438. # "emacs font-lock highlighting fix
  1439. default-install-docs-html:
  1440. @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
  1441. @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
  1442. @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
  1443. default-install-docs-n:
  1444. @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
  1445. @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
  1446. @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
  1447. default-install-demos:
  1448. @echo Installing demos to '$(DEMO_INSTALL_DIR)'
  1449. @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
  1450. @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
  1451. default-clean:
  1452. @echo Cleaning $(TMP_DIR)\* ...
  1453. @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
  1454. @echo Cleaning $(WIN_DIR)\nmakehlp.obj, nmakehlp.exe ...
  1455. @if exist $(WIN_DIR)\nmakehlp.obj del $(WIN_DIR)\nmakehlp.obj
  1456. @if exist $(WIN_DIR)\nmakehlp.exe del $(WIN_DIR)\nmakehlp.exe
  1457. @if exist $(WIN_DIR)\nmakehlp.out del $(WIN_DIR)\nmakehlp.out
  1458. @echo Cleaning $(WIN_DIR)\nmhlp-out.txt ...
  1459. @if exist $(WIN_DIR)\nmhlp-out.txt del $(WIN_DIR)\nmhlp-out.txt
  1460. @echo Cleaning $(WIN_DIR)\_junk.pch ...
  1461. @if exist $(WIN_DIR)\_junk.pch del $(WIN_DIR)\_junk.pch
  1462. @echo Cleaning $(WIN_DIR)\vercl.x, vercl.i ...
  1463. @if exist $(WIN_DIR)\vercl.x del $(WIN_DIR)\vercl.x
  1464. @if exist $(WIN_DIR)\vercl.i del $(WIN_DIR)\vercl.i
  1465. @echo Cleaning $(WIN_DIR)\versions.vc, version.vc ...
  1466. @if exist $(WIN_DIR)\versions.vc del $(WIN_DIR)\versions.vc
  1467. @if exist $(WIN_DIR)\version.vc del $(WIN_DIR)\version.vc
  1468. default-hose: default-clean
  1469. @echo Hosing $(OUT_DIR)\* ...
  1470. @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
  1471. # Only for backward compatibility
  1472. default-distclean: default-hose
  1473. default-setup:
  1474. @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
  1475. @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
  1476. !if "$(TESTPAT)" != ""
  1477. TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
  1478. !endif
  1479. default-test: default-setup $(PROJECT)
  1480. @set TCLLIBPATH=$(OUT_DIR:\=/)
  1481. @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
  1482. cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
  1483. default-shell: default-setup $(PROJECT)
  1484. @set TCLLIBPATH=$(OUT_DIR:\=/)
  1485. @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
  1486. $(DEBUGGER) $(TCLSH)
  1487. # Generation of Windows version resource
  1488. !ifdef RCFILE
  1489. # Note: don't use $** in below rule because there may be other dependencies
  1490. # and only the "main" rc must be passed to the resource compiler
  1491. $(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
  1492. $(RESCMD) $(RCDIR)\$(PROJECT).rc
  1493. !else
  1494. # If parent makefile has not defined a resource definition file,
  1495. # we will generate one from standard template.
  1496. $(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
  1497. $(TMP_DIR)\$(PROJECT).rc:
  1498. @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
  1499. #include <winver.h>
  1500. VS_VERSION_INFO VERSIONINFO
  1501. FILEVERSION COMMAVERSION
  1502. PRODUCTVERSION COMMAVERSION
  1503. FILEFLAGSMASK 0x3fL
  1504. #ifdef DEBUG
  1505. FILEFLAGS VS_FF_DEBUG
  1506. #else
  1507. FILEFLAGS 0x0L
  1508. #endif
  1509. FILEOS VOS_NT_WINDOWS32
  1510. FILETYPE VFT_DLL
  1511. FILESUBTYPE 0x0L
  1512. BEGIN
  1513. BLOCK "StringFileInfo"
  1514. BEGIN
  1515. BLOCK "040904b0"
  1516. BEGIN
  1517. VALUE "FileDescription", "Tcl extension " PROJECT
  1518. VALUE "OriginalFilename", PRJLIBNAME
  1519. VALUE "FileVersion", DOTVERSION
  1520. VALUE "ProductName", "Package " PROJECT " for Tcl"
  1521. VALUE "ProductVersion", DOTVERSION
  1522. END
  1523. END
  1524. BLOCK "VarFileInfo"
  1525. BEGIN
  1526. VALUE "Translation", 0x409, 1200
  1527. END
  1528. END
  1529. <<
  1530. !endif # ifdef RCFILE
  1531. !ifndef DISABLE_IMPLICIT_RULES
  1532. DISABLE_IMPLICIT_RULES = 0
  1533. !endif
  1534. !if !$(DISABLE_IMPLICIT_RULES)
  1535. # Implicit rule definitions - only for building library objects. For stubs and
  1536. # main application, the makefile should define explicit rules.
  1537. {$(ROOT)}.c{$(TMP_DIR)}.obj::
  1538. $(CCPKGCMD) @<<
  1539. $<
  1540. <<
  1541. {$(WIN_DIR)}.c{$(TMP_DIR)}.obj::
  1542. $(CCPKGCMD) @<<
  1543. $<
  1544. <<
  1545. {$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
  1546. $(CCPKGCMD) @<<
  1547. $<
  1548. <<
  1549. {$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
  1550. $(CCPKGCMD) @<<
  1551. $<
  1552. <<
  1553. {$(RCDIR)}.rc{$(TMP_DIR)}.res:
  1554. $(RESCMD) $<
  1555. {$(WIN_DIR)}.rc{$(TMP_DIR)}.res:
  1556. $(RESCMD) $<
  1557. {$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
  1558. $(RESCMD) $<
  1559. .SUFFIXES:
  1560. .SUFFIXES:.c .rc
  1561. !endif
  1562. ################################################################
  1563. # 14. Sanity check selected options against Tcl build options
  1564. # When building an extension, certain configuration options should
  1565. # match the ones used when Tcl was built. Here we check and
  1566. # warn on a mismatch.
  1567. !if !$(DOING_TCL)
  1568. !if $(TCLINSTALL) # Building against an installed Tcl
  1569. !if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
  1570. TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
  1571. !endif
  1572. !else # !$(TCLINSTALL) - building against Tcl source
  1573. !if exist("$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake")
  1574. TCLNMAKECONFIG = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake"
  1575. !endif
  1576. !endif # TCLINSTALL
  1577. !if $(CONFIG_CHECK)
  1578. !ifdef TCLNMAKECONFIG
  1579. !include $(TCLNMAKECONFIG)
  1580. !if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
  1581. !error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
  1582. !endif
  1583. !if $(TCL_VERSION) < 87 && defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
  1584. !message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
  1585. !endif
  1586. !if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
  1587. !message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
  1588. !endif
  1589. !endif
  1590. !endif # TCLNMAKECONFIG
  1591. !endif # !$(DOING_TCL)
  1592. #----------------------------------------------------------
  1593. # Display stats being used.
  1594. #----------------------------------------------------------
  1595. !if !$(DOING_TCL)
  1596. !message *** Building against Tcl at '$(_TCLDIR)'
  1597. !endif
  1598. !if !$(DOING_TK) && $(NEED_TK)
  1599. !message *** Building against Tk at '$(_TKDIR)'
  1600. !endif
  1601. !message *** Intermediate directory will be '$(TMP_DIR)'
  1602. !message *** Output directory will be '$(OUT_DIR)'
  1603. !message *** Installation, if selected, will be in '$(_INSTALLDIR)'
  1604. !message *** Suffix for binaries will be '$(SUFX)'
  1605. !message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
  1606. !endif # ifdef _RULES_VC