-
Notifications
You must be signed in to change notification settings - Fork 49
/
msvc.jam
2257 lines (1960 loc) · 90.9 KB
/
msvc.jam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Copyright (c) 2003 David Abrahams
# Copyright (c) 2005 Vladimir Prus
# Copyright (c) 2005 Alexey Pakhunov
# Copyright (c) 2006 Bojan Resnik
# Copyright (c) 2006 Ilya Sokolov
# Copyright (c) 2007-2017 Rene Rivera
# Copyright (c) 2008 Jurko Gospodnetic
# Copyright (c) 2014 Microsoft Corporation
# Copyright (c) 2019 Michał Janiszewski
# Copyright (c) 2020 Nikita Kniazev
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at
# https://www.bfgroup.xyz/b2/LICENSE.txt)
#| tag::doc[]
[[bbv2.reference.tools.compiler.msvc]]
= Microsoft Visual C++
The `msvc` module supports the
https://docs.microsoft.com/en-us/cpp/[Microsoft Visual C++] command-line
tools on Microsoft Windows. The supported products and versions of
command line tools are listed below:
* Visual Studio 2022-14.3
* Visual Studio 2019-14.2
* Visual Studio 2017—14.1
* Visual Studio 2015—14.0
* Visual Studio 2013—12.0
* Visual Studio 2012—11.0
* Visual Studio 2010—10.0
* Visual Studio 2008—9.0
* Visual Studio 2005—8.0
* Visual Studio .NET 2003—7.1
* Visual Studio .NET—7.0
* Visual Studio 6.0, Service Pack 5--6.5
The user would then call the boost build executable with the toolset set
equal to `msvc-[version number]` for example to build with Visual Studio
2019 one could run:
----
.\b2 toolset=msvc-14.2 target
----
The `msvc` module is initialized using the following syntax:
----
using msvc : [version] : [c++-compile-command] : [compiler options] ;
----
This statement may be repeated several times, if you want to configure
several versions of the compiler.
If the version is not explicitly specified, the most recent version
found in the registry will be used instead. If the special value `all`
is passed as the version, all versions found in the registry will be
configured. If a version is specified, but the command is not, the
compiler binary will be searched in standard installation paths for that
version, followed by PATH.
The compiler command should be specified using forward slashes, and
quoted.
The following options can be provided, using
_`<option-name>option-value syntax`_:
`cflags`::
Specifies additional compiler flags that will be used when compiling C
sources.
`cxxflags`::
Specifies additional compiler flags that will be used when compiling C++
sources.
`compileflags`::
Specifies additional compiler flags that will be used when compiling both C
and C++ sources.
`linkflags`::
Specifies additional command line options that will be passed to the linker.
`assembler`::
The command that compiles assembler sources. If not specified, `ml`
will be used. The command will be invoked after the setup script was
executed and adjusted the PATH variable.
`compiler`::
The command that compiles C and C++ sources. If not specified, `cl`
will be used. The command will be invoked after the setup script was
executed and adjusted the PATH variable.
`compiler-filter`::
Command through which to pipe the output of running the compiler. For
example to pass the output to STLfilt.
`idl-compiler`::
The command that compiles Microsoft COM interface definition files. If
not specified, `midl` will be used. The command will be invoked after
the setup script was executed and adjusted the PATH variable.
`linker`::
The command that links executables and dynamic libraries. If not
specified, `link` will be used. The command will be invoked after the
setup script was executed and adjusted the PATH variable.
`mc-compiler`::
The command that compiles Microsoft message catalog files. If not
specified, `mc` will be used. The command will be invoked after the
setup script was executed and adjusted the PATH variable.
`resource-compiler`::
The command that compiles resource files. If not specified, `rc` will
be used. The command will be invoked after the setup script was
executed and adjusted the PATH variable.
`setup`::
The filename of the global environment setup script to run before
invoking any of the tools defined in this toolset. Will not be used in
case a target platform specific script has been explicitly specified
for the current target platform. Used setup script will be passed the
target platform identifier (x86, x86_amd64, x86_ia64, amd64 or ia64)
as a parameter. If not specified a default script is chosen based on
the used compiler binary, e.g. `vcvars32.bat` or `vsvars32.bat`.
`setup-amd64`; `setup-i386`; `setup-ia64`::
The filename of the target platform specific environment setup script
to run before invoking any of the tools defined in this toolset. If
not specified the global environment setup script is used.
[[bbv2.reference.tools.compiler.msvc.64]]
== 64-bit support
Starting with version 8.0, Microsoft Visual Studio can generate binaries
for 64-bit processor, both 64-bit flavours of x86 (codenamed
AMD64/EM64T), and Itanium (codenamed IA64). In addition, compilers that
are itself run in 64-bit mode, for better performance, are provided. The
complete list of compiler configurations are as follows (we abbreviate
AMD64/EM64T to just AMD64):
* 32-bit x86 host, 32-bit x86 target
* 32-bit x86 host, 64-bit AMD64 target
* 32-bit x86 host, 64-bit IA64 target
* 64-bit AMD64 host, 64-bit AMD64 target
* 64-bit IA64 host, 64-bit IA64 target
The 32-bit host compilers can be always used, even on 64-bit Windows. On
the contrary, 64-bit host compilers require both 64-bit host processor
and 64-bit Windows, but can be faster. By default, only 32-bit host,
32-bit target compiler is installed, and additional compilers need to be
installed explicitly.
To use 64-bit compilation you should:
1. Configure you compiler as usual. If you provide a path to the
compiler explicitly, provide the path to the 32-bit compiler. If you try
to specify the path to any of 64-bit compilers, configuration will not
work.
2. When compiling, use `address-model=64`, to generate AMD64 code.
3. To generate IA64 code, use `architecture=ia64`
The (AMD64 host, AMD64 target) compiler will be used automatically when
you are generating AMD64 code and are running 64-bit Windows on AMD64.
The (IA64 host, IA64 target) compiler will never be used, since nobody
has an IA64 machine to test.
It is believed that AMD64 and EM64T targets are essentially compatible.
The compiler options `/favor:AMD64` and `/favor:EM64T`, which are
accepted only by AMD64 targeting compilers, cause the generated code to
be tuned to a specific flavor of 64-bit x86. B2 will make use
of those options depending on the value of the`instruction-set` feature.
Starting with version 14.0, Microsoft Visual Studio can generate binaries
using native arm64 tools to compile for x86, x86_64, and arm64.
[[bbv2.reference.tools.compiler.msvc.winrt]]
== Windows Runtime support
Starting with version 11.0, Microsoft Visual Studio can produce binaries
for Windows Store and Phone in addition to traditional Win32 desktop. To
specify which Windows API set to target, use the `windows-api` feature.
Available options are `desktop`, `store`, or `phone`. If not specified,
`desktop` will be used.
When using `store` or `phone` the specified toolset determines what
Windows version is targeted. The following options are available:
* Windows 8.0: toolset=msvc-11.0 windows-api=store
* Windows 8.1: toolset=msvc-12.0 windows-api=store
* Windows Phone 8.0: toolset=msvc-11.0 windows-api=phone
* Windows Phone 8.1: toolset=msvc-12.0 windows-api=phone
For example use the following to build for Windows Store 8.1 with the
ARM architecture:
----
.\b2 toolset=msvc-12.0 windows-api=store architecture=arm
----
Note that when targeting Windows Phone 8.1, version 12.0 didn't include
the vcvars phone setup scripts. They can be separately downloaded from
http://blogs.msdn.com/b/vcblog/archive/2014/07/18/using-boost-libraries-in-windows-store-and-phone-applications.aspx[here].
|# # end::doc[]
################################################################################
#
# MSVC Boost Build toolset module.
# --------------------------------
#
# All toolset versions need to have their location either auto-detected or
# explicitly specified except for the special 'default' version that expects the
# environment to find the needed tools or report an error.
#
################################################################################
import "class" : new ;
import common ;
import feature ;
import generators ;
import mc ;
import midl ;
import os ;
import path ;
import pch ;
import project ;
import property ;
import property-set ;
import rc ;
import regex ;
import sequence ;
import set ;
import testing ;
import toolset ;
import type ;
import virtual-target ;
import version ;
type.register MANIFEST : manifest ;
#| tag::embed-doc[]
[[bbv2.builtin.features.embed-manifest]]`embed-manifest`::
*Allowed values:* `on`, `off`.
+
This feature is specific to the `msvc` toolset (see <<Microsoft Visual C++>>),
and controls whether the manifest files should be embedded inside executables
and shared libraries, or placed alongside them. This feature corresponds to the
IDE option found in the project settings dialog, under Configuration Properties
-> Manifest Tool -> Input and Output -> Embed manifest.
|# # end::embed-doc[]
feature.feature embed-manifest : on off : incidental propagated ;
#| tag::embed-doc[]
[[bbv2.builtin.features.embed-manifest-file]]`embed-manifest-file`::
This feature is specific to the `msvc` toolset (see <<Microsoft Visual C++>>),
and controls which manifest files should be embedded inside executables and
shared libraries. This feature corresponds to the IDE option found in the
project settings dialog, under Configuration Properties -> Manifest Tool ->
Input and Output -> Additional Manifest Files.
|# # end::embed-doc[]
feature.feature embed-manifest-file : : free dependency ;
#| tag::embed-doc[]
[[bbv2.builtin.features.embed-manifest-via]]`embed-manifest-via`::
This feature is specific to the `msvc` toolset (see <<Microsoft Visual C++>>),
and controls whether a manifest should be embedded via linker or manifest tool.
|# # end::embed-doc[]
feature.feature embed-manifest-via : mt linker : incidental propagated ;
type.register PDB : pdb ;
################################################################################
#
# Public rules.
#
################################################################################
# Initialize a specific toolset version configuration. As the result, path to
# compiler and, possible, program names are set up, and will be used when that
# version of compiler is requested. For example, you might have:
#
# using msvc : 6.5 : cl.exe ;
# using msvc : 7.0 : Y:/foo/bar/cl.exe ;
#
# The version parameter may be omitted:
#
# using msvc : : Z:/foo/bar/cl.exe ;
#
# The following keywords have special meanings when specified as versions:
# - all - all detected but not yet used versions will be marked as used
# with their default options.
# - default - this is an equivalent to an empty version.
#
# Depending on a supplied version, detected configurations and presence 'cl.exe'
# in the path different results may be achieved. The following table describes
# the possible scenarios:
#
# Nothing "x.y"
# Passed Nothing "x.y" detected, detected,
# version detected detected cl.exe in path cl.exe in path
#
# default Error Use "x.y" Create "default" Use "x.y"
# all None Use all None Use all
# x.y - Use "x.y" - Use "x.y"
# a.b Error Error Create "a.b" Create "a.b"
#
# "x.y" - refers to a detected version;
# "a.b" - refers to an undetected version.
#
# FIXME: Currently the command parameter and the <compiler> property parameter
# seem to overlap in duties. Remove this duplication. This seems to be related
# to why someone started preparing to replace init with configure rules.
#
rule init (
# The msvc version being configured. When omitted the tools invoked when no
# explicit version is given will be configured.
version ?
# The command used to invoke the compiler. If not specified:
# - if version is given, default location for that version will be
# searched
#
# - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
# and 6.* will be searched
#
# - if compiler is not found in the default locations, PATH will be
# searched.
: command *
# Options may include:
#
# All options shared by multiple toolset types as handled by the
# common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>,
# <fflags> & <linkflags>.
#
# <assembler>
# <compiler>
# <idl-compiler>
# <linker>
# <mc-compiler>
# <resource-compiler>
# Exact tool names to be used by this msvc toolset configuration.
#
# <compiler-filter>
# Command through which to pipe the output of running the compiler.
# For example to pass the output to STLfilt.
#
# <setup>
# Global setup command to invoke before running any of the msvc tools.
# It will be passed additional option parameters depending on the actual
# target platform.
#
# <setup-amd64>
# <setup-i386>
# <setup-ia64>
# <setup-arm>
# <setup-phone-i386>
# <setup-phone-arm>
# Platform specific setup command to invoke before running any of the
# msvc tools used when builing a target for a specific platform, e.g.
# when building a 32 or 64 bit executable.
#
# <rewrite-setup-scripts>
# Whether to rewrite setup scripts. New scripts will be output in
# build tree and will be used instead of originals in build actions.
# Possible values:
# * on - rewrite scripts, if they do not already exist (default)
# * always - always rewrite scripts, even if they already exist
# * off - use original setup scripts
: options *
)
{
if $(command)
{
options += <command>$(command) ;
}
configure $(version) : $(options) ;
}
# 'configure' is a newer version of 'init'. The parameter 'command' is passed as
# a part of the 'options' list. See the 'init' rule comment for more detailed
# information.
#
rule configure ( version ? : options * )
{
switch $(version)
{
case "all" :
if $(options)
{
import errors ;
errors.error "MSVC toolset configuration: options should be"
"empty when '$(version)' is specified." ;
}
# Auto-register any version we can detect.
for local i in $(.known-versions)
{
try-auto-detect-version $(i) ;
}
# Configure (i.e. mark as used) all registered versions.
local all-versions = [ $(.versions).all ] ;
if ! $(all-versions)
{
if $(.debug-configuration)
{
ECHO "notice: [msvc-cfg] Asked to configure all registered"
"msvc toolset versions when there are none currently"
"registered." ;
}
}
else
{
for local v in $(all-versions)
{
# Note that there is no need to skip already configured
# versions here as this will request configure-really rule
# to configure the version using default options which will
# in turn cause it to simply do nothing in case the version
# has already been configured.
configure-really $(v) ;
}
}
case "default" :
configure-really : $(options) ;
case * :
configure-really $(version) : $(options) ;
}
}
# Sets up flag definitions dependent on the compiler version used.
# - 'version' is the version of compiler in N.M format.
# - 'conditions' is the property set to be used as flag conditions.
# - 'toolset' is the toolset for which flag settings are to be defined.
# This makes the rule reusable for other msvc-option-compatible compilers.
#
rule configure-version-specific ( toolset : version : conditions )
{
toolset.push-checking-for-flags-module unchecked ;
# Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
# /Zc:wchar_t options that improve C++ standard conformance, but those
# options are off by default. If we are sure that the msvc version is at
# 7.*, add those options explicitly. We can be sure either if user specified
# version 7.* explicitly or if we auto-detected the version ourselves.
if ! [ MATCH ^(6\\.) : $(version) ]
{
toolset.flags $(toolset).compile OPTIONS $(conditions) : "/Zc:forScope" "/Zc:wchar_t" ;
toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
# Explicitly disable the 'function is deprecated' warning. Some msvc
# versions have a bug, causing them to emit the deprecation warning even
# with /W0.
toolset.flags $(toolset).compile OPTIONS $(conditions)/<warnings>off : /wd4996 ;
if [ MATCH "^([78]\\.)" : $(version) ]
{
# 64-bit compatibility warning deprecated since 9.0, see
# http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
toolset.flags $(toolset).compile OPTIONS $(conditions)/<warnings>all : /Wp64 ;
}
}
# 12.0 (VS2013 Update 2) introduced /Zc:inline opt-in standard conformance
# compiler flag that also similar to linker /opt:ref removes unreferenced
# variables and functions that have internal linkage
if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 12 ]
{
toolset.flags $(toolset).compile OPTIONS $(conditions) : "/Zc:inline" ;
# /Gy analog for variables: https://devblogs.microsoft.com/cppblog/introducing-gw-compiler-switch/
toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Gw ;
}
# 14.0 introduced /Zc:throwingNew opt-in flag that disables a workaround
# for not throwing operator new in VC up to 6.0
if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 14 ]
{
toolset.flags $(toolset).compile C++FLAGS $(conditions) : "/Zc:throwingNew" ;
}
# 14.27 (VS2019 Version 16.7) introduced support for ASAN on x86 and x64 CPUs
# This check however now only tests for 14.2 (which is 16.0) as msvc.jam doesn't distinguish between minor versions (e.g. 14.21..14.28 etc)
if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 14 2 ]
{
# General asan compile and link options.
toolset.flags $(toolset).compile OPTIONS
$(conditions)/<address-sanitizer>on
: /fsanitize=address /FS ;
toolset.flags $(toolset).link LINKFLAGS
$(conditions)/<address-sanitizer>on
: -incremental\:no ;
# The various 64 bit runtime asan support libraries and related flags.
toolset.flags $(toolset).link FINDLIBS_SA
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>shared
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>shared
: clang_rt.asan_dynamic-x86_64
clang_rt.asan_dynamic_runtime_thunk-x86_64 ;
toolset.flags $(toolset).link LINKFLAGS
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>shared
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>shared
: /wholearchive\:"clang_rt.asan_dynamic-x86_64.lib"
/wholearchive\:"clang_rt.asan_dynamic_runtime_thunk-x86_64.lib" ;
toolset.flags $(toolset).link FINDLIBS_SA
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>EXE
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>UNIT_TEST
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>EXE
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>UNIT_TEST
: clang_rt.asan-x86_64
clang_rt.asan_cxx-x86_64 ;
toolset.flags $(toolset).link LINKFLAGS
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>EXE
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static/<main-target-type>UNIT_TEST
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>EXE
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static/<main-target-type>UNIT_TEST
: /wholearchive\:"clang_rt.asan-x86_64.lib"
/wholearchive\:"clang_rt.asan_cxx-x86_64.lib" ;
toolset.flags $(toolset).link.dll FINDLIBS_SA
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static
: clang_rt.asan_dll_thunk-x86_64 ;
toolset.flags $(toolset).link.dll LINKFLAGS
$(conditions)/<address-sanitizer>on/<address-model>/<runtime-link>static
$(conditions)/<address-sanitizer>on/<address-model>64/<runtime-link>static
: /wholearchive\:"clang_rt.asan_dll_thunk-x86_64.lib" ;
# The various 32 bit runtime asan support libraries and related flags.
toolset.flags $(toolset).link FINDLIBS_SA
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>shared
: clang_rt.asan_dynamic-i386 clang_rt.asan_dynamic_runtime_thunk-i386 ;
toolset.flags $(toolset).link LINKFLAGS
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>shared
: /wholearchive\:"clang_rt.asan_dynamic-i386.lib"
/wholearchive\:"clang_rt.asan_dynamic_runtime_thunk-i386.lib" ;
toolset.flags $(toolset).link FINDLIBS_SA
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>EXE
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>UNIT_TEST
: clang_rt.asan-i386 clang_rt.asan_cxx-i386 ;
toolset.flags $(toolset).link LINKFLAGS
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>EXE
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>UNIT_TEST
: /wholearchive\:"clang_rt.asan-i386.lib"
/wholearchive\:"clang_rt.asan_cxx-i386.lib" ;
toolset.flags $(toolset).link.dll FINDLIBS_SA
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>LIB/<link>shared
: clang_rt.asan_dll_thunk-i386 ;
toolset.flags $(toolset).link.dll LINKFLAGS
$(conditions)/<address-sanitizer>on/<address-model>32/<runtime-link>static/<main-target-type>LIB/<link>shared
: /wholearchive\:"clang_rt.asan_dll_thunk-i386.lib" ;
}
#
# Processor-specific optimization.
#
if [ MATCH "^([67])" : $(version) ]
{
# 8.0 deprecates some of the options.
toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>speed : /Ot ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/<optimization>space : /Os ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ;
# Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
# tests will fail.
toolset.flags $(toolset).compile OPTIONS $(conditions) : /Op ;
# 7.1 and below have single-threaded static RTL.
toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
}
else
{
# 8.0 and above adds some more options.
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : "/favor:blend" ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : "/favor:EM64T" ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : "/favor:AMD64" ;
# 8.0 and above only has multi-threaded static RTL.
toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
toolset.flags $(toolset).compile OPTIONS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
# Specify target machine type so the linker will not need to guess.
toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : "/MACHINE:X64" ;
toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : "/MACHINE:X86" ;
toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : "/MACHINE:IA64" ;
toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : "/MACHINE:ARM" ;
toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm64) : "/MACHINE:ARM64" ;
local conditionx = [ feature.split $(conditions) ] ;
if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 11 ] {
toolset.add-defaults $(conditionx:J=,)\:<embed-manifest-via>linker ;
}
else {
toolset.add-requirements $(conditionx:J=,)\:<embed-manifest-via>mt ;
}
}
toolset.pop-checking-for-flags-module ;
}
# Feature for handling targeting different Windows API sets.
feature.feature windows-api : desktop store phone : propagated composite link-incompatible ;
feature.compose <windows-api>store : <define>WINAPI_FAMILY=WINAPI_FAMILY_APP <define>_WIN32_WINNT=0x0602
<linkflags>/APPCONTAINER ;
feature.compose <windows-api>phone : <define>WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP <define>_WIN32_WINNT=0x0602
<linkflags>/APPCONTAINER <linkflags>"/NODEFAULTLIB:ole32.lib" <linkflags>"/NODEFAULTLIB:kernel32.lib" <linkflags>WindowsPhoneCore.lib ;
feature.set-default windows-api : desktop ;
# Registers this toolset including all of its flags, features & generators. Does
# nothing on repeated calls.
#
rule register-toolset ( )
{
if ! msvc in [ feature.values toolset ]
{
register-toolset-really ;
}
}
rule resolve-possible-msvc-version-alias ( version )
{
if $(.version-alias-$(version))
{
version = $(.version-alias-$(version)) ;
}
return $(version) ;
}
# Declare action for creating static libraries. If library exists, remove it
# before adding files. See
# http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
if [ os.name ] in NT
{
# The 'DEL' command would issue a message to stdout if the file does not
# exist, so need a check.
actions archive
{
if exist "$(<[1])" DEL "$(<[1])"
$(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")
}
}
else
{
actions archive
{
$(.RM) "$(<[1])"
$(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")
}
}
rule compile.asm ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
}
actions compile.asm
{
$(.SETUP) $(.ASM) -D$(ASMDEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) $(.ASM_OUTPUT) "$(<:W)" "$(>:W)"
}
rule compile.c ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TC CFLAGS ;
compile-c-c++ $(<) : $(>) ;
local cc = [ on $(targets[1]) return $(.CC:E="") ] ;
cc = [ regex.escape "$(cc:J= )" : "|()[]\\+.*^$\" " : "\\" ] ;
local eol = [ on $(targets[1]) return $(.CC.FILTER) ] ;
if $(eol)
{
eol = ".*" [ regex.escape "$(eol:J= )" : "|()[]\\+.*^$\" " : "\\" ] ;
}
else
{
eol = "[^\n]*" "" ;
}
COMMAND_DATABASE on $(targets) = "($(cc)$(eol[1]))$(eol[2])" ;
}
rule compile.c.preprocess ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TC CFLAGS ;
preprocess-c-c++ $(<) : $(>) ;
}
rule compile.c.pch ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets[1]) : -TC CFLAGS ;
get-rspline $(targets[2]) : -TC CFLAGS ;
local pch-header = [ on $(<) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<) = $(sources:G=) ;
local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
if $(pch-source)
{
DEPENDS $(<) : $(pch-source) ;
compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
}
else
{
compile-c-c++-pch $(targets) : $(sources) ;
}
}
toolset.flags msvc YLOPTION : "-Yl" ;
# Action for running the C/C++ compiler without using precompiled headers.
#
# WARNING: Synchronize any changes this in action with intel-win
#
# Notes regarding PDB generation, for when we use
# <debug-symbols>on/<debug-store>database:
#
# 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring
# that the /Fd flag is dropped if PDB_CFLAG is empty.
#
# 2. When compiling executables's source files, PDB_NAME is set on a per-source
# file basis by rule compile-c-c++. The linker will pull these into the
# executable's PDB.
#
# 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb
# for each source file by rule archive, as in this case compiler must be used
# to create a single PDB for our library.
#
actions compile-c-c++ bind PDB_NAME PCH_HEADER_AS_SPELLED PCH_FILE
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -c -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -FI"$(PCH_HEADER_AS_SPELLED:T)" -Yu"$(PCH_HEADER_AS_SPELLED:T)" -Fp"$(PCH_FILE:W)" $(CC_RSPLINE)) $(.CC.FILTER)
}
actions preprocess-c-c++ bind PDB_NAME PCH_HEADER_AS_SPELLED PCH_FILE
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -P -Fi"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -FI"$(PCH_HEADER_AS_SPELLED:T)" -Yu"$(PCH_HEADER_AS_SPELLED:T)" -Fp"$(PCH_FILE:W)" $(CC_RSPLINE))
}
rule compile-c-c++ ( targets + : sources * )
{
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
PDB_NAME on $(<) = $(<[1]:S=.pdb) ;
LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
local pch-header = [ on $(<[1]) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<[1]) = $(pch-header:G=) ;
local cc = [ on $(targets[1]) return $(.CC:E="") ] ;
cc = [ regex.escape "$(cc:J= )" : "|()[]\\+.*^$\" " : "\\" ] ;
local eol = [ on $(targets[1]) return $(.CC.FILTER) ] ;
if $(eol)
{
eol = ".*" [ regex.escape "$(eol:J= )" : "|()[]\\+.*^$\" " : "\\" ] ;
}
else
{
eol = "[^\n]*" "" ;
}
COMMAND_DATABASE on $(targets) = "($(cc)$(eol[1]))$(eol[2])" ;
}
rule preprocess-c-c++ ( targets + : sources * )
{
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
PDB_NAME on $(<) = $(<:S=.pdb) ;
LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
local pch-header = [ on $(<[1]) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<[1]) = $(pch-header:G=) ;
}
# Action for running the C/C++ compiler using precompiled headers. In addition
# to whatever else it needs to compile, this action also adds a temporary source
# .cpp file used to compile the precompiled headers themselves.
#
# The global .escaped-double-quote variable is used to avoid messing up Emacs
# syntax highlighting in the messy N-quoted code below.
actions compile-c-c++-pch bind PCH_HEADER_AS_SPELLED
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -Yc"$(PCH_HEADER_AS_SPELLED:T)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) @($(<[1]:W).cpp:<=":>=":E=$(.hash)include $(.escaped-double-quote)$(PCH_HEADER_AS_SPELLED:T)$(.escaped-double-quote)$(.nl)) $(.CC.FILTER)
}
# Action for running the C/C++ compiler using precompiled headers. An already
# built source file for compiling the precompiled headers is expected to be
# given as one of the source parameters.
actions compile-c-c++-pch-s bind PCH_HEADER_AS_SPELLED
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -Yc"$(PCH_HEADER_AS_SPELLED:T)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
}
rule compile.c++ ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TP C++FLAGS ;
compile-c-c++ $(<) : $(>) ;
}
rule compile.c++.preprocess ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TP C++FLAGS ;
preprocess-c-c++ $(<) : $(>) ;
}
rule compile.c++.pch ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets[1]) : -TP C++FLAGS ;
get-rspline $(targets[2]) : -TP C++FLAGS ;
local pch-header = [ on $(<) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<) = $(sources:G=) ;
local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
if $(pch-source)
{
DEPENDS $(<) : $(pch-source) ;
compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
}
else
{
compile-c-c++-pch $(targets) : $(sources) ;
}
}
rule compile.idl ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
}
# See midl.jam for details.
#
actions compile.idl
{
$(.SETUP) $(.IDL) /nologo @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>:W)" -D$(DEFINES) "-I$(INCLUDES:W)" -U$(UNDEFS) $(MIDLFLAGS) /tlb "$(<[1]:W)" /h "$(<[2]:W)" /iid "$(<[3]:W)" /proxy "$(<[4]:W)" /dlldata "$(<[5]:W)")
$(.TOUCH_FILE) "$(<[4]:W)"
$(.TOUCH_FILE) "$(<[5]:W)"
}
rule compile.mc ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
}
actions compile.mc
{
$(.SETUP) $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
}
rule compile.rc ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
}
actions compile.rc
{
$(.SETUP) $(.RC) /nologo -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
}
toolset.uses-features msvc.link : <embed-manifest> <embed-manifest-file> ;
rule link ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
if <embed-manifest>on in $(properties) && <embed-manifest-via>mt in $(properties)
{
if [ feature.get-values <embed-manifest-file> : $(properties) ]
{
DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
msvc.manifest.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
}
else
{
msvc.manifest $(targets) : $(sources) : $(properties) ;
}
}
}
rule link.dll ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
local import-lib ;
if ! <suppress-import-lib>true in $(properties)
{
import-lib = $(targets[2]) ;
IMPORT_LIB on $(targets) = $(import-lib) ;
}
# On msvc-14.1, the linker might not touch the import library
# if the exports do not change. (Apparently this could also
# happen for incremental linking, which is why we disable it,
# but that no longer seems to be enough).
# Therefore, don't update the import library just because
# it's out-dated. It will be force updated, when the dll
# is updated. Also, make it so that anything that depends
# on it depends on the dll as well.
NOUPDATE $(import-lib) ;
INCLUDES $(import-lib) : $(targets[1]) ;
if <embed-manifest>on in $(properties) && <embed-manifest-via>mt in $(properties)
{
if [ feature.get-values <embed-manifest-file> : $(properties) ]
{
DEPENDS $(<) : [ on $(<) return $(EMBED_MANIFEST_FILE) ] ;
msvc.manifest.dll.user $(targets) $(EMBED_MANIFEST_FILE) : $(sources) : $(properties) ;
}
else
{
msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
}
}
}
# Incremental linking a DLL causes no end of problems: if the actual exports do
# not change, the import .lib file is never updated. Therefore, the .lib is
# always out-of-date and gets rebuilt every time. I am not sure that incremental
# linking is such a great idea in general, but in this case I am sure we do not
# want it.
# Windows manifest is a new way to specify dependencies on managed DotNet
# assemblies and Windows native DLLs. The manifests are embedded as resources
# and are useful in any PE target (both DLL and EXE).
OPT_OUT = "/out:" ;
OPT_LIBPATH = "/LIBPATH:" ;
OPT_MANIFESTINPUT = "/MANIFESTINPUT:" ;
OPT_IMPLIB = "/IMPLIB:" ;
OPT_DEF = "/def:" ;
{
actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE MANIFEST_FILE
{
$(.SETUP) $(.LD) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) $(LIBRARIES) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib" $(LINKOPT) $(LINKFLAGS) $(OPT_OUT)"$(<[1]:W)" $(OPT_LIBPATH)"$(LINKPATH:W)" $(OPT_MANIFESTINPUT)"$(MANIFEST_FILE)")
}
actions manifest
{
$(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
}
actions manifest.user bind EMBED_MANIFEST_FILE
{
$(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1"
}
actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE MANIFEST_FILE
{
$(.SETUP) $(.LD) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>)" $(LIBRARIES_MENTIONED_BY_FILE) $(LIBRARIES) "$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" "$(LIBRARY_OPTION)$(FINDLIBS_SA).lib" $(LINKOPT) $(LINKFLAGS) $(OPT_OUT)"$(<[1]:W)" $(OPT_LIBPATH)"$(LINKPATH:W)" $(OPT_MANIFESTINPUT)"$(MANIFEST_FILE)" /DLL $(OPT_IMPLIB)"$(IMPORT_LIB:W)" $(OPT_DEF)"$(DEF_FILE)")
}
actions manifest.dll
{
$(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
}
actions manifest.dll.user bind EMBED_MANIFEST_FILE
{
$(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2"
}
}
# This rule sets up the pdb file that will be used when generating static
# libraries and the debug-store option is database, so that the compiler puts
# all the debug info into a single .pdb file named after the library.
#
# Poking at source targets this way is probably not clean, but it is the
# easiest approach.
#
rule archive ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
PDB_NAME on $(>) = $(<[1]:S=.pdb) ;