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