]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/tools/msvc.jam
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / tools / build / src / tools / msvc.jam
1 # Copyright (c) 2003 David Abrahams
2 # Copyright (c) 2005 Vladimir Prus
3 # Copyright (c) 2005 Alexey Pakhunov
4 # Copyright (c) 2006 Bojan Resnik
5 # Copyright (c) 2006 Ilya Sokolov
6 # Copyright (c) 2007-2017 Rene Rivera
7 # Copyright (c) 2008 Jurko Gospodnetic
8 # Copyright (c) 2014 Microsoft Corporation
9 #
10 # Distributed under the Boost Software License, Version 1.0.
11 # (See accompanying file LICENSE_1_0.txt or copy at
12 # http://www.boost.org/LICENSE_1_0.txt)
13
14 ################################################################################
15 #
16 # MSVC Boost Build toolset module.
17 # --------------------------------
18 #
19 # All toolset versions need to have their location either auto-detected or
20 # explicitly specified except for the special 'default' version that expects the
21 # environment to find the needed tools or report an error.
22 #
23 ################################################################################
24
25 import "class" : new ;
26 import common ;
27 import feature ;
28 import generators ;
29 import mc ;
30 import midl ;
31 import os ;
32 import path ;
33 import pch ;
34 import project ;
35 import property ;
36 import property-set ;
37 import rc ;
38 import set ;
39 import toolset ;
40 import type ;
41 import virtual-target ;
42
43
44 type.register MANIFEST : manifest ;
45 feature.feature embed-manifest : on off : incidental propagated ;
46 feature.feature embed-manifest-file : : free dependency ;
47
48 type.register PDB : pdb ;
49
50
51 ################################################################################
52 #
53 # Public rules.
54 #
55 ################################################################################
56
57 # Initialize a specific toolset version configuration. As the result, path to
58 # compiler and, possible, program names are set up, and will be used when that
59 # version of compiler is requested. For example, you might have:
60 #
61 # using msvc : 6.5 : cl.exe ;
62 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
63 #
64 # The version parameter may be omitted:
65 #
66 # using msvc : : Z:/foo/bar/cl.exe ;
67 #
68 # The following keywords have special meanings when specified as versions:
69 # - all - all detected but not yet used versions will be marked as used
70 # with their default options.
71 # - default - this is an equivalent to an empty version.
72 #
73 # Depending on a supplied version, detected configurations and presence 'cl.exe'
74 # in the path different results may be achieved. The following table describes
75 # the possible scenarios:
76 #
77 # Nothing "x.y"
78 # Passed Nothing "x.y" detected, detected,
79 # version detected detected cl.exe in path cl.exe in path
80 #
81 # default Error Use "x.y" Create "default" Use "x.y"
82 # all None Use all None Use all
83 # x.y - Use "x.y" - Use "x.y"
84 # a.b Error Error Create "a.b" Create "a.b"
85 #
86 # "x.y" - refers to a detected version;
87 # "a.b" - refers to an undetected version.
88 #
89 # FIXME: Currently the command parameter and the <compiler> property parameter
90 # seem to overlap in duties. Remove this duplication. This seems to be related
91 # to why someone started preparing to replace init with configure rules.
92 #
93 rule init (
94 # The msvc version being configured. When omitted the tools invoked when no
95 # explicit version is given will be configured.
96 version ?
97
98 # The command used to invoke the compiler. If not specified:
99 # - if version is given, default location for that version will be
100 # searched
101 #
102 # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
103 # and 6.* will be searched
104 #
105 # - if compiler is not found in the default locations, PATH will be
106 # searched.
107 : command *
108
109 # Options may include:
110 #
111 # All options shared by multiple toolset types as handled by the
112 # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>,
113 # <fflags> & <linkflags>.
114 #
115 # <assembler>
116 # <compiler>
117 # <idl-compiler>
118 # <linker>
119 # <mc-compiler>
120 # <resource-compiler>
121 # Exact tool names to be used by this msvc toolset configuration.
122 #
123 # <compiler-filter>
124 # Command through which to pipe the output of running the compiler.
125 # For example to pass the output to STLfilt.
126 #
127 # <setup>
128 # Global setup command to invoke before running any of the msvc tools.
129 # It will be passed additional option parameters depending on the actual
130 # target platform.
131 #
132 # <setup-amd64>
133 # <setup-i386>
134 # <setup-ia64>
135 # <setup-arm>
136 # <setup-phone-i386>
137 # <setup-phone-arm>
138 # Platform specific setup command to invoke before running any of the
139 # msvc tools used when builing a target for a specific platform, e.g.
140 # when building a 32 or 64 bit executable.
141 #
142 # <rewrite-setup-scripts>
143 # Whether to rewrite setup scripts. New scripts will be output in
144 # build tree and will be used instead of originals in build actions.
145 # Possible values:
146 # * on - rewrite scripts, if they do not already exist (default)
147 # * always - always rewrite scripts, even if they already exist
148 # * off - use original setup scripts
149 : options *
150 )
151 {
152 if $(command)
153 {
154 options += <command>$(command) ;
155 }
156 configure $(version) : $(options) ;
157 }
158
159
160 # 'configure' is a newer version of 'init'. The parameter 'command' is passed as
161 # a part of the 'options' list. See the 'init' rule comment for more detailed
162 # information.
163 #
164 rule configure ( version ? : options * )
165 {
166 switch $(version)
167 {
168 case "all" :
169 if $(options)
170 {
171 import errors ;
172 errors.error "MSVC toolset configuration: options should be"
173 "empty when '$(version)' is specified." ;
174 }
175
176 # Configure (i.e. mark as used) all registered versions.
177 local all-versions = [ $(.versions).all ] ;
178 if ! $(all-versions)
179 {
180 if $(.debug-configuration)
181 {
182 ECHO "notice: [msvc-cfg] Asked to configure all registered"
183 "msvc toolset versions when there are none currently"
184 "registered." ;
185 }
186 }
187 else
188 {
189 for local v in $(all-versions)
190 {
191 # Note that there is no need to skip already configured
192 # versions here as this will request configure-really rule
193 # to configure the version using default options which will
194 # in turn cause it to simply do nothing in case the version
195 # has already been configured.
196 configure-really $(v) ;
197 }
198 }
199
200 case "default" :
201 configure-really : $(options) ;
202
203 case * :
204 configure-really $(version) : $(options) ;
205 }
206 }
207
208
209 # Sets up flag definitions dependent on the compiler version used.
210 # - 'version' is the version of compiler in N.M format.
211 # - 'conditions' is the property set to be used as flag conditions.
212 # - 'toolset' is the toolset for which flag settings are to be defined.
213 # This makes the rule reusable for other msvc-option-compatible compilers.
214 #
215 rule configure-version-specific ( toolset : version : conditions )
216 {
217 toolset.push-checking-for-flags-module unchecked ;
218 # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
219 # /Zc:wchar_t options that improve C++ standard conformance, but those
220 # options are off by default. If we are sure that the msvc version is at
221 # 7.*, add those options explicitly. We can be sure either if user specified
222 # version 7.* explicitly or if we auto-detected the version ourselves.
223 if ! [ MATCH ^(6\\.) : $(version) ]
224 {
225 toolset.flags $(toolset).compile CFLAGS $(conditions) : "/Zc:forScope" "/Zc:wchar_t" ;
226 toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
227
228 # Explicitly disable the 'function is deprecated' warning. Some msvc
229 # versions have a bug, causing them to emit the deprecation warning even
230 # with /W0.
231 toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ;
232
233 if [ MATCH "^([78]\\.)" : $(version) ]
234 {
235 # 64-bit compatibility warning deprecated since 9.0, see
236 # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
237 toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ;
238 }
239 }
240
241 #
242 # Processor-specific optimization.
243 #
244
245 if [ MATCH "^([67])" : $(version) ]
246 {
247 # 8.0 deprecates some of the options.
248 toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
249 toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
250 toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
251
252 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
253 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
254 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
255 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
256 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ;
257
258 # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
259 # tests will fail.
260 toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
261
262 # 7.1 and below have single-threaded static RTL.
263 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
264 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
265 }
266 else
267 {
268 # 8.0 and above adds some more options.
269 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : "/favor:blend" ;
270 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : "/favor:EM64T" ;
271 toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : "/favor:AMD64" ;
272
273 # 8.0 and above only has multi-threaded static RTL.
274 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
275 toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
276
277 # Specify target machine type so the linker will not need to guess.
278 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : "/MACHINE:X64" ;
279 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : "/MACHINE:X86" ;
280 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : "/MACHINE:IA64" ;
281 toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : "/MACHINE:ARM" ;
282
283 # Make sure that manifest will be generated even if there is no
284 # dependencies to put there.
285 toolset.flags $(toolset).link LINKFLAGS $(conditions) : /MANIFEST ;
286 }
287
288 toolset.pop-checking-for-flags-module ;
289 }
290
291 # Feature for handling targeting different Windows API sets.
292 feature.feature windows-api : desktop store phone : propagated composite link-incompatible ;
293 feature.compose <windows-api>store : <define>WINAPI_FAMILY=WINAPI_FAMILY_APP <define>_WIN32_WINNT=0x0602
294 <linkflags>/APPCONTAINER ;
295 feature.compose <windows-api>phone : <define>WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP <define>_WIN32_WINNT=0x0602
296 <linkflags>/APPCONTAINER <linkflags>"/NODEFAULTLIB:ole32.lib" <linkflags>"/NODEFAULTLIB:kernel32.lib" <linkflags>WindowsPhoneCore.lib ;
297 feature.set-default windows-api : desktop ;
298
299
300 # Registers this toolset including all of its flags, features & generators. Does
301 # nothing on repeated calls.
302 #
303 rule register-toolset ( )
304 {
305 if ! msvc in [ feature.values toolset ]
306 {
307 register-toolset-really ;
308 }
309 }
310
311 rule resolve-possible-msvc-version-alias ( version )
312 {
313 if $(.version-alias-$(version))
314 {
315 version = $(.version-alias-$(version)) ;
316 }
317 return $(version) ;
318 }
319
320
321 # Declare action for creating static libraries. If library exists, remove it
322 # before adding files. See
323 # http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
324 if [ os.name ] in NT
325 {
326 # The 'DEL' command would issue a message to stdout if the file does not
327 # exist, so need a check.
328 actions archive
329 {
330 if exist "$(<[1])" DEL "$(<[1])"
331 $(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
332 }
333 }
334 else
335 {
336 actions archive
337 {
338 $(.RM) "$(<[1])"
339 $(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
340 }
341 }
342
343 rule compile.asm ( targets + : sources * : properties * )
344 {
345 set-setup-command $(targets) : $(properties) ;
346 }
347
348 # For the assembler the following options are turned on by default:
349 #
350 # -Zp4 align structures to 4 bytes
351 # -Cp preserve case of user identifiers
352 # -Cx preserve case in publics, externs
353 #
354 actions compile.asm
355 {
356 $(.SETUP) $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
357 }
358
359
360 rule compile.c ( targets + : sources * : properties * )
361 {
362 set-setup-command $(targets) : $(properties) ;
363 C++FLAGS on $(targets[1]) = ;
364 get-rspline $(targets) : -TC ;
365 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
366 }
367
368
369 rule compile.c.preprocess ( targets + : sources * : properties * )
370 {
371 set-setup-command $(targets) : $(properties) ;
372 C++FLAGS on $(targets[1]) = ;
373 get-rspline $(targets) : -TC ;
374 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
375 }
376
377
378 rule compile.c.pch ( targets + : sources * : properties * )
379 {
380 set-setup-command $(targets) : $(properties) ;
381 C++FLAGS on $(targets[1]) = ;
382 get-rspline $(targets[1]) : -TC ;
383 get-rspline $(targets[2]) : -TC ;
384 local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
385 if $(pch-source)
386 {
387 DEPENDS $(<) : $(pch-source) ;
388 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
389 }
390 else
391 {
392 compile-c-c++-pch $(targets) : $(sources) ;
393 }
394 }
395
396 toolset.flags msvc YLOPTION : "-Yl" ;
397
398 # Action for running the C/C++ compiler without using precompiled headers.
399 #
400 # WARNING: Synchronize any changes this in action with intel-win
401 #
402 # Notes regarding PDB generation, for when we use
403 # <debug-symbols>on/<debug-store>database:
404 #
405 # 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring
406 # that the /Fd flag is dropped if PDB_CFLAG is empty.
407 #
408 # 2. When compiling executables's source files, PDB_NAME is set on a per-source
409 # file basis by rule compile-c-c++. The linker will pull these into the
410 # executable's PDB.
411 #
412 # 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb
413 # for each source file by rule archive, as in this case compiler must be used
414 # to create a single PDB for our library.
415 #
416 actions compile-c-c++ bind PDB_NAME
417 {
418 $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
419 }
420
421 actions preprocess-c-c++ bind PDB_NAME
422 {
423 $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)"
424 }
425
426 rule compile-c-c++ ( targets + : sources * )
427 {
428 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
429 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
430 PDB_NAME on $(<) = $(<[1]:S=.pdb) ;
431 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
432 }
433
434 rule preprocess-c-c++ ( targets + : sources * )
435 {
436 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
437 DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
438 PDB_NAME on $(<) = $(<:S=.pdb) ;
439 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
440 }
441
442 # Action for running the C/C++ compiler using precompiled headers. In addition
443 # to whatever else it needs to compile, this action also adds a temporary source
444 # .cpp file used to compile the precompiled headers themselves.
445 #
446 # The global .escaped-double-quote variable is used to avoid messing up Emacs
447 # syntax highlighting in the messy N-quoted code below.
448 actions compile-c-c++-pch
449 {
450 $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl))" $(.CC.FILTER)
451 }
452
453
454 # Action for running the C/C++ compiler using precompiled headers. An already
455 # built source file for compiling the precompiled headers is expected to be
456 # given as one of the source parameters.
457 actions compile-c-c++-pch-s
458 {
459 $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
460 }
461
462
463 rule compile.c++ ( targets + : sources * : properties * )
464 {
465 set-setup-command $(targets) : $(properties) ;
466 get-rspline $(targets) : -TP ;
467 compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
468 }
469
470 rule compile.c++.preprocess ( targets + : sources * : properties * )
471 {
472 set-setup-command $(targets) : $(properties) ;
473 get-rspline $(targets) : -TP ;
474 preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
475 }
476
477
478 rule compile.c++.pch ( targets + : sources * : properties * )
479 {
480 set-setup-command $(targets) : $(properties) ;
481 get-rspline $(targets[1]) : -TP ;
482 get-rspline $(targets[2]) : -TP ;
483 local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
484 if $(pch-source)
485 {
486 DEPENDS $(<) : $(pch-source) ;
487 compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
488 }
489 else
490 {
491 compile-c-c++-pch $(targets) : $(sources) ;
492 }
493 }
494
495 rule compile.idl ( targets + : sources * : properties * )
496 {
497 set-setup-command $(targets) : $(properties) ;
498 }
499
500 # See midl.jam for details.
501 #
502 actions compile.idl
503 {
504 $(.SETUP) $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(.nl)"$(>:W)" $(.nl)-D$(DEFINES) $(.nl)"-I$(INCLUDES:W)" $(.nl)-U$(UNDEFS) $(.nl)$(MIDLFLAGS) $(.nl)/tlb "$(<[1]:W)" $(.nl)/h "$(<[2]:W)" $(.nl)/iid "$(<[3]:W)" $(.nl)/proxy "$(<[4]:W)" $(.nl)/dlldata "$(<[5]:W)")"
505 $(.TOUCH_FILE) "$(<[4]:W)"
506 $(.TOUCH_FILE) "$(<[5]:W)"
507 }
508
509 rule compile.mc ( targets + : sources * : properties * )
510 {
511 set-setup-command $(targets) : $(properties) ;
512 }
513
514 actions compile.mc
515 {
516 $(.SETUP) $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
517 }
518
519
520 rule compile.rc ( targets + : sources * : properties * )
521 {
522 set-setup-command $(targets) : $(properties) ;
523 }
524
525 actions compile.rc
526 {
527 $(.SETUP) $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
528 }
529
530 toolset.uses-features msvc.link : <embed-manifest> <embed-manifest-file> ;
531
532 rule link ( targets + : sources * : properties * )
533 {
534 set-setup-command $(targets) : $(properties) ;
535 if <embed-manifest>on in $(properties)
536 {
537 if [ feature.get-values <embed-manifest-file> : $(properties) ]
538 {
539 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
540 msvc.manifest.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
541 }
542 else
543 {
544 msvc.manifest $(targets) : $(sources) : $(properties) ;
545 }
546 }
547 }
548
549 rule link.dll ( targets + : sources * : properties * )
550 {
551 set-setup-command $(targets) : $(properties) ;
552 DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
553 local import-lib ;
554 if ! <suppress-import-lib>true in $(properties)
555 {
556 import-lib = $(targets[2]) ;
557 IMPORT_LIB on $(targets) = $(import-lib) ;
558 }
559 # On msvc-14.1, the linker might not touch the import library
560 # if the exports do not change. (Apparently this could also
561 # happen for incremental linking, which is why we disable it,
562 # but that no longer seems to be enough).
563 # Therefore, don't update the import library just because
564 # it's out-dated. It will be force updated, when the dll
565 # is updated. Also, make it so that anything that depends
566 # on it depends on the dll as well.
567 NOUPDATE $(import-lib) ;
568 INCLUDES $(import-lib) : $(targets[1]) ;
569 if <embed-manifest>on in $(properties)
570 {
571 if [ feature.get-values <embed-manifest-file> : $(properties) ]
572 {
573 DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
574 msvc.manifest.dll.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
575 }
576 else
577 {
578 msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
579 }
580 }
581 }
582
583 # Incremental linking a DLL causes no end of problems: if the actual exports do
584 # not change, the import .lib file is never updated. Therefore, the .lib is
585 # always out-of-date and gets rebuilt every time. I am not sure that incremental
586 # linking is such a great idea in general, but in this case I am sure we do not
587 # want it.
588
589 # Windows manifest is a new way to specify dependencies on managed DotNet
590 # assemblies and Windows native DLLs. The manifests are embedded as resources
591 # and are useful in any PE target (both DLL and EXE).
592
593 if [ os.name ] in NT
594 {
595 actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
596 {
597 $(.SETUP) $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
598 if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
599 }
600
601 actions manifest
602 {
603 if exist "$(<[1]).manifest" (
604 $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
605 )
606 }
607
608 actions manifest.user bind EMBED_MANIFEST_FILE
609 {
610 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1"
611 }
612
613 actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE
614 {
615 $(.SETUP) $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(IMPORT_LIB:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
616 if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
617 }
618
619 actions manifest.dll
620 {
621 if exist "$(<[1]).manifest" (
622 $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
623 )
624 }
625 actions manifest.dll.user bind EMBED_MANIFEST_FILE
626 {
627 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
628 }
629 }
630 else
631 {
632 actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
633 {
634 $(.SETUP) $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
635 }
636
637 actions manifest
638 {
639 if test -e "$(<[1]).manifest"; then
640 $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
641 fi
642 }
643
644 actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE
645 {
646 $(.SETUP) $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(IMPORT_LIB:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
647 }
648
649 actions manifest.dll
650 {
651 if test -e "$(<[1]).manifest"; then
652 $(.SETUP) $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
653 fi
654 }
655
656 actions manifest.dll.user bind EMBED_MANIFEST_FILE
657 {
658 $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
659 }
660 }
661
662 # This rule sets up the pdb file that will be used when generating static
663 # libraries and the debug-store option is database, so that the compiler puts
664 # all the debug info into a single .pdb file named after the library.
665 #
666 # Poking at source targets this way is probably not clean, but it is the
667 # easiest approach.
668 #
669 rule archive ( targets + : sources * : properties * )
670 {
671 set-setup-command $(targets) : $(properties) ;
672 PDB_NAME on $(>) = $(<[1]:S=.pdb) ;
673 LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
674 }
675
676
677 ################################################################################
678 #
679 # Classes.
680 #
681 ################################################################################
682
683 class msvc-pch-generator : pch-generator
684 {
685 import property-set ;
686
687 rule run-pch ( project name ? : property-set : sources * )
688 {
689 # Searching for the header and source file in the sources.
690 local pch-header ;
691 local pch-source ;
692 for local s in $(sources)
693 {
694 if [ type.is-derived [ $(s).type ] H ]
695 {
696 pch-header = $(s) ;
697 }
698 else if
699 [ type.is-derived [ $(s).type ] CPP ] ||
700 [ type.is-derived [ $(s).type ] C ]
701 {
702 pch-source = $(s) ;
703 }
704 }
705
706 if ! $(pch-header)
707 {
708 import errors : user-error : errors.user-error ;
709 errors.user-error "can not build pch without pch-header" ;
710 }
711
712 # If we do not have the PCH source - that is fine. We will just create a
713 # temporary .cpp file in the action.
714
715 local generated = [ generator.run $(project) $(name)
716 : [ property-set.create
717 # Passing of <pch-source> is a dirty trick, needed because
718 # non-composing generators with multiple inputs are subtly
719 # broken. For more detailed information see:
720 # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
721 <pch-source>$(pch-source)
722 [ $(property-set).raw ] ]
723 : $(pch-header) ] ;
724
725 local pch-file ;
726 for local g in $(generated[2-])
727 {
728 if [ type.is-derived [ $(g).type ] PCH ]
729 {
730 pch-file = $(g) ;
731 }
732 }
733
734 return [ $(generated[1]).add-raw <pch-header>$(pch-header)
735 <pch-file>$(pch-file) ] $(generated[2-]) ;
736 }
737 }
738
739
740 ################################################################################
741 #
742 # Local rules.
743 #
744 ################################################################################
745
746 # Detects versions listed as '.known-versions' by checking registry information,
747 # environment variables & default paths. Supports both native Windows and
748 # Cygwin.
749 #
750 local rule auto-detect-toolset-versions ( )
751 {
752 if [ os.name ] in NT CYGWIN
753 {
754 # Get installation paths from the registry.
755 for local i in $(.known-versions)
756 {
757 if $(.version-$(i)-reg)
758 {
759 local vc-path ;
760 for local x in "" "Wow6432Node\\"
761 {
762 vc-path += [ W32_GETREG
763 "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
764 : "ProductDir" ] ;
765 }
766
767 if $(vc-path)
768 {
769 vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
770 register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
771 }
772 }
773 }
774 }
775
776 # Check environment and default installation paths.
777 for local i in $(.known-versions)
778 {
779 if ! $(i) in [ $(.versions).all ]
780 {
781 register-configuration $(i) : [ default-path $(i) ] ;
782 }
783 }
784 }
785
786 actions write-setup-script
787 {
788 @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)"
789 }
790
791 if [ os.name ] = NT
792 {
793 local rule call-batch-script ( command )
794 {
795 return "call $(command) >nul$(.nl)" ;
796 }
797 }
798 else
799 {
800 # On cygwin, we need to run both the batch script
801 # and the following command in the same instance
802 # of cmd.exe.
803 local rule call-batch-script ( command )
804 {
805 return "cmd.exe /S /C call $(command) \">nul\" \"&&\" " ;
806 }
807 }
808
809 # Local helper rule to create the vcvars setup command for given architecture
810 # and options.
811 #
812 local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup )
813 {
814 local setup-options ;
815 local setup = [ feature.get-values <setup-$(cpu)> : $(options) ] ;
816
817 if ! $(setup)-is-defined
818 {
819 if $(global-setup)-is-defined
820 {
821 setup = $(global-setup) ;
822
823 # If needed we can easily add using configuration flags
824 # here for overriding which options get passed to the
825 # global setup command for which target platform:
826 # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ;
827 setup-options ?= $(default-global-setup-options) ;
828 }
829 else
830 {
831 if [ MATCH "(14.1)" : $(version) ]
832 {
833 if $(.debug-configuration)
834 {
835 ECHO 'notice\: "[generate-setup-cmd]" $(version) is 14.1' ;
836 }
837 parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
838 }
839 setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ;
840 setup ?= [ path.join $(parent) "vcvarsall.bat" ] ;
841 }
842 }
843
844 return $(setup) "$(setup-options:J= )" ;
845 }
846
847 # Worker for set-setup-command. Usable in a virtual-target.action.
848 rule adjust-setup-command ( new-setup : setup : properties * )
849 {
850 local internal = $(new-setup:S=.read) ;
851 NOTFILE $(internal) ;
852 local setup-options = [ property.select <msvc.setup-options> : $(properties) ] ;
853 setup-options = $(setup-options:G=:E=) ;
854 DEPENDS $(internal) : $(setup) ;
855 DEPENDS $(new-setup) : $(internal) ;
856 REBUILDS $(new-setup) : $(internal) ;
857 msvc.read-setup $(internal) : $(setup) ;
858 msvc.write-setup-script $(new-setup) : $(setup) ;
859 __ACTION_RULE__ on $(internal) = msvc.rewrite-setup $(setup) $(setup-options) $(new-setup) ;
860 }
861
862 # This doesn't actually do anything. It's merely
863 # used as a trigger for __ACTION_RULE__.
864 actions quietly read-setup { }
865
866 # Calculates the changes to the environment make by setup-script
867 # Should be used as a callback for __ACTION_RULE__
868 local rule rewrite-setup ( setup-script setup-options new-setup : target : * )
869 {
870 local setup-path = [ on $(setup-script) return $(LOCATE) $(SEARCH) ] ;
871 setup-path = $(setup-path[1]) ;
872 local command = "\"$(setup-script:G=:R=$(setup-path))\" $(setup-options)" ;
873 local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ;
874 local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(command) >nul && set" ] : "\n" ] ;
875 local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ;
876 if $(diff-vars)
877 {
878 FILE_CONTENTS on $(new-setup) = "REM $(command)" "SET "$(diff-vars) ;
879 }
880 }
881
882 IMPORT msvc : rewrite-setup : : msvc.rewrite-setup ;
883
884 # Helper rule to generate a faster alternative to MSVC setup scripts.
885 # We used to call MSVC setup scripts directly in every action, however in
886 # newer MSVC versions (10.0+) they make long-lasting registry queries
887 # which have a significant impact on build time.
888 local rule set-setup-command ( targets * : properties * )
889 {
890 if ! [ on $(targets) return $(.SETUP) ]
891 {
892 local setup-script = [ on $(targets) return $(.SETUP-SCRIPT) ] ;
893 local setup-options = [ on $(targets) return $(.SETUP-OPTIONS) ] ;
894 local key = .setup-command-$(setup-script:E=)-$(setup-options:E=) ;
895 if ! $($(key))
896 {
897 properties = [ feature.expand $(properties) ] ;
898 properties = [ property.select <toolset> <toolset-msvc:version> <architecture> <address-model> <windows-api> <relevant> : $(properties) ] ;
899 local ps = [ property-set.create $(properties) <msvc.setup-options>$(setup-options) ] ;
900 local original = [ virtual-target.from-file $(setup-script) : [ path.pwd ] : $(.project) ] ;
901 local action = [ new non-scanning-action $(original) : msvc.adjust-setup-command : $(ps) ] ;
902 local new-setup = [ virtual-target.register [ new file-target msvc-setup.bat exact : : $(.project) : $(action) ] ] ;
903 local command = [ $(new-setup).actualize ] ;
904 local path = [ on $(command) return $(LOCATE) ] ;
905 local block-update = $(command:S=.nup) ;
906 NOUPDATE $(block-update) ;
907 NOTFILE $(block-update) ;
908 DEPENDS $(block-update) : $(command) ;
909 if [ on $(targets) return $(.REWRITE-SETUP) ]
910 {
911 ALWAYS $(command) ;
912 }
913 $(key) = [ call-batch-script "\"$(command:WG=:R=$(path))\" $(setup-options:E=)" ] $(block-update) ;
914 }
915 DEPENDS $(targets) : $($(key)[2]) ;
916 .SETUP on $(targets) = $($(key)[1]) ;
917 }
918 }
919
920 # Worker rule for toolset version configuration. Takes an explicit version id or
921 # nothing in case it should configure the default toolset version (the first
922 # registered one or a new 'default' one in case no toolset versions have been
923 # registered yet).
924 #
925 local rule configure-really ( version ? : options * )
926 {
927 local v = $(version) ;
928
929 # Decide what the 'default' version is.
930 if ! $(v)
931 {
932 # Take the best registered (i.e. auto-detected) version.
933 version = [ $(.versions).all ] ;
934 for local known in $(.known-versions)
935 {
936 if $(known) in $(version)
937 {
938 version = $(known) ;
939 break ;
940 }
941 }
942 version = $(version[1]) ;
943 v = $(version) ;
944
945 # Note: 'version' can still be empty at this point if no versions have
946 # been auto-detected.
947 version ?= "default" ;
948 }
949
950 # Version alias -> real version number.
951 version = [ resolve-possible-msvc-version-alias $(version) ] ;
952
953 # Check whether the selected configuration is already in use.
954 if $(version) in [ $(.versions).used ]
955 {
956 # Allow multiple 'toolset.using' calls for the same configuration if the
957 # identical sets of options are used.
958 if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
959 {
960 import errors ;
961 errors.error "MSVC toolset configuration: Toolset version"
962 "'$(version)' already configured." ;
963 }
964 }
965 else
966 {
967 # Register a new configuration.
968 $(.versions).register $(version) ;
969
970 # Add user-supplied to auto-detected options.
971 options = [ $(.versions).get $(version) : options ] $(options) ;
972
973 # Mark the configuration as 'used'.
974 $(.versions).use $(version) ;
975
976 # Generate conditions and save them.
977 local conditions = [ common.check-init-parameters msvc : version $(v) ]
978 ;
979
980 $(.versions).set $(version) : conditions : $(conditions) ;
981
982 local command = [ feature.get-values <command> : $(options) ] ;
983
984 # For 14.1 we need the exact version as MS is planning rolling updates
985 # that will cause our `setup-cmd` to become invalid
986 exact-version = [ MATCH "(14\.10\.[0-9\.]+)" : $(command) ] ;
987
988 # If version is specified, we try to search first in default paths, and
989 # only then in PATH.
990 command = [ common.get-invocation-command msvc : cl.exe : $(command) :
991 [ default-paths $(version) ] : $(version) ] ;
992
993 if ( ! $(version) || $(version) = "default" ) && ! $(command:D)
994 {
995 ECHO ;
996 ECHO warning\:
997 "Did not find command for MSVC toolset."
998 "If you have Visual Studio 2017 installed you will need to"
999 "specify the full path to the command,"
1000 "set VS150COMNTOOLS for your installation,"
1001 "or"
1002 "build from the 'Visual Studio Command Prompt for VS 2017'."
1003 ;
1004 ECHO ;
1005 }
1006
1007 common.handle-options msvc : $(conditions) : $(command) : $(options) ;
1008
1009 if ! $(version)
1010 {
1011 # Even if version is not explicitly specified, try to detect the
1012 # version from the path.
1013 # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
1014 # 9.0express as 9.0 here.
1015 if [ MATCH "(MSVC\\14.1)" : $(command) ]
1016 {
1017 version = 14.1 ;
1018 }
1019 else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ]
1020 {
1021 version = 14.0 ;
1022 }
1023 else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ]
1024 {
1025 version = 12.0 ;
1026 }
1027 else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
1028 {
1029 version = 11.0 ;
1030 }
1031 else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
1032 {
1033 version = 10.0 ;
1034 }
1035 else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
1036 {
1037 version = 9.0 ;
1038 }
1039 else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
1040 {
1041 version = 8.0 ;
1042 }
1043 else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
1044 {
1045 version = 7.1 ;
1046 }
1047 else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
1048 $(command) ]
1049 {
1050 version = 7.1toolkit ;
1051 }
1052 else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
1053 {
1054 version = 7.0 ;
1055 }
1056 else
1057 {
1058 version = 6.0 ;
1059 }
1060 }
1061
1062 # Generate and register setup command.
1063
1064 local below-8.0 = [ MATCH "^([67]\\.)" : $(version) ] ;
1065 local below-11.0 = [ MATCH "^([6789]\\.|10\\.)" : $(version) ] ;
1066
1067 local cpu = i386 amd64 ia64 arm ;
1068 if $(below-8.0)
1069 {
1070 cpu = i386 ;
1071 }
1072 else if $(below-11.0)
1073 {
1074 cpu = i386 amd64 ia64 ;
1075 }
1076
1077 local setup-amd64 ;
1078 local setup-i386 ;
1079 local setup-ia64 ;
1080 local setup-arm ;
1081 local setup-phone-i386 ;
1082 local setup-phone-arm ;
1083
1084 if $(command)
1085 {
1086 # TODO: Note that if we specify a non-existant toolset version then
1087 # this rule may find and use a corresponding compiler executable
1088 # belonging to an incorrect toolset version. For example, if you
1089 # have only MSVC 7.1 installed, have its executable on the path and
1090 # specify you want Boost Build to use MSVC 9.0, then you want Boost
1091 # Build to report an error but this may cause it to silently use the
1092 # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0
1093 # toolset version.
1094 command = [ common.get-absolute-tool-path $(command[-1]) ] ;
1095 }
1096
1097 if $(command)
1098 {
1099 local parent = [ path.make $(command) ] ;
1100 parent = [ path.parent $(parent) ] ;
1101 parent = [ path.native $(parent) ] ;
1102
1103 # Setup will be used if the command name has been specified. If
1104 # setup is not specified explicitly then a default setup script will
1105 # be used instead. Setup scripts may be global or architecture/
1106 # /platform/cpu specific. Setup options are used only in case of
1107 # global setup scripts.
1108
1109 # Default setup scripts provided with different VC distributions:
1110 #
1111 # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
1112 # builds. It was located in the bin folder for the regular version
1113 # and in the root folder for the free VC 7.1 tools.
1114 #
1115 # Later 8.0 & 9.0 versions introduce separate platform specific
1116 # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
1117 # located in or under the bin folder. Most also include a global
1118 # vcvarsall.bat helper script located in the root folder which runs
1119 # one of the aforementioned vcvars*.bat scripts based on the options
1120 # passed to it. So far only the version coming with some PlatformSDK
1121 # distributions does not include this top level script but to
1122 # support those we need to fall back to using the worker scripts
1123 # directly in case the top level script can not be found.
1124
1125 local global-setup = [ feature.get-values <setup> : $(options) ] ;
1126 global-setup = $(global-setup[1]) ;
1127 local global-setup-phone = $(global-setup) ;
1128 if ! $(below-8.0)
1129 {
1130 global-setup ?= [ locate-default-setup $(command) : $(parent) :
1131 vcvarsall.bat ] ;
1132 }
1133
1134 local default-setup-amd64 = vcvarsx86_amd64.bat ;
1135 local default-setup-i386 = vcvars32.bat ;
1136 local default-setup-ia64 = vcvarsx86_ia64.bat ;
1137 local default-setup-arm = vcvarsx86_arm.bat ;
1138 local default-setup-phone-i386 = vcvarsphonex86.bat ;
1139 local default-setup-phone-arm = vcvarsphonex86_arm.bat ;
1140
1141 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
1142 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
1143 # mention an x86_IPF option, that seems to be a documentation bug
1144 # and x86_ia64 is the correct option.
1145 local default-global-setup-options-amd64 = x86_amd64 ;
1146 local default-global-setup-options-i386 = x86 ;
1147 local default-global-setup-options-ia64 = x86_ia64 ;
1148 local default-global-setup-options-arm = x86_arm ;
1149
1150 # When using 64-bit Windows, and targeting 64-bit, it is possible to
1151 # use a native 64-bit compiler, selected by the "amd64" & "ia64"
1152 # parameters to vcvarsall.bat. There are two variables we can use --
1153 # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
1154 # 'x86' when running 32-bit Windows, no matter which processor is
1155 # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
1156 # Windows.
1157 #
1158 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
1159 {
1160 default-global-setup-options-amd64 = amd64 ;
1161 }
1162 # When Boost.Build itself is running as a 32-bit process on 64-bit
1163 # Windows, the above test will fail (since WOW64 simulates a 32-bit
1164 # environment, including environment values). So check the WOW64
1165 # variable PROCESSOR_ARCHITEW6432 as well.
1166 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITEW6432 ] ]
1167 {
1168 default-global-setup-options-amd64 = amd64 ;
1169 }
1170 # TODO: The same 'native compiler usage' should be implemented for
1171 # the Itanium platform by using the "ia64" parameter. For this
1172 # though we need someone with access to this platform who can find
1173 # out how to correctly detect this case.
1174 else if $(somehow-detect-the-itanium-platform)
1175 {
1176 default-global-setup-options-ia64 = ia64 ;
1177 }
1178
1179 for local c in $(cpu)
1180 {
1181 exact-version ?= $(version) ;
1182 setup-$(c) = [ generate-setup-cmd $(exact-version) : $(command) : $(parent) : $(options) : $(c) : $(global-setup) : $(default-global-setup-options-$(c)) : $(default-setup-$(c)) ] ;
1183 }
1184
1185 # Windows phone has different setup scripts, located in a different directory hierarchy.
1186 # The 11.0 toolset can target Windows Phone 8.0 and the 12.0 toolset can target Windows Phone 8.1,
1187 # each of which have a different directory for their vcvars setup scripts.
1188 local phone-parent = [ path.native [ path.join $(parent) WPSDK ] ] ;
1189 local phone-directory = $(phone-parent) ;
1190 if [ MATCH "(11.0)" : $(version) ]
1191 {
1192 phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ;
1193 }
1194 else if [ MATCH "(12.0)" : $(version) ]
1195 {
1196 phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ;
1197 }
1198 global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ;
1199
1200 # If can't locate default phone setup script then this VS version doesn't support Windows Phone.
1201 if $(global-setup-phone)-is-defined
1202 {
1203 # i386 CPU is for the Windows Phone emulator in Visual Studio.
1204 local phone-cpu = i386 arm ;
1205 for local c in $(phone-cpu)
1206 {
1207 setup-phone-$(c) = [ generate-setup-cmd $(version) : $(phone-directory) : $(phone-parent) : $(options) : $(c) : $(global-setup-phone) : $(default-global-setup-options-$(c)) : $(default-setup-phone-$(c)) ] ;
1208 }
1209 }
1210 }
1211
1212 # Get tool names (if any) and finish setup.
1213
1214 compiler = [ feature.get-values <compiler> : $(options) ] ;
1215 compiler ?= cl ;
1216
1217 linker = [ feature.get-values <linker> : $(options) ] ;
1218 linker ?= link ;
1219
1220 resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
1221 resource-compiler ?= rc ;
1222
1223 # Turn on some options for i386 assembler
1224 # -coff generate COFF format object file (compatible with cl.exe output)
1225 local default-assembler-amd64 = ml64 ;
1226 local default-assembler-i386 = "ml -coff" ;
1227 local default-assembler-ia64 = ias ;
1228 local default-assembler-ia64 = armasm ;
1229
1230 assembler = [ feature.get-values <assembler> : $(options) ] ;
1231
1232 idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
1233 idl-compiler ?= midl ;
1234
1235 mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
1236 mc-compiler ?= mc ;
1237
1238 manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
1239 manifest-tool ?= mt ;
1240
1241 local cc-filter = [ feature.get-values <compiler-filter> : $(options) ]
1242 ;
1243
1244 for local c in $(cpu)
1245 {
1246 # Setup script is not required in some configurations.
1247 setup-$(c) ?= "" ;
1248
1249 local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
1250
1251 if $(.debug-configuration)
1252 {
1253 for local cpu-condition in $(cpu-conditions)
1254 {
1255 ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
1256 }
1257 }
1258
1259 local cpu-assembler = $(assembler) ;
1260 cpu-assembler ?= $(default-assembler-$(c)) ;
1261
1262 for local api in desktop store phone
1263 {
1264 local setup-script = $(setup-$(c)) ;
1265 if $(api) = phone
1266 {
1267 setup-script = $(setup-phone-$(c)) ;
1268 }
1269
1270 if <rewrite-setup-scripts>always in $(options)
1271 {
1272 toolset.flags msvc .REWRITE-SETUP <windows-api>$(api)/$(cpu-conditions) : true ;
1273 }
1274
1275 if ! $(setup-script)
1276 {
1277 # Should we try to set up some error handling or fallbacks here?
1278 }
1279 else if <rewrite-setup-scripts>off in $(options) || [ os.name ] != NT
1280 {
1281 toolset.flags msvc .SETUP <windows-api>$(api)/$(cpu-conditions) : [ call-batch-script "\"$(setup-script[1]:W)\" $(setup-script[2-]:E=)" ] ;
1282 }
1283 else
1284 {
1285 toolset.flags msvc .SETUP-SCRIPT <windows-api>$(api)/$(cpu-conditions) : $(setup-script[1]) ;
1286 toolset.flags msvc .SETUP-OPTIONS <windows-api>$(api)/$(cpu-conditions) : $(setup-script[2-]) ;
1287 }
1288
1289 toolset.flags msvc.compile .RC <windows-api>$(api)/$(cpu-conditions) : $(resource-compiler) ;
1290 toolset.flags msvc.compile .IDL <windows-api>$(api)/$(cpu-conditions) : $(idl-compiler) ;
1291 toolset.flags msvc.compile .MC <windows-api>$(api)/$(cpu-conditions) : $(mc-compiler) ;
1292 toolset.flags msvc.link .MT <windows-api>$(api)/$(cpu-conditions) : $(manifest-tool) -nologo ;
1293
1294 if $(api) = desktop
1295 {
1296 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 -nologo ;
1297 }
1298 else
1299 {
1300 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 /ZW /EHsc -nologo ;
1301 }
1302 toolset.flags msvc.compile .ASM <windows-api>$(api)/$(cpu-conditions) : $(cpu-assembler) -nologo ;
1303 toolset.flags msvc.link .LD <windows-api>$(api)/$(cpu-conditions) : $(linker) /NOLOGO "/INCREMENTAL:NO" ;
1304 toolset.flags msvc.archive .LD <windows-api>$(api)/$(cpu-conditions) : $(linker) /lib /NOLOGO ;
1305 }
1306
1307 if $(cc-filter)
1308 {
1309 toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
1310 }
1311 }
1312
1313 # Starting with Visual Studio 2013 the CRT is split into a desktop and app dll.
1314 # If targeting WinRT and 12.0 set lib path to link against app CRT.
1315 if [ MATCH "(12)" : $(version) ]
1316 {
1317 local storeLibPath = [ path.join $(parent) "lib/store" ] ;
1318 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-i386) : [ path.native $(storeLibPath) ] ;
1319 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-amd64) : [ path.native [ path.join $(storeLibPath) "amd64" ] ] ;
1320 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-arm) : [ path.native [ path.join $(storeLibPath) "arm" ] ] ;
1321 }
1322
1323 # Set version-specific flags.
1324 configure-version-specific msvc : $(version) : $(conditions) ;
1325 }
1326 }
1327
1328
1329 # Returns the default installation path for the given version.
1330 #
1331 local rule default-path ( version )
1332 {
1333 # Use auto-detected path if possible.
1334 local result = [ feature.get-values <command> : [ $(.versions).get $(version)
1335 : options ] ] ;
1336
1337 if $(result)
1338 {
1339 result = $(result:D) ;
1340 }
1341 else
1342 {
1343 # try to use vswhere
1344 local pseudo_env_VS150 ;
1345 if $(version) = 14.1 || $(version) = "default"
1346 {
1347 local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
1348 local prop = "-property installationPath" ;
1349 local limit = "-version \"[15.0,16.0)\"" ;
1350 local root = [ os.environ "ProgramFiles(x86)" ] ;
1351 if ( ! $(root) )
1352 {
1353 root = [ os.environ "ProgramFiles" ] ;
1354 }
1355 local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ;
1356 if ( [ path.exists $(vswhere) ] )
1357 {
1358 local vmwhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ;
1359 local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vmwhere_cmd) ] : "\n" ] ;
1360 pseudo_env_VS150 = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
1361 }
1362 }
1363
1364 # Check environment or previous path_VS150
1365 for local env in $(.version-$(version)-env)
1366 {
1367 local env-path ;
1368 if ( $(pseudo_env_VS150) && [ path.exists $(pseudo_env_VS150) ] )
1369 {
1370 env-path = $(pseudo_env_VS150) ;
1371 }
1372 else
1373 {
1374 env-path = [ os.environ $(env) ] ;
1375 }
1376 if $(env-path) && $(.version-$(version)-path)
1377 {
1378 for local bin-path in $(.version-$(version)-path)
1379 {
1380 result = [ path.glob [ path.make $(env-path) ] : $(bin-path) ] ;
1381 if $(result)
1382 {
1383 result = [ path.native $(result[1]) ] ;
1384 break ;
1385 }
1386 }
1387 }
1388 if $(result)
1389 {
1390 break ;
1391 }
1392 }
1393 }
1394
1395 return $(result) ;
1396 }
1397
1398
1399 # Returns either the default installation path (if 'version' is not empty) or
1400 # list of all known default paths (if no version is given)
1401 #
1402 local rule default-paths ( version ? )
1403 {
1404 local possible-paths ;
1405
1406 if $(version)
1407 {
1408 possible-paths += [ default-path $(version) ] ;
1409 }
1410 else
1411 {
1412 for local i in $(.known-versions)
1413 {
1414 possible-paths += [ default-path $(i) ] ;
1415 }
1416 }
1417
1418 return $(possible-paths) ;
1419 }
1420
1421
1422 rule get-rspline ( target : lang-opt )
1423 {
1424 CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
1425 $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES)
1426 $(.nl)\"-I$(INCLUDES:W)\" ] ;
1427 }
1428
1429 class msvc-linking-generator : linking-generator
1430 {
1431 # Calls the base version. If necessary, also create a target for the
1432 # manifest file.specifying source's name as the name of the created
1433 # target. As result, the PCH will be named whatever.hpp.gch, and not
1434 # whatever.gch.
1435 rule generated-targets ( sources + : property-set : project name ? )
1436 {
1437 local result = [ linking-generator.generated-targets $(sources)
1438 : $(property-set) : $(project) $(name) ] ;
1439
1440 if $(result)
1441 {
1442 local name-main = [ $(result[1]).name ] ;
1443 local action = [ $(result[1]).action ] ;
1444
1445 if [ $(property-set).get <debug-symbols> ] = "on"
1446 {
1447 # We force the exact name on PDB. The reason is tagging -- the
1448 # tag rule may reasonably special case some target types, like
1449 # SHARED_LIB. The tag rule will not catch PDBs, and it cannot
1450 # even easily figure out if a PDB is paired with a SHARED_LIB,
1451 # EXE or something else. Because PDBs always get the same name
1452 # as the main target, with .pdb as extension, just force it.
1453 local target = [ class.new file-target $(name-main:S=.pdb) exact
1454 : PDB : $(project) : $(action) ] ;
1455 local registered-target = [ virtual-target.register $(target) ]
1456 ;
1457 if $(target) != $(registered-target)
1458 {
1459 $(action).replace-targets $(target) : $(registered-target) ;
1460 }
1461 result += $(registered-target) ;
1462 }
1463
1464 if [ $(property-set).get <embed-manifest> ] = "off"
1465 {
1466 # Manifest is an evil target. It has .manifest appened to the
1467 # name of the main target, including extension, e.g.
1468 # a.exe.manifest. We use the 'exact' name to achieve this
1469 # effect.
1470 local target = [ class.new file-target $(name-main).manifest
1471 exact : MANIFEST : $(project) : $(action) ] ;
1472 local registered-target = [ virtual-target.register $(target) ]
1473 ;
1474 if $(target) != $(registered-target)
1475 {
1476 $(action).replace-targets $(target) : $(registered-target) ;
1477 }
1478 result += $(registered-target) ;
1479 }
1480 }
1481 return $(result) ;
1482 }
1483 }
1484
1485
1486 # Unsafe worker rule for the register-toolset() rule. Must not be called
1487 # multiple times.
1488 #
1489 local rule register-toolset-really ( )
1490 {
1491 feature.extend toolset : msvc ;
1492
1493 # Intel and msvc supposedly have link-compatible objects.
1494 feature.subfeature toolset msvc : vendor : intel : propagated optional ;
1495
1496 # Inherit MIDL flags.
1497 toolset.inherit-flags msvc : midl ;
1498
1499 # Inherit MC flags.
1500 toolset.inherit-flags msvc : mc ;
1501
1502 # Dynamic runtime comes only in MT flavour.
1503 toolset.add-requirements
1504 <toolset>msvc,<runtime-link>shared:<threading>multi ;
1505
1506 # Declare msvc toolset specific features.
1507 {
1508 feature.feature debug-store : object database : propagated ;
1509 feature.feature pch-source : : dependency free ;
1510 }
1511
1512 # Declare generators.
1513 {
1514 # TODO: Is it possible to combine these? Make the generators
1515 # non-composing so that they do not convert each source into a separate
1516 # .rsp file.
1517 generators.register [ new msvc-linking-generator msvc.link :
1518 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ;
1519 generators.register [ new msvc-linking-generator msvc.link.dll :
1520 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB :
1521 <toolset>msvc <suppress-import-lib>false ] ;
1522 generators.register [ new msvc-linking-generator msvc.link.dll :
1523 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB :
1524 <toolset>msvc <suppress-import-lib>true ] ;
1525
1526 generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
1527 generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
1528 generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
1529 generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
1530 generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
1531
1532 # Using 'register-c-compiler' adds the build directory to INCLUDES.
1533 generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
1534 generators.override msvc.compile.rc : rc.compile.resource ;
1535 generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
1536
1537 generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
1538 generators.override msvc.compile.idl : midl.compile.idl ;
1539
1540 generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
1541 generators.override msvc.compile.mc : mc.compile ;
1542
1543 # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
1544 # the latter have their HPP type derived from H. The type of compilation
1545 # is determined entirely by the destination type.
1546 generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
1547 generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
1548
1549 generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
1550 generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
1551 }
1552
1553 toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
1554 toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
1555 toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
1556
1557 #
1558 # Declare flags for compilation.
1559 #
1560
1561 toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ;
1562 toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ;
1563
1564 toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
1565 toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
1566
1567 toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
1568 toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
1569 toolset.flags msvc.compile CFLAGS <optimization>off : /Od ;
1570 toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
1571 toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
1572 toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
1573
1574 toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ;
1575 toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ;
1576 toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ;
1577 toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
1578
1579 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
1580 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
1581 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
1582 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
1583
1584 toolset.flags msvc.compile C++FLAGS <cxxstd>14 : "/std:c++14" ;
1585 toolset.flags msvc.compile C++FLAGS <cxxstd>17 : "/std:c++17" ;
1586 toolset.flags msvc.compile C++FLAGS <cxxstd>latest : "/std:c++latest" ;
1587
1588 # By default 8.0 enables rtti support while prior versions disabled it. We
1589 # simply enable or disable it explicitly so we do not have to depend on this
1590 # default behaviour.
1591 toolset.flags msvc.compile CFLAGS <rtti>on : /GR ;
1592 toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ;
1593 toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
1594 toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
1595
1596 toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
1597 toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
1598
1599 toolset.flags msvc.compile OPTIONS <cflags> : ;
1600 toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ;
1601
1602 toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
1603
1604 toolset.flags msvc.compile DEFINES <define> ;
1605 toolset.flags msvc.compile UNDEFS <undef> ;
1606 toolset.flags msvc.compile INCLUDES <include> ;
1607
1608 # Declare flags for the assembler.
1609 toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
1610
1611 toolset.flags msvc.compile.asm ASMFLAGS <debug-symbols>on : "/Zi /Zd" ;
1612
1613 toolset.flags msvc.compile.asm ASMFLAGS <warnings>on : /W3 ;
1614 toolset.flags msvc.compile.asm ASMFLAGS <warnings>off : /W0 ;
1615 toolset.flags msvc.compile.asm ASMFLAGS <warnings>all : /W4 ;
1616 toolset.flags msvc.compile.asm ASMFLAGS <warnings-as-errors>on : /WX ;
1617
1618 toolset.flags msvc.compile.asm DEFINES <define> ;
1619
1620 # Declare flags for linking.
1621 {
1622 toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : "/PDB:" ; # not used yet
1623 toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
1624 toolset.flags msvc.link DEF_FILE <def-file> ;
1625
1626 # The linker disables the default optimizations when using /DEBUG so we
1627 # have to enable them manually for release builds with debug symbols.
1628 toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : "/OPT:REF,ICF" ;
1629
1630 toolset.flags msvc LINKFLAGS <user-interface>console : "/subsystem:console" ;
1631 toolset.flags msvc LINKFLAGS <user-interface>gui : "/subsystem:windows" ;
1632 toolset.flags msvc LINKFLAGS <user-interface>wince : "/subsystem:windowsce" ;
1633 toolset.flags msvc LINKFLAGS <user-interface>native : "/subsystem:native" ;
1634 toolset.flags msvc LINKFLAGS <user-interface>auto : "/subsystem:posix" ;
1635
1636 toolset.flags msvc.link OPTIONS <linkflags> ;
1637 toolset.flags msvc.link LINKPATH <library-path> ;
1638
1639 toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
1640 toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
1641 toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
1642 toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
1643
1644 toolset.flags msvc.link.dll LINKFLAGS <suppress-import-lib>true : /NOENTRY ;
1645 }
1646
1647 toolset.flags msvc.archive AROPTIONS <archiveflags> ;
1648
1649 # Create a project to allow building the setup scripts
1650 project.initialize $(__name__) ;
1651 .project = [ project.current ] ;
1652 project msvc ;
1653
1654 feature.feature msvc.setup-options : : free ;
1655 }
1656
1657
1658 # Locates the requested setup script under the given folder and returns its full
1659 # path or nothing in case the script can not be found. In case multiple scripts
1660 # are found only the first one is returned.
1661 #
1662 # TODO: There used to exist a code comment for the msvc.init rule stating that
1663 # we do not correctly detect the location of the vcvars32.bat setup script for
1664 # the free VC7.1 tools in case user explicitly provides a path. This should be
1665 # tested or simply remove this whole comment in case this toolset version is no
1666 # longer important.
1667 #
1668 local rule locate-default-setup ( command : parent : setup-name )
1669 {
1670 local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
1671 if $(result[1])
1672 {
1673 return $(result[1]) ;
1674 }
1675 }
1676
1677
1678 # Validates given path, registers found configuration and prints debug
1679 # information about it.
1680 #
1681 local rule register-configuration ( version : path ? )
1682 {
1683 if $(path)
1684 {
1685 local command = [ GLOB $(path) : cl.exe ] ;
1686
1687 if $(command)
1688 {
1689 if $(.debug-configuration)
1690 {
1691 ECHO notice\: "[msvc-cfg]" msvc-$(version) detected, command\:
1692 '$(command)' ;
1693 }
1694
1695 $(.versions).register $(version) ;
1696 $(.versions).set $(version) : options : <command>$(command) ;
1697 }
1698 }
1699 }
1700
1701
1702 ################################################################################
1703 #
1704 # Startup code executed when loading this module.
1705 #
1706 ################################################################################
1707
1708 if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
1709 {
1710 .debug-configuration = true ;
1711 }
1712
1713 # Miscellaneous constants.
1714 .RM = [ common.rm-command ] ;
1715 .nl = "
1716 " ;
1717 .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
1718 .escaped-double-quote = "\"" ;
1719 .TOUCH_FILE = [ common.file-touch-command ] ;
1720
1721 # List of all registered configurations.
1722 .versions = [ new configurations ] ;
1723
1724 # Supported CPU architectures.
1725 .cpu-arch-i386 =
1726 <architecture>/<address-model>
1727 <architecture>/<address-model>32
1728 <architecture>x86/<address-model>
1729 <architecture>x86/<address-model>32 ;
1730
1731 .cpu-arch-amd64 =
1732 <architecture>/<address-model>64
1733 <architecture>x86/<address-model>64 ;
1734
1735 .cpu-arch-ia64 =
1736 <architecture>ia64/<address-model>
1737 <architecture>ia64/<address-model>64 ;
1738
1739 .cpu-arch-arm =
1740 <architecture>arm/<address-model>
1741 <architecture>arm/<address-model>32 ;
1742
1743
1744 # Supported CPU types (only Itanium optimization options are supported from
1745 # VC++ 2005 on). See
1746 # http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
1747 # detailed information.
1748 .cpu-type-g5 = i586 pentium pentium-mmx ;
1749 .cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
1750 k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ;
1751 .cpu-type-em64t = prescott nocona core2 corei7 corei7-avx core-avx-i
1752 conroe conroe-xe conroe-l allendale merom
1753 merom-xe kentsfield kentsfield-xe penryn wolfdale
1754 yorksfield nehalem sandy-bridge ivy-bridge haswell
1755 broadwell skylake skylake-avx512 cannonlake ;
1756 .cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3
1757 athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3
1758 bdver4 btver1 btver2 znver1 ;
1759 .cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
1760 athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
1761 .cpu-type-itanium = itanium itanium1 merced ;
1762 .cpu-type-itanium2 = itanium2 mckinley ;
1763 .cpu-type-arm = armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
1764 armv7 armv7s ;
1765
1766 # Known toolset versions, in order of preference.
1767 .known-versions = 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
1768 7.1toolkit 7.0 6.0 ;
1769
1770 # Version aliases.
1771 .version-alias-6 = 6.0 ;
1772 .version-alias-6.5 = 6.0 ;
1773 .version-alias-7 = 7.0 ;
1774 .version-alias-8 = 8.0 ;
1775 .version-alias-9 = 9.0 ;
1776 .version-alias-10 = 10.0 ;
1777 .version-alias-11 = 11.0 ;
1778 .version-alias-12 = 12.0 ;
1779 .version-alias-14 = 14.0 ;
1780 .version-alias-14.1 = 14.1 ;
1781
1782 # Names of registry keys containing the Visual C++ installation path (relative
1783 # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
1784 .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
1785 .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
1786 .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
1787 .version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
1788 .version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
1789 .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
1790 .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
1791 .version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ;
1792 .version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ;
1793 .version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ;
1794 .version-12.0-reg = "VisualStudio\\12.0\\Setup\\VC" ;
1795 .version-14.0-reg = "VisualStudio\\14.0\\Setup\\VC" ;
1796
1797 # Visual C++ Toolkit 2003 does not store its installation path in the registry.
1798 # The environment variable 'VCToolkitInstallDir' and the default installation
1799 # path will be checked instead.
1800 .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003/bin" ;
1801 .version-7.1toolkit-env = VCToolkitInstallDir ;
1802 # Visual Studio 2017 doesn't use a registry at all. And the suggested methods
1803 # of discovery involve having a compiled program. So as a fallback we search
1804 # paths for VS2017 (aka msvc >= 14.1).
1805 .version-14.1-path =
1806 "../../VC/Tools/MSVC/*/bin/Host*/*"
1807 "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*"
1808 ;
1809 .version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
1810
1811 # Auto-detect all the available msvc installations on the system.
1812 auto-detect-toolset-versions ;
1813
1814
1815 # And finally trigger the actual Boost Build toolset registration.
1816 register-toolset ;