]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/tools/msvc.jam
add subtree-ish sources for 12.0.3
[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 Rene Rivera
7 # Copyright (c) 2008 Jurko Gospodnetic
8 # Copyright (c) 2014 Microsoft Corporation
9 #
10 # Distributed under the Boost Software License, Version 1.0.
11 # (See accompanying file LICENSE_1_0.txt or copy at
12 # http://www.boost.org/LICENSE_1_0.txt)
13
14 ################################################################################
15 #
16 # MSVC Boost Build toolset module.
17 # --------------------------------
18 #
19 # All toolset versions need to have their location either auto-detected or
20 # explicitly specified except for the special 'default' version that expects the
21 # environment to find the needed tools or report an error.
22 #
23 ################################################################################
24
25 import "class" : new ;
26 import common ;
27 import feature ;
28 import generators ;
29 import mc ;
30 import midl ;
31 import os ;
32 import path ;
33 import pch ;
34 import property ;
35 import rc ;
36 import set ;
37 import toolset ;
38 import type ;
39
40
41 type.register MANIFEST : manifest ;
42 feature.feature embed-manifest : on off : incidental propagated ;
43 feature.feature embed-manifest-file : : free dependency ;
44
45 type.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 #
90 rule 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 #
161 rule 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 #
212 rule 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.
289 feature.feature windows-api : desktop store phone : propagated composite link-incompatible ;
290 feature.compose <windows-api>store : <define>WINAPI_FAMILY=WINAPI_FAMILY_APP <define>_WIN32_WINNT=0x0602
291 <linkflags>/APPCONTAINER ;
292 feature.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 ;
294 feature.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 #
300 rule register-toolset ( )
301 {
302 if ! msvc in [ feature.values toolset ]
303 {
304 register-toolset-really ;
305 }
306 }
307
308 rule 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.
321 if [ 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 }
331 else
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 #
347 actions compile.asm
348 {
349 $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
350 }
351
352
353 rule 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
361 rule 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
369 rule 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
386 toolset.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 #
406 actions 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
411 actions 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
416 rule 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
424 rule 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.
438 actions 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.
447 actions 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
453 rule 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
459 rule 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
466 rule 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 #
485 actions 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
493 actions compile.mc
494 {
495 $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
496 }
497
498
499 actions compile.rc
500 {
501 $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
502 }
503
504
505 rule 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
521 rule 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
548 if [ 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 }
585 else
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 #
624 rule 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
637 class 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 #
704 local 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.
744 rule 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
787 actions 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 #
796 local 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 {
823 setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ;
824 }
825 }
826
827 # Cygwin to Windows path translation.
828 setup = "\""$(setup:W)"\"" ;
829
830 # Append setup options to the setup name and add the final setup
831 # prefix & suffix.
832 setup-options ?= "" ;
833 local rewrite = [ feature.get-values <rewrite-setup-scripts> : $(options) ] ;
834 setup = [ maybe-rewrite-setup msvc : $(setup:J=" ") : $(setup-options:J=" ") : $(version) : $(rewrite) ] ;
835 setup = $(setup-prefix)$(setup)$(setup-suffix) ;
836
837 return $(setup) ;
838 }
839
840
841 # Worker rule for toolset version configuration. Takes an explicit version id or
842 # nothing in case it should configure the default toolset version (the first
843 # registered one or a new 'default' one in case no toolset versions have been
844 # registered yet).
845 #
846 local rule configure-really ( version ? : options * )
847 {
848 local v = $(version) ;
849
850 # Decide what the 'default' version is.
851 if ! $(v)
852 {
853 # Take the first registered (i.e. auto-detected) version.
854 version = [ $(.versions).all ] ;
855 version = $(version[1]) ;
856 v = $(version) ;
857
858 # Note: 'version' can still be empty at this point if no versions have
859 # been auto-detected.
860 version ?= "default" ;
861 }
862
863 # Version alias -> real version number.
864 version = [ resolve-possible-msvc-version-alias $(version) ] ;
865
866 # Check whether the selected configuration is already in use.
867 if $(version) in [ $(.versions).used ]
868 {
869 # Allow multiple 'toolset.using' calls for the same configuration if the
870 # identical sets of options are used.
871 if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
872 {
873 import errors ;
874 errors.error "MSVC toolset configuration: Toolset version"
875 "'$(version)' already configured." ;
876 }
877 }
878 else
879 {
880 # Register a new configuration.
881 $(.versions).register $(version) ;
882
883 # Add user-supplied to auto-detected options.
884 options = [ $(.versions).get $(version) : options ] $(options) ;
885
886 # Mark the configuration as 'used'.
887 $(.versions).use $(version) ;
888
889 # Generate conditions and save them.
890 local conditions = [ common.check-init-parameters msvc : version $(v) ]
891 ;
892
893 $(.versions).set $(version) : conditions : $(conditions) ;
894
895 local command = [ feature.get-values <command> : $(options) ] ;
896
897 # If version is specified, we try to search first in default paths, and
898 # only then in PATH.
899 command = [ common.get-invocation-command msvc : cl.exe : $(command) :
900 [ default-paths $(version) ] : $(version) ] ;
901
902 common.handle-options msvc : $(conditions) : $(command) : $(options) ;
903
904 if ! $(version)
905 {
906 # Even if version is not explicitly specified, try to detect the
907 # version from the path.
908 # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
909 # 9.0express as 9.0 here.
910 if [ MATCH "(Microsoft Visual Studio 15)" : $(command) ]
911 {
912 version = 15.0 ;
913 }
914 else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ]
915 {
916 version = 14.0 ;
917 }
918 else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ]
919 {
920 version = 12.0 ;
921 }
922 else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
923 {
924 version = 11.0 ;
925 }
926 else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
927 {
928 version = 10.0 ;
929 }
930 else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
931 {
932 version = 9.0 ;
933 }
934 else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
935 {
936 version = 8.0 ;
937 }
938 else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
939 {
940 version = 7.1 ;
941 }
942 else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
943 $(command) ]
944 {
945 version = 7.1toolkit ;
946 }
947 else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
948 {
949 version = 7.0 ;
950 }
951 else
952 {
953 version = 6.0 ;
954 }
955 }
956
957 # Generate and register setup command.
958
959 local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ;
960 local below-11.0 = [ MATCH ^([6789]\\.|10\\.) : $(version) ] ;
961
962 local cpu = i386 amd64 ia64 arm ;
963 if $(below-8.0)
964 {
965 cpu = i386 ;
966 }
967 else if $(below-11.0)
968 {
969 cpu = i386 amd64 ia64 ;
970 }
971
972 local setup-amd64 ;
973 local setup-i386 ;
974 local setup-ia64 ;
975 local setup-arm ;
976 local setup-phone-i386 ;
977 local setup-phone-arm ;
978
979 if $(command)
980 {
981 # TODO: Note that if we specify a non-existant toolset version then
982 # this rule may find and use a corresponding compiler executable
983 # belonging to an incorrect toolset version. For example, if you
984 # have only MSVC 7.1 installed, have its executable on the path and
985 # specify you want Boost Build to use MSVC 9.0, then you want Boost
986 # Build to report an error but this may cause it to silently use the
987 # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0
988 # toolset version.
989 command = [ common.get-absolute-tool-path $(command[-1]) ] ;
990 }
991
992 if $(command)
993 {
994 local parent = [ path.make $(command) ] ;
995 parent = [ path.parent $(parent) ] ;
996 parent = [ path.native $(parent) ] ;
997
998 # Setup will be used if the command name has been specified. If
999 # setup is not specified explicitly then a default setup script will
1000 # be used instead. Setup scripts may be global or architecture/
1001 # /platform/cpu specific. Setup options are used only in case of
1002 # global setup scripts.
1003
1004 # Default setup scripts provided with different VC distributions:
1005 #
1006 # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
1007 # builds. It was located in the bin folder for the regular version
1008 # and in the root folder for the free VC 7.1 tools.
1009 #
1010 # Later 8.0 & 9.0 versions introduce separate platform specific
1011 # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
1012 # located in or under the bin folder. Most also include a global
1013 # vcvarsall.bat helper script located in the root folder which runs
1014 # one of the aforementioned vcvars*.bat scripts based on the options
1015 # passed to it. So far only the version coming with some PlatformSDK
1016 # distributions does not include this top level script but to
1017 # support those we need to fall back to using the worker scripts
1018 # directly in case the top level script can not be found.
1019
1020 local global-setup = [ feature.get-values <setup> : $(options) ] ;
1021 global-setup = $(global-setup[1]) ;
1022 local global-setup-phone = $(global-setup) ;
1023 if ! $(below-8.0)
1024 {
1025 global-setup ?= [ locate-default-setup $(command) : $(parent) :
1026 vcvarsall.bat ] ;
1027 }
1028
1029 local default-setup-amd64 = vcvarsx86_amd64.bat ;
1030 local default-setup-i386 = vcvars32.bat ;
1031 local default-setup-ia64 = vcvarsx86_ia64.bat ;
1032 local default-setup-arm = vcvarsx86_arm.bat ;
1033 local default-setup-phone-i386 = vcvarsphonex86.bat ;
1034 local default-setup-phone-arm = vcvarsphonex86_arm.bat ;
1035
1036 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
1037 # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
1038 # mention an x86_IPF option, that seems to be a documentation bug
1039 # and x86_ia64 is the correct option.
1040 local default-global-setup-options-amd64 = x86_amd64 ;
1041 local default-global-setup-options-i386 = x86 ;
1042 local default-global-setup-options-ia64 = x86_ia64 ;
1043 local default-global-setup-options-arm = x86_arm ;
1044
1045 # When using 64-bit Windows, and targeting 64-bit, it is possible to
1046 # use a native 64-bit compiler, selected by the "amd64" & "ia64"
1047 # parameters to vcvarsall.bat. There are two variables we can use --
1048 # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
1049 # 'x86' when running 32-bit Windows, no matter which processor is
1050 # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
1051 # Windows.
1052 #
1053 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
1054 {
1055 default-global-setup-options-amd64 = amd64 ;
1056 }
1057 # When Boost.Build itself is running as a 32-bit process on 64-bit
1058 # Windows, the above test will fail (since WOW64 simulates a 32-bit
1059 # environment, including environment values). So check the WOW64
1060 # variable PROCESSOR_ARCHITEW6432 as well.
1061 if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITEW6432 ] ]
1062 {
1063 default-global-setup-options-amd64 = amd64 ;
1064 }
1065 # TODO: The same 'native compiler usage' should be implemented for
1066 # the Itanium platform by using the "ia64" parameter. For this
1067 # though we need someone with access to this platform who can find
1068 # out how to correctly detect this case.
1069 else if $(somehow-detect-the-itanium-platform)
1070 {
1071 default-global-setup-options-ia64 = ia64 ;
1072 }
1073
1074 for local c in $(cpu)
1075 {
1076 setup-$(c) = [ generate-setup-cmd $(version) : $(command) : $(parent) : $(options) : $(c) : $(global-setup) : $(default-global-setup-options-$(c)) : $(default-setup-$(c)) ] ;
1077 }
1078
1079 # Windows phone has different setup scripts, located in a different directory hierarchy.
1080 # The 11.0 toolset can target Windows Phone 8.0 and the 12.0 toolset can target Windows Phone 8.1,
1081 # each of which have a different directory for their vcvars setup scripts.
1082 local phone-parent = [ path.native [ path.join $(parent) WPSDK ] ] ;
1083 local phone-directory = $(phone-parent) ;
1084 if [ MATCH "(11.0)" : $(version) ]
1085 {
1086 phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ;
1087 }
1088 else if [ MATCH "(12.0)" : $(version) ]
1089 {
1090 phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ;
1091 }
1092 global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ;
1093
1094 # If can't locate default phone setup script then this VS version doesn't support Windows Phone.
1095 if $(global-setup-phone)-is-defined
1096 {
1097 # i386 CPU is for the Windows Phone emulator in Visual Studio.
1098 local phone-cpu = i386 arm ;
1099 for local c in $(phone-cpu)
1100 {
1101 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)) ] ;
1102 }
1103 }
1104 }
1105
1106 # Get tool names (if any) and finish setup.
1107
1108 compiler = [ feature.get-values <compiler> : $(options) ] ;
1109 compiler ?= cl ;
1110
1111 linker = [ feature.get-values <linker> : $(options) ] ;
1112 linker ?= link ;
1113
1114 resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
1115 resource-compiler ?= rc ;
1116
1117 # Turn on some options for i386 assembler
1118 # -coff generate COFF format object file (compatible with cl.exe output)
1119 local default-assembler-amd64 = ml64 ;
1120 local default-assembler-i386 = "ml -coff" ;
1121 local default-assembler-ia64 = ias ;
1122 local default-assembler-ia64 = armasm ;
1123
1124 assembler = [ feature.get-values <assembler> : $(options) ] ;
1125
1126 idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
1127 idl-compiler ?= midl ;
1128
1129 mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
1130 mc-compiler ?= mc ;
1131
1132 manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
1133 manifest-tool ?= mt ;
1134
1135 local cc-filter = [ feature.get-values <compiler-filter> : $(options) ]
1136 ;
1137
1138 for local c in $(cpu)
1139 {
1140 # Setup script is not required in some configurations.
1141 setup-$(c) ?= "" ;
1142
1143 local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
1144
1145 if $(.debug-configuration)
1146 {
1147 for local cpu-condition in $(cpu-conditions)
1148 {
1149 ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
1150 }
1151 }
1152
1153 local cpu-assembler = $(assembler) ;
1154 cpu-assembler ?= $(default-assembler-$(c)) ;
1155
1156 toolset.flags msvc.compile .RC <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(resource-compiler) ;
1157 toolset.flags msvc.compile .IDL <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(idl-compiler) ;
1158 toolset.flags msvc.compile .MC <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(mc-compiler) ;
1159 toolset.flags msvc.link .MT <windows-api>$(api)/$(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ;
1160
1161 for api in desktop store phone
1162 {
1163 local setup-script = $(setup-$(c)) ;
1164 if $(api) = phone
1165 {
1166 setup-script = $(setup-phone-$(c)) ;
1167 }
1168 if $(api) = desktop
1169 {
1170 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 -nologo ;
1171 }
1172 else
1173 {
1174 toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 /ZW /EHsc -nologo ;
1175 }
1176 toolset.flags msvc.compile .ASM <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(cpu-assembler) -nologo ;
1177 toolset.flags msvc.link .LD <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(linker) /NOLOGO /INCREMENTAL:NO ;
1178 toolset.flags msvc.archive .LD <windows-api>$(api)/$(cpu-conditions) : $(setup-script)$(linker) /lib /NOLOGO ;
1179 }
1180
1181 if $(cc-filter)
1182 {
1183 toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
1184 }
1185 }
1186
1187 # Starting with Visual Studio 2013 the CRT is split into a desktop and app dll.
1188 # If targeting WinRT and 12.0 set lib path to link against app CRT.
1189 if [ MATCH "(12)" : $(version) ]
1190 {
1191 local storeLibPath = [ path.join $(parent) "lib/store" ] ;
1192 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-i386) : [ path.native $(storeLibPath) ] ;
1193 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-amd64) : [ path.native [ path.join $(storeLibPath) "amd64" ] ] ;
1194 toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-arm) : [ path.native [ path.join $(storeLibPath) "arm" ] ] ;
1195 }
1196
1197 # Set version-specific flags.
1198 configure-version-specific msvc : $(version) : $(conditions) ;
1199 }
1200 }
1201
1202
1203 # Returns the default installation path for the given version.
1204 #
1205 local rule default-path ( version )
1206 {
1207 # Use auto-detected path if possible.
1208 local path = [ feature.get-values <command> : [ $(.versions).get $(version)
1209 : options ] ] ;
1210
1211 if $(path)
1212 {
1213 path = $(path:D) ;
1214 }
1215 else
1216 {
1217 # Check environment.
1218 if $(.version-$(version)-env)
1219 {
1220 local vc-path = [ os.environ $(.version-$(version)-env) ] ;
1221 if $(vc-path)
1222 {
1223 vc-path = [ path.make $(vc-path) ] ;
1224 vc-path = [ path.join $(vc-path) $(.version-$(version)-envpath) ] ;
1225 vc-path = [ path.native $(vc-path) ] ;
1226
1227 path = $(vc-path) ;
1228 }
1229 }
1230
1231 # Check default path.
1232 if ! $(path) && $(.version-$(version)-path)
1233 {
1234 path = [ path.native [ path.join $(.ProgramFiles) $(.version-$(version)-path) ] ] ;
1235 }
1236 }
1237
1238 return $(path) ;
1239 }
1240
1241
1242 # Returns either the default installation path (if 'version' is not empty) or
1243 # list of all known default paths (if no version is given)
1244 #
1245 local rule default-paths ( version ? )
1246 {
1247 local possible-paths ;
1248
1249 if $(version)
1250 {
1251 possible-paths += [ default-path $(version) ] ;
1252 }
1253 else
1254 {
1255 for local i in $(.known-versions)
1256 {
1257 possible-paths += [ default-path $(i) ] ;
1258 }
1259 }
1260
1261 return $(possible-paths) ;
1262 }
1263
1264
1265 rule get-rspline ( target : lang-opt )
1266 {
1267 CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
1268 $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES)
1269 $(.nl)\"-I$(INCLUDES:W)\" ] ;
1270 }
1271
1272 class msvc-linking-generator : linking-generator
1273 {
1274 # Calls the base version. If necessary, also create a target for the
1275 # manifest file.specifying source's name as the name of the created
1276 # target. As result, the PCH will be named whatever.hpp.gch, and not
1277 # whatever.gch.
1278 rule generated-targets ( sources + : property-set : project name ? )
1279 {
1280 local result = [ linking-generator.generated-targets $(sources)
1281 : $(property-set) : $(project) $(name) ] ;
1282
1283 if $(result)
1284 {
1285 local name-main = [ $(result[0]).name ] ;
1286 local action = [ $(result[0]).action ] ;
1287
1288 if [ $(property-set).get <debug-symbols> ] = "on"
1289 {
1290 # We force the exact name on PDB. The reason is tagging -- the
1291 # tag rule may reasonably special case some target types, like
1292 # SHARED_LIB. The tag rule will not catch PDBs, and it cannot
1293 # even easily figure out if a PDB is paired with a SHARED_LIB,
1294 # EXE or something else. Because PDBs always get the same name
1295 # as the main target, with .pdb as extension, just force it.
1296 local target = [ class.new file-target $(name-main:S=.pdb) exact
1297 : PDB : $(project) : $(action) ] ;
1298 local registered-target = [ virtual-target.register $(target) ]
1299 ;
1300 if $(target) != $(registered-target)
1301 {
1302 $(action).replace-targets $(target) : $(registered-target) ;
1303 }
1304 result += $(registered-target) ;
1305 }
1306
1307 if [ $(property-set).get <embed-manifest> ] = "off"
1308 {
1309 # Manifest is an evil target. It has .manifest appened to the
1310 # name of the main target, including extension, e.g.
1311 # a.exe.manifest. We use the 'exact' name to achieve this
1312 # effect.
1313 local target = [ class.new file-target $(name-main).manifest
1314 exact : MANIFEST : $(project) : $(action) ] ;
1315 local registered-target = [ virtual-target.register $(target) ]
1316 ;
1317 if $(target) != $(registered-target)
1318 {
1319 $(action).replace-targets $(target) : $(registered-target) ;
1320 }
1321 result += $(registered-target) ;
1322 }
1323 }
1324 return $(result) ;
1325 }
1326 }
1327
1328
1329 # Unsafe worker rule for the register-toolset() rule. Must not be called
1330 # multiple times.
1331 #
1332 local rule register-toolset-really ( )
1333 {
1334 feature.extend toolset : msvc ;
1335
1336 # Intel and msvc supposedly have link-compatible objects.
1337 feature.subfeature toolset msvc : vendor : intel : propagated optional ;
1338
1339 # Inherit MIDL flags.
1340 toolset.inherit-flags msvc : midl ;
1341
1342 # Inherit MC flags.
1343 toolset.inherit-flags msvc : mc ;
1344
1345 # Dynamic runtime comes only in MT flavour.
1346 toolset.add-requirements
1347 <toolset>msvc,<runtime-link>shared:<threading>multi ;
1348
1349 # Declare msvc toolset specific features.
1350 {
1351 feature.feature debug-store : object database : propagated ;
1352 feature.feature pch-source : : dependency free ;
1353 }
1354
1355 # Declare generators.
1356 {
1357 # TODO: Is it possible to combine these? Make the generators
1358 # non-composing so that they do not convert each source into a separate
1359 # .rsp file.
1360 generators.register [ new msvc-linking-generator msvc.link :
1361 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ;
1362 generators.register [ new msvc-linking-generator msvc.link.dll :
1363 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB :
1364 <toolset>msvc <suppress-import-lib>false ] ;
1365 generators.register [ new msvc-linking-generator msvc.link.dll :
1366 OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB :
1367 <toolset>msvc <suppress-import-lib>true ] ;
1368
1369 generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
1370 generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
1371 generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
1372 generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
1373 generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
1374
1375 # Using 'register-c-compiler' adds the build directory to INCLUDES.
1376 generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
1377 generators.override msvc.compile.rc : rc.compile.resource ;
1378 generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
1379
1380 generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
1381 generators.override msvc.compile.idl : midl.compile.idl ;
1382
1383 generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
1384 generators.override msvc.compile.mc : mc.compile ;
1385
1386 # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
1387 # the latter have their HPP type derived from H. The type of compilation
1388 # is determined entirely by the destination type.
1389 generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
1390 generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
1391
1392 generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
1393 generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
1394 }
1395
1396 toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
1397 toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
1398 toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
1399
1400 #
1401 # Declare flags for compilation.
1402 #
1403
1404 toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ;
1405 toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ;
1406
1407 toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
1408 toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
1409
1410 toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
1411 toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
1412 toolset.flags msvc.compile CFLAGS <optimization>off : /Od ;
1413 toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
1414 toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
1415 toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
1416
1417 toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ;
1418 toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ;
1419 toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ;
1420 toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
1421
1422 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
1423 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
1424 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
1425 toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
1426
1427 # By default 8.0 enables rtti support while prior versions disabled it. We
1428 # simply enable or disable it explicitly so we do not have to depend on this
1429 # default behaviour.
1430 toolset.flags msvc.compile CFLAGS <rtti>on : /GR ;
1431 toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ;
1432 toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
1433 toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
1434
1435 toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
1436 toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
1437
1438 toolset.flags msvc.compile OPTIONS <cflags> : ;
1439 toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ;
1440
1441 toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
1442
1443 toolset.flags msvc.compile DEFINES <define> ;
1444 toolset.flags msvc.compile UNDEFS <undef> ;
1445 toolset.flags msvc.compile INCLUDES <include> ;
1446
1447 # Declare flags for the assembler.
1448 toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
1449
1450 toolset.flags msvc.compile.asm ASMFLAGS <debug-symbols>on : "/Zi /Zd" ;
1451
1452 toolset.flags msvc.compile.asm ASMFLAGS <warnings>on : /W3 ;
1453 toolset.flags msvc.compile.asm ASMFLAGS <warnings>off : /W0 ;
1454 toolset.flags msvc.compile.asm ASMFLAGS <warnings>all : /W4 ;
1455 toolset.flags msvc.compile.asm ASMFLAGS <warnings-as-errors>on : /WX ;
1456
1457 toolset.flags msvc.compile.asm DEFINES <define> ;
1458
1459 # Declare flags for linking.
1460 {
1461 toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet
1462 toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
1463 toolset.flags msvc.link DEF_FILE <def-file> ;
1464
1465 # The linker disables the default optimizations when using /DEBUG so we
1466 # have to enable them manually for release builds with debug symbols.
1467 toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ;
1468
1469 toolset.flags msvc LINKFLAGS <user-interface>console : /subsystem:console ;
1470 toolset.flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ;
1471 toolset.flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ;
1472 toolset.flags msvc LINKFLAGS <user-interface>native : /subsystem:native ;
1473 toolset.flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ;
1474
1475 toolset.flags msvc.link OPTIONS <linkflags> ;
1476 toolset.flags msvc.link LINKPATH <library-path> ;
1477
1478 toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
1479 toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
1480 toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
1481 toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
1482
1483 toolset.flags msvc.link.dll LINKFLAGS <suppress-import-lib>true : /NOENTRY ;
1484 }
1485
1486 toolset.flags msvc.archive AROPTIONS <archiveflags> ;
1487 }
1488
1489
1490 # Locates the requested setup script under the given folder and returns its full
1491 # path or nothing in case the script can not be found. In case multiple scripts
1492 # are found only the first one is returned.
1493 #
1494 # TODO: There used to exist a code comment for the msvc.init rule stating that
1495 # we do not correctly detect the location of the vcvars32.bat setup script for
1496 # the free VC7.1 tools in case user explicitly provides a path. This should be
1497 # tested or simply remove this whole comment in case this toolset version is no
1498 # longer important.
1499 #
1500 local rule locate-default-setup ( command : parent : setup-name )
1501 {
1502 local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
1503 if $(result[1])
1504 {
1505 return $(result[1]) ;
1506 }
1507 }
1508
1509
1510 # Validates given path, registers found configuration and prints debug
1511 # information about it.
1512 #
1513 local rule register-configuration ( version : path ? )
1514 {
1515 if $(path)
1516 {
1517 local command = [ GLOB $(path) : cl.exe ] ;
1518
1519 if $(command)
1520 {
1521 if $(.debug-configuration)
1522 {
1523 ECHO notice: [msvc-cfg] msvc-$(version) detected, command:
1524 '$(command)' ;
1525 }
1526
1527 $(.versions).register $(version) ;
1528 $(.versions).set $(version) : options : <command>$(command) ;
1529 }
1530 }
1531 }
1532
1533
1534 ################################################################################
1535 #
1536 # Startup code executed when loading this module.
1537 #
1538 ################################################################################
1539
1540 if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
1541 {
1542 .debug-configuration = true ;
1543 }
1544
1545 # Miscellaneous constants.
1546 .RM = [ common.rm-command ] ;
1547 .nl = "
1548 " ;
1549 .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
1550 .escaped-double-quote = "\"" ;
1551 .TOUCH_FILE = [ common.file-touch-command ] ;
1552
1553 # List of all registered configurations.
1554 .versions = [ new configurations ] ;
1555
1556 # Supported CPU architectures.
1557 .cpu-arch-i386 =
1558 <architecture>/<address-model>
1559 <architecture>/<address-model>32
1560 <architecture>x86/<address-model>
1561 <architecture>x86/<address-model>32 ;
1562
1563 .cpu-arch-amd64 =
1564 <architecture>/<address-model>64
1565 <architecture>x86/<address-model>64 ;
1566
1567 .cpu-arch-ia64 =
1568 <architecture>ia64/<address-model>
1569 <architecture>ia64/<address-model>64 ;
1570
1571 .cpu-arch-arm =
1572 <architecture>arm/<address-model>
1573 <architecture>arm/<address-model>32 ;
1574
1575
1576 # Supported CPU types (only Itanium optimization options are supported from
1577 # VC++ 2005 on). See
1578 # http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
1579 # detailed information.
1580 .cpu-type-g5 = i586 pentium pentium-mmx ;
1581 .cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
1582 k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ;
1583 .cpu-type-em64t = prescott nocona core2 corei7 corei7-avx core-avx-i
1584 conroe conroe-xe conroe-l allendale merom
1585 merom-xe kentsfield kentsfield-xe penryn wolfdale
1586 yorksfield nehalem sandy-bridge ivy-bridge haswell ;
1587 .cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3
1588 athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3
1589 btver1 btver2 ;
1590 .cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
1591 athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
1592 .cpu-type-itanium = itanium itanium1 merced ;
1593 .cpu-type-itanium2 = itanium2 mckinley ;
1594 .cpu-type-arm = armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
1595 armv7 armv7s ;
1596
1597 # Known toolset versions, in order of preference.
1598 .known-versions = 15.0 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
1599 7.1toolkit 7.0 6.0 ;
1600
1601 # Version aliases.
1602 .version-alias-6 = 6.0 ;
1603 .version-alias-6.5 = 6.0 ;
1604 .version-alias-7 = 7.0 ;
1605 .version-alias-8 = 8.0 ;
1606 .version-alias-9 = 9.0 ;
1607 .version-alias-10 = 10.0 ;
1608 .version-alias-11 = 11.0 ;
1609 .version-alias-12 = 12.0 ;
1610 .version-alias-14 = 14.0 ;
1611 .version-alias-15 = 15.0 ;
1612
1613 # Names of registry keys containing the Visual C++ installation path (relative
1614 # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
1615 .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
1616 .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
1617 .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
1618 .version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
1619 .version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
1620 .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
1621 .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
1622 .version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ;
1623 .version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ;
1624 .version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ;
1625 .version-12.0-reg = "VisualStudio\\12.0\\Setup\\VC" ;
1626 .version-14.0-reg = "VisualStudio\\14.0\\Setup\\VC" ;
1627 .version-15.0-reg = "VisualStudio\\15.0\\Setup\\VC" ;
1628
1629 # Visual C++ Toolkit 2003 does not store its installation path in the registry.
1630 # The environment variable 'VCToolkitInstallDir' and the default installation
1631 # path will be checked instead.
1632 .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003" "bin" ;
1633 .version-7.1toolkit-env = VCToolkitInstallDir ;
1634
1635 # Path to the folder containing "cl.exe" relative to the value of the
1636 # corresponding environment variable.
1637 .version-7.1toolkit-envpath = "bin" ;
1638
1639
1640 # Auto-detect all the available msvc installations on the system.
1641 auto-detect-toolset-versions ;
1642
1643
1644 # And finally trigger the actual Boost Build toolset registration.
1645 register-toolset ;