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