mirror of
https://github.com/boostorg/build.git
synced 2026-02-15 00:52:16 +00:00
2125 lines
84 KiB
Plaintext
2125 lines
84 KiB
Plaintext
# 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_1_0.txt or copy at
|
|
# http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
#| tag::doc[]
|
|
|
|
[[bbv2.reference.tools.compiler.msvc]]
|
|
= Microsoft Visual C++
|
|
|
|
The `msvc` module supports the
|
|
http://msdn.microsoft.com/visualc/[Microsoft Visual C++] command-line
|
|
tools on Microsoft Windows. The supported products and versions of
|
|
command line tools are listed below:
|
|
|
|
* 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.
|
|
|
|
[[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 sequence ;
|
|
import set ;
|
|
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." ;
|
|
}
|
|
|
|
# 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 CFLAGS $(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 CFLAGS $(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 CFLAGS $(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 CFLAGS $(conditions) : "/Zc:inline" ;
|
|
|
|
# /Gy analog for variables: https://devblogs.microsoft.com/cppblog/introducing-gw-compiler-switch/
|
|
toolset.flags $(toolset).compile CFLAGS $(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 CFLAGS $(conditions) : "/Zc:throwingNew" ;
|
|
}
|
|
|
|
#
|
|
# Processor-specific optimization.
|
|
#
|
|
|
|
if [ MATCH "^([67])" : $(version) ]
|
|
{
|
|
# 8.0 deprecates some of the options.
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
|
|
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
|
|
toolset.flags $(toolset).compile CFLAGS $(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 CFLAGS $(conditions) : /Op ;
|
|
|
|
# 7.1 and below have single-threaded static RTL.
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
|
|
}
|
|
else
|
|
{
|
|
# 8.0 and above adds some more options.
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : "/favor:blend" ;
|
|
toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : "/favor:EM64T" ;
|
|
toolset.flags $(toolset).compile CFLAGS $(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 CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
|
|
toolset.flags $(toolset).compile CFLAGS $(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" ;
|
|
|
|
if [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 11 ]
|
|
{
|
|
# Make sure that manifest will be generated even if there is no
|
|
# dependencies to put there.
|
|
toolset.flags $(toolset).link LINKFLAGS $(conditions) : /MANIFEST ;
|
|
}
|
|
else
|
|
{
|
|
toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>mt : /MANIFEST ;
|
|
toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>linker/<embed-manifest>off : /MANIFEST ;
|
|
toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>linker/<embed-manifest>on : "/MANIFEST:EMBED" ;
|
|
|
|
local conditionx = [ feature.split $(conditions) ] ;
|
|
toolset.add-defaults $(conditionx:J=,)\:<embed-manifest-via>linker ;
|
|
}
|
|
}
|
|
|
|
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++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
|
|
}
|
|
|
|
|
|
rule compile.c.preprocess ( targets + : sources * : properties * )
|
|
{
|
|
set-setup-command $(targets) : $(properties) ;
|
|
get-rspline $(targets) : -TC CFLAGS ;
|
|
preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
|
|
}
|
|
|
|
|
|
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-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
|
|
{
|
|
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
|
|
}
|
|
|
|
actions preprocess-c-c++ bind PDB_NAME
|
|
{
|
|
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)"
|
|
}
|
|
|
|
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) ] ;
|
|
}
|
|
|
|
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) ] ;
|
|
}
|
|
|
|
# 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
|
|
{
|
|
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) @($(<[1]:W).cpp:<=":>=":E=$(.hash)include $(.escaped-double-quote)$(>[1]:D=)$(.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
|
|
{
|
|
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(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++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
|
|
}
|
|
|
|
rule compile.c++.preprocess ( targets + : sources * : properties * )
|
|
{
|
|
set-setup-command $(targets) : $(properties) ;
|
|
get-rspline $(targets) : -TP C++FLAGS ;
|
|
preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
|
|
}
|
|
|
|
|
|
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-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).
|
|
|
|
{
|
|
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) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" /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) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" /MANIFESTINPUT:"$(MANIFEST_FILE)" /DLL /IMPLIB:"$(IMPORT_LIB:W)" /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) ;
|
|
LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
|
|
}
|
|
|
|
|
|
################################################################################
|
|
#
|
|
# Classes.
|
|
#
|
|
################################################################################
|
|
|
|
class msvc-pch-generator : pch-generator
|
|
{
|
|
import property-set ;
|
|
|
|
rule run-pch ( project name ? : property-set : sources * )
|
|
{
|
|
# Searching for the header and source file in the sources.
|
|
local pch-header ;
|
|
local pch-source ;
|
|
for local s in $(sources)
|
|
{
|
|
if [ type.is-derived [ $(s).type ] H ]
|
|
{
|
|
pch-header = $(s) ;
|
|
}
|
|
else if
|
|
[ type.is-derived [ $(s).type ] CPP ] ||
|
|
[ type.is-derived [ $(s).type ] C ]
|
|
{
|
|
pch-source = $(s) ;
|
|
}
|
|
}
|
|
|
|
if ! $(pch-header)
|
|
{
|
|
import errors : user-error : errors.user-error ;
|
|
errors.user-error "can not build pch without pch-header" ;
|
|
}
|
|
|
|
# If we do not have the PCH source - that is fine. We will just create a
|
|
# temporary .cpp file in the action.
|
|
|
|
local generated = [ generator.run $(project) $(name)
|
|
: [ property-set.create
|
|
# Passing of <pch-source> is a dirty trick, needed because
|
|
# non-composing generators with multiple inputs are subtly
|
|
# broken. For more detailed information see:
|
|
# https://zigzag.cs.msu.su:7813/boost.build/ticket/111
|
|
<pch-source>$(pch-source)
|
|
[ $(property-set).raw ] ]
|
|
: $(pch-header) ] ;
|
|
|
|
local pch-file ;
|
|
for local g in $(generated[2-])
|
|
{
|
|
if [ type.is-derived [ $(g).type ] PCH ]
|
|
{
|
|
pch-file = $(g) ;
|
|
}
|
|
}
|
|
|
|
return [ $(generated[1]).add-raw <pch-header>$(pch-header)
|
|
<pch-file>$(pch-file) ] $(generated[2-]) ;
|
|
}
|
|
}
|
|
|
|
|
|
################################################################################
|
|
#
|
|
# Local rules.
|
|
#
|
|
################################################################################
|
|
|
|
# Detects versions listed as '.known-versions' by checking registry information,
|
|
# environment variables & default paths. Supports both native Windows and
|
|
# Cygwin.
|
|
#
|
|
local rule auto-detect-toolset-versions ( )
|
|
{
|
|
if [ os.name ] in NT CYGWIN
|
|
{
|
|
# Get installation paths from the registry.
|
|
for local i in $(.known-versions)
|
|
{
|
|
if $(.version-$(i)-reg)
|
|
{
|
|
local vc-path ;
|
|
for local x in "" "Wow6432Node\\"
|
|
{
|
|
vc-path += [ W32_GETREG
|
|
"HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
|
|
: "ProductDir" ] ;
|
|
}
|
|
|
|
if $(vc-path)
|
|
{
|
|
vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
|
|
register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check environment and default installation paths.
|
|
for local i in $(.known-versions)
|
|
{
|
|
if ! $(i) in [ $(.versions).all ]
|
|
{
|
|
register-configuration $(i) : [ default-path $(i) ] ;
|
|
}
|
|
}
|
|
}
|
|
|
|
actions write-setup-script
|
|
{
|
|
@($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)"
|
|
}
|
|
|
|
if [ os.name ] = NT
|
|
{
|
|
local rule call-batch-script ( command )
|
|
{
|
|
return "call $(command) >nul$(.nl)" ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# On cygwin, we need to run both the batch script
|
|
# and the following command in the same instance
|
|
# of cmd.exe.
|
|
local rule call-batch-script ( command )
|
|
{
|
|
return "cmd.exe /S /C call $(command) \">nul\" \"&&\" " ;
|
|
}
|
|
}
|
|
|
|
# Local helper rule to create the vcvars setup command for given architecture
|
|
# and options.
|
|
#
|
|
local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup )
|
|
{
|
|
local setup-options ;
|
|
local setup = [ feature.get-values <setup-$(cpu)> : $(options) ] ;
|
|
|
|
if ! $(setup)-is-defined
|
|
{
|
|
if $(global-setup)-is-defined
|
|
{
|
|
setup = $(global-setup) ;
|
|
|
|
# If needed we can easily add using configuration flags
|
|
# here for overriding which options get passed to the
|
|
# global setup command for which target platform:
|
|
# setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ;
|
|
setup-options ?= $(default-global-setup-options) ;
|
|
}
|
|
else
|
|
{
|
|
if [ MATCH "(14.2)" : $(version) ]
|
|
{
|
|
if $(.debug-configuration)
|
|
{
|
|
ECHO "notice: [generate-setup-cmd] $(version) is 14.2" ;
|
|
}
|
|
parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
|
|
}
|
|
else if [ MATCH "(14.1)" : $(version) ]
|
|
{
|
|
if $(.debug-configuration)
|
|
{
|
|
ECHO "notice: [generate-setup-cmd] $(version) is 14.1" ;
|
|
}
|
|
parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
|
|
}
|
|
setup = [ locate-default-setup $(command) : $(parent) : $(default-setup) ] ;
|
|
setup ?= [ path.join $(parent) "vcvarsall.bat" ] ;
|
|
}
|
|
}
|
|
|
|
return $(setup) "$(setup-options:J= )" ;
|
|
}
|
|
|
|
# Worker for set-setup-command. Usable in a virtual-target.action.
|
|
rule adjust-setup-command ( new-setup : setup : properties * )
|
|
{
|
|
local internal = $(new-setup:S=.read) ;
|
|
NOTFILE $(internal) ;
|
|
local setup-options = [ property.select <msvc.setup-options> : $(properties) ] ;
|
|
setup-options = $(setup-options:G=:E=) ;
|
|
DEPENDS $(internal) : $(setup) ;
|
|
DEPENDS $(new-setup) : $(internal) ;
|
|
REBUILDS $(new-setup) : $(internal) ;
|
|
msvc.read-setup $(internal) : $(setup) ;
|
|
msvc.write-setup-script $(new-setup) : $(setup) ;
|
|
__ACTION_RULE__ on $(internal) = msvc.rewrite-setup $(setup) $(setup-options) $(new-setup) ;
|
|
}
|
|
|
|
# This doesn't actually do anything. It's merely
|
|
# used as a trigger for __ACTION_RULE__.
|
|
actions quietly read-setup { }
|
|
|
|
# Calculates the changes to the environment make by setup-script
|
|
# Should be used as a callback for __ACTION_RULE__
|
|
local rule rewrite-setup ( setup-script setup-options new-setup : target : * )
|
|
{
|
|
local setup-path = [ on $(setup-script) return $(LOCATE) $(SEARCH) ] ;
|
|
setup-path = $(setup-path[1]) ;
|
|
local command = "\"$(setup-script:G=:R=$(setup-path))\" $(setup-options)" ;
|
|
local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ;
|
|
local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(command) >nul && set" ] : "\n" ] ;
|
|
local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ;
|
|
if $(diff-vars)
|
|
{
|
|
FILE_CONTENTS on $(new-setup) = "REM $(command)" "SET "$(diff-vars) ;
|
|
}
|
|
}
|
|
|
|
IMPORT msvc : rewrite-setup : : msvc.rewrite-setup ;
|
|
|
|
# Helper rule to generate a faster alternative to MSVC setup scripts.
|
|
# We used to call MSVC setup scripts directly in every action, however in
|
|
# newer MSVC versions (10.0+) they make long-lasting registry queries
|
|
# which have a significant impact on build time.
|
|
local rule set-setup-command ( targets * : properties * )
|
|
{
|
|
if ! [ on $(targets) return $(.SETUP) ]
|
|
{
|
|
local setup-script = [ on $(targets) return $(.SETUP-SCRIPT) ] ;
|
|
# If no setup script was given, then we don't need to do anything.
|
|
if ! $(setup-script)
|
|
{
|
|
return ;
|
|
}
|
|
local setup-options = [ on $(targets) return $(.SETUP-OPTIONS) ] ;
|
|
local key = .setup-command-$(setup-script:E=)-$(setup-options:E=) ;
|
|
if ! $($(key))
|
|
{
|
|
properties = [ feature.expand $(properties) ] ;
|
|
properties = [ property.select <toolset> <toolset-msvc:version> <architecture> <address-model> <windows-api> <relevant> : $(properties) ] ;
|
|
local ps = [ property-set.create $(properties) <msvc.setup-options>$(setup-options) ] ;
|
|
local original = [ virtual-target.from-file $(setup-script) : [ path.pwd ] : $(.project) ] ;
|
|
local action = [ new non-scanning-action $(original) : msvc.adjust-setup-command : $(ps) ] ;
|
|
local new-setup = [ virtual-target.register [ new file-target msvc-setup.bat exact : : $(.project) : $(action) ] ] ;
|
|
local command = [ $(new-setup).actualize ] ;
|
|
local path = [ on $(command) return $(LOCATE) ] ;
|
|
local block-update = $(command:S=.nup) ;
|
|
NOUPDATE $(block-update) ;
|
|
NOTFILE $(block-update) ;
|
|
DEPENDS $(block-update) : $(command) ;
|
|
if [ on $(targets) return $(.REWRITE-SETUP) ]
|
|
{
|
|
ALWAYS $(command) ;
|
|
}
|
|
$(key) = [ call-batch-script "\"$(command:WG=:R=$(path))\" $(setup-options:E=)" ] $(block-update) ;
|
|
}
|
|
DEPENDS $(targets) : $($(key)[2]) ;
|
|
.SETUP on $(targets) = $($(key)[1]) ;
|
|
}
|
|
}
|
|
|
|
# Worker rule for toolset version configuration. Takes an explicit version id or
|
|
# nothing in case it should configure the default toolset version (the first
|
|
# registered one or a new 'default' one in case no toolset versions have been
|
|
# registered yet).
|
|
#
|
|
local rule configure-really ( version ? : options * )
|
|
{
|
|
local command = [ feature.get-values <command> : $(options) ] ;
|
|
|
|
if ! $(version) && ! $(command)
|
|
{
|
|
# We were given neither a command, nor a version.
|
|
# Take the best registered (i.e. auto-detected) version.
|
|
# FIXME: consider whether an explicitly specified setup script
|
|
# should disable this logic. We already won't get here if
|
|
# there is a user specified command.
|
|
version = [ $(.versions).all ] ;
|
|
for local known in $(.known-versions)
|
|
{
|
|
if $(known) in $(version)
|
|
{
|
|
version = $(known) ;
|
|
break ;
|
|
}
|
|
}
|
|
# version might still have multiple elements if no versions
|
|
# were auto-detected, but an unknown version was configured
|
|
# manually.
|
|
version = $(version[1]) ;
|
|
}
|
|
|
|
# Handle a user-provided command, and deduce the version if necessary.
|
|
# If the user-requested version was not autodetected and no command
|
|
# was given, attempt to find it in PATH
|
|
if $(command) || ! ( $(version:E=default) in [ $(.versions).all ] )
|
|
{
|
|
local found-command = [ common.get-invocation-command-nodefault msvc : cl.exe : $(command) ] ;
|
|
|
|
if $(found-command)
|
|
{
|
|
command = $(found-command) ;
|
|
if ! $(command:D)
|
|
{
|
|
local path = [ common.get-absolute-tool-path $(command) ] ;
|
|
command = $(command:R=$(path)) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# If we still failed to find cl.exe, bail out.
|
|
ECHO ;
|
|
ECHO warning\:
|
|
"Did not find command for MSVC toolset."
|
|
"If you have Visual Studio 2017 installed you will need to"
|
|
"specify the full path to the command,"
|
|
"set VS150COMNTOOLS for your installation,"
|
|
"or"
|
|
"build from the 'Visual Studio Command Prompt for VS 2017'."
|
|
;
|
|
ECHO ;
|
|
command ?= cl.exe ;
|
|
}
|
|
|
|
if ! $(version)
|
|
{
|
|
# Even if version is not explicitly specified, try to detect the
|
|
# version from the path.
|
|
# FIXME: We currently detect both Microsoft Visual Studio 9.0 and
|
|
# 9.0express as 9.0 here.
|
|
if [ MATCH "(MSVC\\\\14.2)" : $(command) ]
|
|
{
|
|
version = 14.2 ;
|
|
}
|
|
else if [ MATCH "(MSVC\\\\14.1)" : $(command) ]
|
|
{
|
|
version = 14.1 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual Studio 14)" : $(command) ]
|
|
{
|
|
version = 14.0 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual Studio 12)" : $(command) ]
|
|
{
|
|
version = 12.0 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
|
|
{
|
|
version = 11.0 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
|
|
{
|
|
version = 10.0 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
|
|
{
|
|
version = 9.0 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
|
|
{
|
|
version = 8.0 ;
|
|
}
|
|
else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
|
|
{
|
|
version = 7.1 ;
|
|
}
|
|
else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
|
|
$(command) ]
|
|
{
|
|
version = 7.1toolkit ;
|
|
}
|
|
else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
|
|
{
|
|
version = 7.0 ;
|
|
}
|
|
else
|
|
{
|
|
version = 6.0 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Version alias -> real version number.
|
|
version = [ resolve-possible-msvc-version-alias $(version) ] ;
|
|
|
|
# Check whether the selected configuration is already in use.
|
|
if $(version) in [ $(.versions).used ]
|
|
{
|
|
# Allow multiple 'toolset.using' calls for the same configuration if the
|
|
# identical sets of options are used.
|
|
if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
|
|
{
|
|
import errors ;
|
|
errors.user-error "MSVC toolset configuration: Toolset version"
|
|
"'$(version)' already configured." ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Register a new configuration.
|
|
$(.versions).register $(version) ;
|
|
$(.versions).set $(version) : options : $(options) ;
|
|
|
|
# Mark the configuration as 'used'.
|
|
$(.versions).use $(version) ;
|
|
|
|
# Generate conditions and save them.
|
|
local conditions = [ common.check-init-parameters msvc : version $(version) ] ;
|
|
|
|
$(.versions).set $(version) : conditions : $(conditions) ;
|
|
|
|
command ?= [ $(.versions).get $(version) : default-command ] ;
|
|
|
|
# For 14.1+ we need the exact version as MS is planning rolling updates
|
|
# that will cause our `setup-cmd` to become invalid
|
|
exact-version = [ MATCH "(14\.[1-9][0-9]\.[0-9\.]+)" : $(command) ] ;
|
|
|
|
common.handle-options msvc : $(conditions) : $(command) : $(options) ;
|
|
|
|
# Generate and register setup command.
|
|
|
|
local below-8.0 = [ MATCH "^([67]\\.)" : $(version) ] ;
|
|
local below-11.0 = [ MATCH "^([6789]\\.|10\\.)" : $(version) ] ;
|
|
|
|
local cpu = i386 amd64 ia64 arm arm64 ;
|
|
if $(below-8.0)
|
|
{
|
|
cpu = i386 ;
|
|
}
|
|
else if $(below-11.0)
|
|
{
|
|
cpu = i386 amd64 ia64 ;
|
|
}
|
|
|
|
local setup-amd64 ;
|
|
local setup-i386 ;
|
|
local setup-ia64 ;
|
|
local setup-arm ;
|
|
local setup-arm64 ;
|
|
local setup-phone-i386 ;
|
|
local setup-phone-arm ;
|
|
|
|
if $(command)
|
|
{
|
|
# TODO: Note that if we specify a non-existant toolset version then
|
|
# this rule may find and use a corresponding compiler executable
|
|
# belonging to an incorrect toolset version. For example, if you
|
|
# have only MSVC 7.1 installed, have its executable on the path and
|
|
# specify you want Boost Build to use MSVC 9.0, then you want Boost
|
|
# Build to report an error but this may cause it to silently use the
|
|
# MSVC 7.1 compiler even though it thinks it is using the msvc-9.0
|
|
# toolset version.
|
|
command = [ common.get-absolute-tool-path $(command[-1]) ] ;
|
|
}
|
|
|
|
if $(command)
|
|
{
|
|
local parent = [ path.make $(command) ] ;
|
|
parent = [ path.parent $(parent) ] ;
|
|
parent = [ path.native $(parent) ] ;
|
|
|
|
# Setup will be used if the command name has been specified. If
|
|
# setup is not specified explicitly then a default setup script will
|
|
# be used instead. Setup scripts may be global or architecture/
|
|
# /platform/cpu specific. Setup options are used only in case of
|
|
# global setup scripts.
|
|
|
|
# Default setup scripts provided with different VC distributions:
|
|
#
|
|
# VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
|
|
# builds. It was located in the bin folder for the regular version
|
|
# and in the root folder for the free VC 7.1 tools.
|
|
#
|
|
# Later 8.0 & 9.0 versions introduce separate platform specific
|
|
# vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
|
|
# located in or under the bin folder. Most also include a global
|
|
# vcvarsall.bat helper script located in the root folder which runs
|
|
# one of the aforementioned vcvars*.bat scripts based on the options
|
|
# passed to it. So far only the version coming with some PlatformSDK
|
|
# distributions does not include this top level script but to
|
|
# support those we need to fall back to using the worker scripts
|
|
# directly in case the top level script can not be found.
|
|
|
|
local global-setup = [ feature.get-values <setup> : $(options) ] ;
|
|
global-setup = $(global-setup[1]) ;
|
|
local global-setup-phone = $(global-setup) ;
|
|
if ! $(below-8.0)
|
|
{
|
|
global-setup ?= [ locate-default-setup $(command) : $(parent) :
|
|
vcvarsall.bat ] ;
|
|
}
|
|
|
|
local default-setup-amd64 = vcvarsx86_amd64.bat ;
|
|
local default-setup-i386 = vcvars32.bat ;
|
|
local default-setup-ia64 = vcvarsx86_ia64.bat ;
|
|
local default-setup-arm = vcvarsx86_arm.bat ;
|
|
local default-setup-arm64 = vcvarsx86_arm64.bat ;
|
|
local default-setup-phone-i386 = vcvarsphonex86.bat ;
|
|
local default-setup-phone-arm = vcvarsphonex86_arm.bat ;
|
|
|
|
# http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
|
|
# http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
|
|
# mention an x86_IPF option, that seems to be a documentation bug
|
|
# and x86_ia64 is the correct option.
|
|
local default-global-setup-options-amd64 = x86_amd64 ;
|
|
local default-global-setup-options-i386 = x86 ;
|
|
local default-global-setup-options-ia64 = x86_ia64 ;
|
|
local default-global-setup-options-arm = x86_arm ;
|
|
local default-global-setup-options-arm64 = x86_arm64 ;
|
|
|
|
# When using 64-bit Windows, and targeting 64-bit, it is possible to
|
|
# use a native 64-bit compiler, selected by the "amd64" & "ia64"
|
|
# parameters to vcvarsall.bat. There are two variables we can use --
|
|
# PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
|
|
# 'x86' when running 32-bit Windows, no matter which processor is
|
|
# used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
|
|
# Windows.
|
|
#
|
|
if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
|
|
{
|
|
default-global-setup-options-amd64 = amd64 ;
|
|
}
|
|
# When B2 itself is running as a 32-bit process on 64-bit
|
|
# Windows, the above test will fail (since WOW64 simulates a 32-bit
|
|
# environment, including environment values). So check the WOW64
|
|
# variable PROCESSOR_ARCHITEW6432 as well.
|
|
if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITEW6432 ] ]
|
|
{
|
|
default-global-setup-options-amd64 = amd64 ;
|
|
}
|
|
# TODO: The same 'native compiler usage' should be implemented for
|
|
# the Itanium platform by using the "ia64" parameter. For this
|
|
# though we need someone with access to this platform who can find
|
|
# out how to correctly detect this case.
|
|
else if $(somehow-detect-the-itanium-platform)
|
|
{
|
|
default-global-setup-options-ia64 = ia64 ;
|
|
}
|
|
|
|
for local c in $(cpu)
|
|
{
|
|
exact-version ?= $(version) ;
|
|
setup-$(c) = [ generate-setup-cmd $(exact-version) : $(command) : $(parent) : $(options) : $(c) : $(global-setup) : $(default-global-setup-options-$(c)) : $(default-setup-$(c)) ] ;
|
|
}
|
|
|
|
# Windows phone has different setup scripts, located in a different directory hierarchy.
|
|
# The 11.0 toolset can target Windows Phone 8.0 and the 12.0 toolset can target Windows Phone 8.1,
|
|
# each of which have a different directory for their vcvars setup scripts.
|
|
local phone-parent = [ path.native [ path.join $(parent) WPSDK ] ] ;
|
|
local phone-directory = $(phone-parent) ;
|
|
if [ MATCH "(11.0)" : $(version) ]
|
|
{
|
|
phone-directory = [ path.native [ path.join $(phone-directory) WP80 ] ] ;
|
|
}
|
|
else if [ MATCH "(12.0)" : $(version) ]
|
|
{
|
|
phone-directory = [ path.native [ path.join $(phone-directory) WP81 ] ] ;
|
|
}
|
|
global-setup-phone ?= [ locate-default-setup $(phone-directory) : $(phone-parent) : vcvarsphoneall.bat ] ;
|
|
|
|
# If can't locate default phone setup script then this VS version doesn't support Windows Phone.
|
|
if $(global-setup-phone)-is-defined
|
|
{
|
|
# i386 CPU is for the Windows Phone emulator in Visual Studio.
|
|
local phone-cpu = i386 arm ;
|
|
for local c in $(phone-cpu)
|
|
{
|
|
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)) ] ;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Get tool names (if any) and finish setup.
|
|
|
|
compiler = [ feature.get-values <compiler> : $(options) ] ;
|
|
compiler ?= cl ;
|
|
|
|
linker = [ feature.get-values <linker> : $(options) ] ;
|
|
linker ?= link ;
|
|
|
|
resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
|
|
resource-compiler ?= rc ;
|
|
|
|
# Turn on some options for i386 assembler
|
|
# -coff generate COFF format object file (compatible with cl.exe output)
|
|
local default-assembler-amd64 = ml64 ;
|
|
local default-assembler-i386 = "ml -coff" ;
|
|
local default-assembler-ia64 = ias ;
|
|
local default-assembler-arm = armasm ;
|
|
local default-assembler-arm64 = armasm64 ;
|
|
|
|
# For the assembler the following options are turned on by default:
|
|
#
|
|
# -Zp4 align structures to 4 bytes
|
|
# -Cp preserve case of user identifiers
|
|
# -Cx preserve case in publics, externs
|
|
#
|
|
local assembler-flags-amd64 = "-c -Zp4 -Cp -Cx" ;
|
|
local assembler-flags-i386 = "-c -Zp4 -Cp -Cx" ;
|
|
local assembler-flags-ia64 = "-c -Zp4 -Cp -Cx" ;
|
|
local assembler-flags-arm = "" ;
|
|
local assembler-flags-arm64 = "" ;
|
|
|
|
local assembler-output-flag-amd64 = -Fo ;
|
|
local assembler-output-flag-i386 = -Fo ;
|
|
local assembler-output-flag-ia64 = -Fo ;
|
|
local assembler-output-flag-arm = -o ;
|
|
local assembler-output-flag-arm64 = -o ;
|
|
|
|
assembler = [ feature.get-values <assembler> : $(options) ] ;
|
|
|
|
idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
|
|
idl-compiler ?= midl ;
|
|
|
|
mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
|
|
mc-compiler ?= mc ;
|
|
|
|
manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
|
|
manifest-tool ?= mt ;
|
|
|
|
local cc-filter = [ feature.get-values <compiler-filter> : $(options) ]
|
|
;
|
|
|
|
for local c in $(cpu)
|
|
{
|
|
# Setup script is not required in some configurations.
|
|
setup-$(c) ?= "" ;
|
|
|
|
local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
|
|
|
|
if $(.debug-configuration)
|
|
{
|
|
for local cpu-condition in $(cpu-conditions)
|
|
{
|
|
ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c):J= )'" ;
|
|
}
|
|
}
|
|
|
|
local cpu-assembler = $(assembler) ;
|
|
cpu-assembler ?= $(default-assembler-$(c)) ;
|
|
local assembler-flags = $(assembler-flags-$(c)) ;
|
|
local assembler-output-flag = $(assembler-output-flag-$(c)) ;
|
|
|
|
for local api in desktop store phone
|
|
{
|
|
local setup-script = $(setup-$(c)) ;
|
|
if $(api) = phone
|
|
{
|
|
setup-script = $(setup-phone-$(c)) ;
|
|
}
|
|
|
|
if <rewrite-setup-scripts>always in $(options)
|
|
{
|
|
toolset.flags msvc .REWRITE-SETUP <windows-api>$(api)/$(cpu-conditions) : true ;
|
|
}
|
|
|
|
if ! $(setup-script)
|
|
{
|
|
# Should we try to set up some error handling or fallbacks here?
|
|
}
|
|
else if <rewrite-setup-scripts>off in $(options) || [ os.name ] != NT
|
|
{
|
|
toolset.flags msvc .SETUP <windows-api>$(api)/$(cpu-conditions) : [ call-batch-script "\"$(setup-script[1]:W)\" $(setup-script[2-]:E=)" ] ;
|
|
}
|
|
else
|
|
{
|
|
toolset.flags msvc .SETUP-SCRIPT <windows-api>$(api)/$(cpu-conditions) : $(setup-script[1]) ;
|
|
toolset.flags msvc .SETUP-OPTIONS <windows-api>$(api)/$(cpu-conditions) : $(setup-script[2-]) ;
|
|
}
|
|
|
|
toolset.flags msvc.compile .RC <windows-api>$(api)/$(cpu-conditions) : $(resource-compiler) ;
|
|
toolset.flags msvc.compile .IDL <windows-api>$(api)/$(cpu-conditions) : $(idl-compiler) ;
|
|
toolset.flags msvc.compile .MC <windows-api>$(api)/$(cpu-conditions) : $(mc-compiler) ;
|
|
toolset.flags msvc.link .MT <windows-api>$(api)/$(cpu-conditions) : $(manifest-tool) -nologo ;
|
|
|
|
if $(api) = desktop
|
|
{
|
|
toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 -nologo ;
|
|
}
|
|
else
|
|
{
|
|
toolset.flags msvc.compile .CC <windows-api>$(api)/$(cpu-conditions) : $(compiler) /Zm800 /ZW /EHsc -nologo ;
|
|
}
|
|
toolset.flags msvc.compile .ASM <windows-api>$(api)/$(cpu-conditions) : $(cpu-assembler) $(assembler-flags) -nologo ;
|
|
toolset.flags msvc.compile .ASM_OUTPUT <windows-api>$(api)/$(cpu-conditions) : $(assembler-output-flag) ;
|
|
toolset.flags msvc.link .LD <windows-api>$(api)/$(cpu-conditions) : $(linker) /NOLOGO "/INCREMENTAL:NO" ;
|
|
toolset.flags msvc.archive .LD <windows-api>$(api)/$(cpu-conditions) : $(linker) /lib /NOLOGO ;
|
|
}
|
|
|
|
if $(cc-filter)
|
|
{
|
|
toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
|
|
}
|
|
}
|
|
|
|
# Starting with Visual Studio 2013 the CRT is split into a desktop and app dll.
|
|
# If targeting WinRT and 12.0 set lib path to link against app CRT.
|
|
if [ MATCH "(12)" : $(version) ]
|
|
{
|
|
local storeLibPath = [ path.join $(parent) "lib/store" ] ;
|
|
toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-i386) : [ path.native $(storeLibPath) ] ;
|
|
toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-amd64) : [ path.native [ path.join $(storeLibPath) "amd64" ] ] ;
|
|
toolset.flags msvc.link LINKPATH $(conditions)/<windows-api>store/$(.cpu-arch-arm) : [ path.native [ path.join $(storeLibPath) "arm" ] ] ;
|
|
}
|
|
|
|
# LTO
|
|
toolset.flags msvc.compile OPTIONS $(conditions)/<lto>on : /GL ;
|
|
toolset.flags msvc.link LINKFLAGS $(conditions)/<lto>on : /LTCG ;
|
|
|
|
# Set version-specific flags.
|
|
configure-version-specific msvc : $(version) : $(conditions) ;
|
|
}
|
|
}
|
|
|
|
|
|
# Returns the default installation path for the given version.
|
|
#
|
|
local rule default-path ( version )
|
|
{
|
|
local result ;
|
|
{
|
|
# try to use vswhere
|
|
local pseudo_env_VSCOMNTOOLS ;
|
|
local all-env-paths ;
|
|
local root = [ os.environ "ProgramFiles(x86)" ] ;
|
|
if ( ! $(root) )
|
|
{
|
|
root = [ os.environ "ProgramFiles" ] ;
|
|
}
|
|
if ( ! $(root) ) && [ os.name ] in CYGWIN
|
|
{
|
|
# We probably are in an 'env -i' Cygwin session, where the user
|
|
# was unable restore the "ProgramFiles(x86)" environment variable,
|
|
# because it is an invalid environment variable name in Cygwin.
|
|
# However, we can try to query cygpath instead.
|
|
root = [ SHELL "cygpath -w -F 42" : strip-eol ] ; # CSIDL_PROGRAM_FILESX86
|
|
if ( ! $(root) )
|
|
{
|
|
root = [ SHELL "cygpath -w -F 38" : strip-eol ] ; # CSIDL_PROGRAM_FILES
|
|
}
|
|
}
|
|
# When we are a Cygwin build, [ SHELL ] does execute using "/bin/sh -c".
|
|
# When /bin/sh does find a forward slash, no PATH search is performed,
|
|
# causing [ SHELL "C:\\...\\Installer/vswhere.exe" ] to succeed.
|
|
# And fortunately, forward slashes do also work in native Windows.
|
|
local vswhere = "$(root)/Microsoft Visual Studio/Installer/vswhere.exe" ;
|
|
# The check for $(root) is to avoid a segmentation fault if not found.
|
|
if $(version) in 14.1 14.2 default && $(root) && [ path.exists $(vswhere) ]
|
|
{
|
|
local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
|
|
local prop = "-property installationPath" ;
|
|
local limit ;
|
|
|
|
if $(version) = 14.2 || $(version) = "default"
|
|
{
|
|
limit = "-version \"[16.0,17.0)\"" ;
|
|
}
|
|
else if $(version) = 14.1
|
|
{
|
|
limit = "-version \"[15.0,16.0)\"" ;
|
|
}
|
|
|
|
# Quoting the "*" is for when we are a Cygwin build, to bypass /bin/sh.
|
|
local vswhere_cmd = "\"$(vswhere)\" -latest -products \"*\" $(req) $(prop) $(limit)" ;
|
|
# The split character "\r" is for when we are a Cygwin build.
|
|
local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vswhere_cmd) ] : "\r\n" ] ;
|
|
pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
|
|
if ! [ path.exists $(pseudo_env_VSCOMNTOOLS) ]
|
|
{
|
|
return ; # Not found. If we have vswhere, assume that it works.
|
|
}
|
|
all-env-paths = $(pseudo_env_VSCOMNTOOLS) ;
|
|
}
|
|
else
|
|
{
|
|
all-env-paths = [ sequence.transform os.environ
|
|
: $(.version-$(version)-env) ] ;
|
|
}
|
|
|
|
# Check environment or previous path_VS150
|
|
for local env-path in $(all-env-paths)
|
|
{
|
|
if $(env-path) && $(.version-$(version)-path)
|
|
{
|
|
for local bin-path in $(.version-$(version)-path)
|
|
{
|
|
result = [ path.glob [ path.make $(env-path) ] : $(bin-path) ] ;
|
|
if $(result)
|
|
{
|
|
result = [ path.native $(result[1]) ] ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
if $(result)
|
|
{
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $(result) ;
|
|
}
|
|
|
|
|
|
|
|
rule get-rspline ( target : lang-opt lang-flags )
|
|
{
|
|
CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
|
|
$($(lang-flags)) $(OPTIONS) -c -D$(DEFINES)
|
|
\"-I$(INCLUDES:W)\" \"-FI$(FORCE_INCLUDES:W)\" ] ;
|
|
}
|
|
|
|
class msvc-linking-generator : linking-generator
|
|
{
|
|
# Calls the base version. If necessary, also create a target for the
|
|
# manifest file.specifying source's name as the name of the created
|
|
# target. As result, the PCH will be named whatever.hpp.gch, and not
|
|
# whatever.gch.
|
|
rule generated-targets ( sources + : property-set : project name ? )
|
|
{
|
|
local result = [ linking-generator.generated-targets $(sources)
|
|
: $(property-set) : $(project) $(name) ] ;
|
|
|
|
if $(result)
|
|
{
|
|
local name-main = [ $(result[1]).name ] ;
|
|
local action = [ $(result[1]).action ] ;
|
|
|
|
if [ $(property-set).get <debug-symbols> ] = "on"
|
|
{
|
|
# We force the exact name on PDB. The reason is tagging -- the
|
|
# tag rule may reasonably special case some target types, like
|
|
# SHARED_LIB. The tag rule will not catch PDBs, and it cannot
|
|
# even easily figure out if a PDB is paired with a SHARED_LIB,
|
|
# EXE or something else. Because PDBs always get the same name
|
|
# as the main target, with .pdb as extension, just force it.
|
|
local target = [ class.new file-target $(name-main:S=.pdb) exact
|
|
: PDB : $(project) : $(action) ] ;
|
|
local registered-target = [ virtual-target.register $(target) ]
|
|
;
|
|
if $(target) != $(registered-target)
|
|
{
|
|
$(action).replace-targets $(target) : $(registered-target) ;
|
|
}
|
|
result += $(registered-target) ;
|
|
}
|
|
|
|
if [ $(property-set).get <embed-manifest> ] = "off"
|
|
{
|
|
# Manifest is an evil target. It has .manifest appened to the
|
|
# name of the main target, including extension, e.g.
|
|
# a.exe.manifest. We use the 'exact' name to achieve this
|
|
# effect.
|
|
local target = [ class.new file-target $(name-main).manifest
|
|
exact : MANIFEST : $(project) : $(action) ] ;
|
|
local registered-target = [ virtual-target.register $(target) ]
|
|
;
|
|
if $(target) != $(registered-target)
|
|
{
|
|
$(action).replace-targets $(target) : $(registered-target) ;
|
|
}
|
|
result += $(registered-target) ;
|
|
}
|
|
}
|
|
return $(result) ;
|
|
}
|
|
}
|
|
|
|
|
|
# Unsafe worker rule for the register-toolset() rule. Must not be called
|
|
# multiple times.
|
|
#
|
|
local rule register-toolset-really ( )
|
|
{
|
|
feature.extend toolset : msvc ;
|
|
|
|
# Intel and msvc supposedly have link-compatible objects.
|
|
feature.subfeature toolset msvc : vendor : intel : propagated optional ;
|
|
|
|
# Inherit MIDL flags.
|
|
toolset.inherit-flags msvc : midl ;
|
|
|
|
# Inherit MC flags.
|
|
toolset.inherit-flags msvc : mc ;
|
|
|
|
# Dynamic runtime comes only in MT flavour.
|
|
toolset.add-requirements
|
|
<toolset>msvc,<runtime-link>shared:<threading>multi ;
|
|
|
|
# Declare msvc toolset specific features.
|
|
{
|
|
feature.feature debug-store : object database : propagated ;
|
|
feature.feature pch-source : : dependency free ;
|
|
}
|
|
|
|
# Declare generators.
|
|
{
|
|
# TODO: Is it possible to combine these? Make the generators
|
|
# non-composing so that they do not convert each source into a separate
|
|
# .rsp file.
|
|
generators.register [ new msvc-linking-generator msvc.link :
|
|
OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ;
|
|
generators.register [ new msvc-linking-generator msvc.link.dll :
|
|
OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB :
|
|
<toolset>msvc <suppress-import-lib>false ] ;
|
|
generators.register [ new msvc-linking-generator msvc.link.dll :
|
|
OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB :
|
|
<toolset>msvc <suppress-import-lib>true ] ;
|
|
|
|
generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
|
|
generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
|
|
generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
|
|
generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
|
|
generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
|
|
|
|
# Using 'register-c-compiler' adds the build directory to INCLUDES.
|
|
generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
|
|
generators.override msvc.compile.rc : rc.compile.resource ;
|
|
generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
|
|
|
|
generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
|
|
generators.override msvc.compile.idl : midl.compile.idl ;
|
|
|
|
generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
|
|
generators.override msvc.compile.mc : mc.compile ;
|
|
|
|
# Note: the 'H' source type will catch both '.h' and '.hpp' headers as
|
|
# the latter have their HPP type derived from H. The type of compilation
|
|
# is determined entirely by the destination type.
|
|
generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
|
|
generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
|
|
|
|
generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
|
|
generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
|
|
}
|
|
|
|
toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
|
|
toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
|
|
toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
|
|
|
|
#
|
|
# Declare flags for compilation.
|
|
#
|
|
|
|
toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ;
|
|
toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ;
|
|
|
|
toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
|
|
toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
|
|
|
|
toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
|
|
toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
|
|
toolset.flags msvc.compile CFLAGS <optimization>off : /Od ;
|
|
toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
|
|
toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
|
|
toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
|
|
|
|
toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ;
|
|
toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ;
|
|
toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ;
|
|
toolset.flags msvc.compile CFLAGS <warnings>extra : /W4 ;
|
|
toolset.flags msvc.compile CFLAGS <warnings>pedantic : /W4 ;
|
|
toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
|
|
|
|
toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
|
|
toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
|
|
toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
|
|
toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
|
|
|
|
toolset.flags msvc.compile C++FLAGS <cxxstd>14 : "/std:c++14" ;
|
|
toolset.flags msvc.compile C++FLAGS <cxxstd>17 : "/std:c++17" ;
|
|
toolset.flags msvc.compile C++FLAGS <cxxstd>latest : "/std:c++latest" ;
|
|
|
|
# By default 8.0 enables rtti support while prior versions disabled it. We
|
|
# simply enable or disable it explicitly so we do not have to depend on this
|
|
# default behaviour.
|
|
toolset.flags msvc.compile CFLAGS <rtti>on : /GR ;
|
|
toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ;
|
|
toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
|
|
toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
|
|
|
|
toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
|
|
toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
|
|
|
|
toolset.flags msvc.compile CFLAGS <cflags> : ;
|
|
toolset.flags msvc.compile.c++ C++FLAGS <cxxflags> : ;
|
|
|
|
toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
|
|
|
|
toolset.flags msvc.compile DEFINES <define> ;
|
|
toolset.flags msvc.compile UNDEFS <undef> ;
|
|
toolset.flags msvc.compile INCLUDES <include> ;
|
|
toolset.flags msvc.compile FORCE_INCLUDES <force-include> ;
|
|
|
|
# Declare flags for the assembler.
|
|
toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
|
|
|
|
toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<debug-symbols>on : "/Zi /Zd" ;
|
|
|
|
toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>on : /W3 ;
|
|
toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>off : /W0 ;
|
|
toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>all : /W4 ;
|
|
toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings-as-errors>on : /WX ;
|
|
|
|
toolset.flags msvc.compile.asm ASMDEFINES <architecture>x86 : <define> ;
|
|
|
|
# Declare flags for linking.
|
|
{
|
|
toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : "/PDB:" ; # not used yet
|
|
toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
|
|
toolset.flags msvc.link DEF_FILE <def-file> ;
|
|
toolset.flags msvc.link MANIFEST_FILE <embed-manifest-via>linker : <embed-manifest-file> ;
|
|
|
|
# The linker disables the default optimizations when using /DEBUG so we
|
|
# have to enable them manually for release builds with debug symbols.
|
|
toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : "/OPT:REF,ICF" ;
|
|
|
|
toolset.flags msvc LINKFLAGS <user-interface>console : "/subsystem:console" ;
|
|
toolset.flags msvc LINKFLAGS <user-interface>gui : "/subsystem:windows" ;
|
|
toolset.flags msvc LINKFLAGS <user-interface>wince : "/subsystem:windowsce" ;
|
|
toolset.flags msvc LINKFLAGS <user-interface>native : "/subsystem:native" ;
|
|
toolset.flags msvc LINKFLAGS <user-interface>auto : "/subsystem:posix" ;
|
|
|
|
toolset.flags msvc.link LINKFLAGS <linkflags> ;
|
|
toolset.flags msvc.link LINKPATH <library-path> ;
|
|
|
|
toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
|
|
toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
|
|
toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
|
|
toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
|
|
|
|
toolset.flags msvc.link.dll LINKFLAGS <suppress-import-lib>true : /NOENTRY ;
|
|
}
|
|
|
|
toolset.flags msvc.archive AROPTIONS <archiveflags> ;
|
|
|
|
# Enable response file control
|
|
toolset.flags msvc RESPONSE_FILE_SUB <response-file>auto : a ;
|
|
toolset.flags msvc RESPONSE_FILE_SUB <response-file>file : f ;
|
|
toolset.flags msvc RESPONSE_FILE_SUB <response-file>contents : c ;
|
|
|
|
# Create a project to allow building the setup scripts
|
|
project.initialize $(__name__) ;
|
|
.project = [ project.current ] ;
|
|
project msvc ;
|
|
|
|
feature.feature msvc.setup-options : : free ;
|
|
}
|
|
|
|
|
|
# Locates the requested setup script under the given folder and returns its full
|
|
# path or nothing in case the script can not be found. In case multiple scripts
|
|
# are found only the first one is returned.
|
|
#
|
|
# TODO: There used to exist a code comment for the msvc.init rule stating that
|
|
# we do not correctly detect the location of the vcvars32.bat setup script for
|
|
# the free VC7.1 tools in case user explicitly provides a path. This should be
|
|
# tested or simply remove this whole comment in case this toolset version is no
|
|
# longer important.
|
|
#
|
|
local rule locate-default-setup ( command : parent : setup-name )
|
|
{
|
|
local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
|
|
if $(result[1])
|
|
{
|
|
return $(result[1]) ;
|
|
}
|
|
}
|
|
|
|
|
|
# Validates given path, registers found configuration and prints debug
|
|
# information about it.
|
|
#
|
|
local rule register-configuration ( version : path ? )
|
|
{
|
|
if $(path)
|
|
{
|
|
local command = [ GLOB $(path) : cl.exe ] ;
|
|
|
|
if $(command)
|
|
{
|
|
if $(.debug-configuration)
|
|
{
|
|
ECHO notice\: "[msvc-cfg]" msvc-$(version) detected, command\:
|
|
'$(command)' ;
|
|
}
|
|
|
|
$(.versions).register $(version) ;
|
|
$(.versions).set $(version) : default-command : $(command) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
################################################################################
|
|
#
|
|
# Startup code executed when loading this module.
|
|
#
|
|
################################################################################
|
|
|
|
if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
|
|
{
|
|
.debug-configuration = true ;
|
|
}
|
|
|
|
# Miscellaneous constants.
|
|
.RM = [ common.rm-command ] ;
|
|
.nl = "
|
|
" ;
|
|
_ = " " ;
|
|
.ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
|
|
.escaped-double-quote = "\"" ;
|
|
.hash = "\#" ;
|
|
.TOUCH_FILE = [ common.file-touch-command ] ;
|
|
|
|
# List of all registered configurations.
|
|
.versions = [ new configurations ] ;
|
|
|
|
# Supported CPU architectures.
|
|
.cpu-arch-info-i386 = x86 32 ;
|
|
.cpu-arch-info-amd64 = x86 64 ;
|
|
.cpu-arch-info-ia64 = ia64 64 ;
|
|
.cpu-arch-info-arm = arm 32 ;
|
|
.cpu-arch-info-arm64 = arm 64 ;
|
|
|
|
# Fill explicit architecture and address model values
|
|
for local cpu in [ MATCH "^\\.cpu-arch-info-(.*)" : [ VARNAMES $(__name__) ] ]
|
|
{
|
|
local arch = $(.cpu-arch-info-$(cpu)[1]) ;
|
|
.cpus-on-$(arch) += $(cpu) ;
|
|
.cpu-arch-$(cpu) = <architecture>$(arch)/<address-model>$(.cpu-arch-info-$(cpu)[2]) ;
|
|
}
|
|
|
|
# Match implicit architecture and address model based on the current platform
|
|
.default-cpu-arch = [ os.environ PROCESSOR_ARCHITEW6432 ] ;
|
|
.default-cpu-arch ?= [ os.environ PROCESSOR_ARCHITECTURE ] ;
|
|
.default-cpu-arch = $(.default-cpu-arch:L) ;
|
|
switch $(.default-cpu-arch)
|
|
{
|
|
case x86 : .default-cpu-arch = i386 ;
|
|
case em64t : .default-cpu-arch = amd64 ;
|
|
}
|
|
|
|
for local cpu in $(.cpus-on-$(.cpu-arch-info-$(.default-cpu-arch)[1]))
|
|
{
|
|
.cpu-arch-$(cpu) += <architecture>/<address-model>$(.cpu-arch-info-$(cpu)[2]) ;
|
|
}
|
|
|
|
.cpu-arch-$(.default-cpu-arch) += <architecture>$(.cpu-arch-info-$(.default-cpu-arch)[1])/<address-model> ;
|
|
.cpu-arch-$(.default-cpu-arch) += <architecture>/<address-model> ;
|
|
|
|
# If there is only one address model for an architecture we allow to ommit it
|
|
for local arch in [ MATCH "^\\.cpus-on-(.*)" : [ VARNAMES $(__name__) ] ]
|
|
{
|
|
if ! $(.cpus-on-$(arch)[2-]) && $(.cpus-on-$(arch)[1]) != $(.default-cpu-arch)
|
|
{
|
|
.cpu-arch-$(.cpus-on-$(arch)) += <architecture>$(arch)/<address-model> ;
|
|
}
|
|
}
|
|
|
|
|
|
# Supported CPU types (only Itanium optimization options are supported from
|
|
# VC++ 2005 on). See
|
|
# http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
|
|
# detailed information.
|
|
.cpu-type-g5 = i586 pentium pentium-mmx ;
|
|
.cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
|
|
k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 c7 ;
|
|
.cpu-type-em64t = prescott nocona core2 corei7 corei7-avx core-avx-i
|
|
conroe conroe-xe conroe-l allendale merom
|
|
merom-xe kentsfield kentsfield-xe penryn wolfdale
|
|
yorksfield nehalem sandy-bridge ivy-bridge haswell
|
|
broadwell skylake skylake-avx512 cannonlake icelake-client
|
|
icelake-server cascadelake cooperlake tigerlake ;
|
|
.cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3
|
|
athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3
|
|
bdver4 btver1 btver2 znver1 znver2 ;
|
|
.cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
|
|
athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
|
|
.cpu-type-itanium = itanium itanium1 merced ;
|
|
.cpu-type-itanium2 = itanium2 mckinley ;
|
|
.cpu-type-arm = armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
|
|
armv7 armv7s ;
|
|
|
|
# Known toolset versions, in order of preference.
|
|
.known-versions = 14.2 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
|
|
7.1toolkit 7.0 6.0 ;
|
|
|
|
# Version aliases.
|
|
.version-alias-6 = 6.0 ;
|
|
.version-alias-6.5 = 6.0 ;
|
|
.version-alias-7 = 7.0 ;
|
|
.version-alias-8 = 8.0 ;
|
|
.version-alias-9 = 9.0 ;
|
|
.version-alias-10 = 10.0 ;
|
|
.version-alias-11 = 11.0 ;
|
|
.version-alias-12 = 12.0 ;
|
|
.version-alias-14 = 14.0 ;
|
|
|
|
# Names of registry keys containing the Visual C++ installation path (relative
|
|
# to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
|
|
.version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
|
|
.version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
|
|
.version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
|
|
.version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
|
|
.version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
|
|
.version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
|
|
.version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
|
|
.version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ;
|
|
.version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ;
|
|
.version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ;
|
|
.version-12.0-reg = "VisualStudio\\12.0\\Setup\\VC" ;
|
|
.version-14.0-reg = "VisualStudio\\14.0\\Setup\\VC" ;
|
|
|
|
# Visual C++ Toolkit 2003 does not store its installation path in the registry.
|
|
# The environment variable 'VCToolkitInstallDir' and the default installation
|
|
# path will be checked instead.
|
|
.version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003/bin" ;
|
|
.version-7.1toolkit-env = VCToolkitInstallDir ;
|
|
# Visual Studio 2017 doesn't use a registry at all. And the suggested methods
|
|
# of discovery involve having a compiled program. So as a fallback we search
|
|
# paths for VS2017 (aka msvc >= 14.1).
|
|
.version-14.1-path =
|
|
"../../VC/Tools/MSVC/*/bin/Host*/*"
|
|
"Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*"
|
|
;
|
|
.version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
|
|
.version-14.2-path =
|
|
"../../VC/Tools/MSVC/*/bin/Host*/*"
|
|
"Microsoft Visual Studio/2019/*/VC/Tools/MSVC/*/bin/Host*/*"
|
|
;
|
|
.version-14.2-env = VS160COMNTOOLS ProgramFiles ProgramFiles(x86) ;
|
|
|
|
# Auto-detect all the available msvc installations on the system.
|
|
auto-detect-toolset-versions ;
|
|
|
|
|
|
# And finally trigger the actual Boost Build toolset registration.
|
|
register-toolset ;
|