mirror of
https://github.com/boostorg/build.git
synced 2026-02-15 13:02:11 +00:00
Initial MSVC support for Boost.Build/Python.
Patch from Juraj Ivančić. [SVN r75722]
This commit is contained in:
@@ -20,14 +20,14 @@ class BjamAction:
|
||||
self.function = function
|
||||
|
||||
def __call__(self, targets, sources, property_set):
|
||||
if self.function:
|
||||
self.function(targets, sources, property_set)
|
||||
|
||||
# Bjam actions defined from Python have only the command
|
||||
# to execute, and no associated jam procedural code. So
|
||||
# passing 'property_set' to it is not necessary.
|
||||
bjam_interface.call("set-update-action", self.action_name,
|
||||
targets, sources, [])
|
||||
if self.function:
|
||||
self.function(targets, sources, property_set)
|
||||
|
||||
class BjamNativeAction:
|
||||
"""Class representing bjam action defined by Jam code.
|
||||
@@ -132,7 +132,12 @@ class Engine:
|
||||
bjam_flags = reduce(operator.or_,
|
||||
(action_modifiers[flag] for flag in flags), 0)
|
||||
|
||||
bjam_interface.define_action(action_name, command, bound_list, bjam_flags)
|
||||
# We allow command to be empty so that we can define 'action' as pure
|
||||
# python function that would do some conditional logic and then relay
|
||||
# to other actions.
|
||||
assert command or function
|
||||
if command:
|
||||
bjam_interface.define_action(action_name, command, bound_list, bjam_flags)
|
||||
|
||||
self.actions[action_name] = BjamAction(action_name, function)
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class Property(object):
|
||||
(other._feature, other._value, other._condition))
|
||||
|
||||
|
||||
def create_from_string(s, allow_condition=False):
|
||||
def create_from_string(s, allow_condition=False,allow_missing_value=False):
|
||||
|
||||
condition = []
|
||||
import types
|
||||
@@ -92,7 +92,7 @@ def create_from_string(s, allow_condition=False):
|
||||
f = feature.get(feature_name)
|
||||
|
||||
value = get_value(s)
|
||||
if not value:
|
||||
if not value and not allow_missing_value:
|
||||
get_manager().errors()("Invalid property '%s' -- no value specified" % s)
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ def flags(rule_or_module, variable_name, condition, values = []):
|
||||
transformed = []
|
||||
for c in condition:
|
||||
# FIXME: 'split' might be a too raw tool here.
|
||||
pl = [property.create_from_string(s) for s in c.split('/')]
|
||||
pl = [property.create_from_string(s,False,True) for s in c.split('/')]
|
||||
pl = feature.expand_subfeatures(pl);
|
||||
transformed.append(property_set.create(pl))
|
||||
condition = transformed
|
||||
@@ -380,7 +380,6 @@ def add_requirements(requirements):
|
||||
|
||||
#if ! $(.ignore-requirements)
|
||||
#{
|
||||
print "XXXX", requirements
|
||||
__requirements.extend(requirements)
|
||||
#}
|
||||
|
||||
|
||||
@@ -144,11 +144,20 @@ def register_globals ():
|
||||
feature.feature ('threading', ['single', 'multi'], ['propagated'])
|
||||
feature.feature ('rtti', ['on', 'off'], ['propagated'])
|
||||
feature.feature ('exception-handling', ['on', 'off'], ['propagated'])
|
||||
|
||||
# Whether there is support for asynchronous EH (e.g. catching SEGVs).
|
||||
feature.feature ('asynch-exceptions', ['on', 'off'], ['propagated'])
|
||||
|
||||
# Whether all extern "C" functions are considered nothrow by default.
|
||||
feature.feature ('extern-c-nothrow', ['off', 'on'], ['propagated'])
|
||||
|
||||
feature.feature ('debug-symbols', ['on', 'off'], ['propagated'])
|
||||
feature.feature ('define', [], ['free'])
|
||||
feature.feature ('undef', [], ['free'])
|
||||
feature.feature ('include', [], ['free', 'path']) #order-sensitive
|
||||
feature.feature ('cflags', [], ['free'])
|
||||
feature.feature ('cxxflags', [], ['free'])
|
||||
feature.feature ('asmflags', [], ['free'])
|
||||
feature.feature ('linkflags', [], ['free'])
|
||||
feature.feature ('archiveflags', [], ['free'])
|
||||
feature.feature ('version', [], ['free'])
|
||||
@@ -309,10 +318,6 @@ def register_globals ():
|
||||
variant ('release', ['<optimization>speed', '<debug-symbols>off', '<inlining>full',
|
||||
'<runtime-debugging>off', '<define>NDEBUG'])
|
||||
variant ('profile', ['release'], ['<profiling>on', '<debug-symbols>on'])
|
||||
|
||||
type.register ('H', ['h'])
|
||||
type.register ('HPP', ['hpp'], 'H')
|
||||
type.register ('C', ['c'])
|
||||
|
||||
|
||||
reset ()
|
||||
@@ -700,20 +705,10 @@ class ArchiveGenerator (generators.Generator):
|
||||
|
||||
return result
|
||||
|
||||
### rule register-archiver ( id composing ? : source_types + : target_types + :
|
||||
### requirements * )
|
||||
### {
|
||||
### local g = [ new ArchiveGenerator $(id) $(composing) : $(source_types)
|
||||
### : $(target_types) : $(requirements) ] ;
|
||||
### generators.register $(g) ;
|
||||
### }
|
||||
###
|
||||
###
|
||||
### IMPORT $(__name__) : register-linker register-archiver
|
||||
### : : generators.register-linker generators.register-archiver ;
|
||||
###
|
||||
###
|
||||
###
|
||||
|
||||
def register_archiver(id, source_types, target_types, requirements):
|
||||
g = ArchiveGenerator(id, True, source_types, target_types, requirements)
|
||||
generators.register(g)
|
||||
|
||||
class DummyGenerator(generators.Generator):
|
||||
"""Generator that accepts everything and produces nothing. Useful as a general
|
||||
|
||||
@@ -349,7 +349,9 @@ def get_absolute_tool_path(command):
|
||||
programs = path.programs_path()
|
||||
m = path.glob(programs, [command, command + '.exe' ])
|
||||
if not len(m):
|
||||
print "Could not find:", command, "in", programs
|
||||
if __debug_configuration:
|
||||
print "Could not find:", command, "in", programs
|
||||
return None
|
||||
return os.path.dirname(m[0])
|
||||
|
||||
# ported from trunk@47174
|
||||
|
||||
46
v2/tools/mc.py
Normal file
46
v2/tools/mc.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright (c) 2005 Alexey Pakhunov.
|
||||
# Copyright (c) 2011 Juraj Ivancic
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software
|
||||
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Support for Microsoft message compiler tool.
|
||||
# Notes:
|
||||
# - there's just message compiler tool, there's no tool for
|
||||
# extracting message strings from sources
|
||||
# - This file allows to use Microsoft message compiler
|
||||
# with any toolset. In msvc.jam, there's more specific
|
||||
# message compiling action.
|
||||
|
||||
import bjam
|
||||
|
||||
from b2.tools import common, rc
|
||||
from b2.build import generators, type
|
||||
from b2.build.toolset import flags
|
||||
from b2.build.feature import feature
|
||||
from b2.manager import get_manager
|
||||
|
||||
def init():
|
||||
pass
|
||||
|
||||
type.register('MC', ['mc'])
|
||||
|
||||
|
||||
# Command line options
|
||||
feature('mc-input-encoding', ['ansi', 'unicode'], ['free'])
|
||||
feature('mc-output-encoding', ['unicode', 'ansi'], ['free'])
|
||||
feature('mc-set-customer-bit', ['no', 'yes'], ['free'])
|
||||
|
||||
flags('mc.compile', 'MCFLAGS', ['<mc-input-encoding>ansi'], ['-a'])
|
||||
flags('mc.compile', 'MCFLAGS', ['<mc-input-encoding>unicode'], ['-u'])
|
||||
flags('mc.compile', 'MCFLAGS', ['<mc-output-encoding>ansi'], '-A')
|
||||
flags('mc.compile', 'MCFLAGS', ['<mc-output-encoding>unicode'], ['-U'])
|
||||
flags('mc.compile', 'MCFLAGS', ['<mc-set-customer-bit>no'], [])
|
||||
flags('mc.compile', 'MCFLAGS', ['<mc-set-customer-bit>yes'], ['-c'])
|
||||
|
||||
generators.register_standard('mc.compile', ['MC'], ['H', 'RC'])
|
||||
|
||||
get_manager().engine().register_action(
|
||||
'mc.compile',
|
||||
'mc $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"')
|
||||
134
v2/tools/midl.py
Normal file
134
v2/tools/midl.py
Normal file
@@ -0,0 +1,134 @@
|
||||
# Copyright (c) 2005 Alexey Pakhunov.
|
||||
# Copyright (c) 2011 Juraj Ivancic
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software
|
||||
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Microsoft Interface Definition Language (MIDL) related routines
|
||||
from b2.build import scanner, type
|
||||
from b2.build.toolset import flags
|
||||
from b2.build.feature import feature
|
||||
from b2.manager import get_manager
|
||||
from b2.tools import builtin, common
|
||||
from b2.util import regex
|
||||
|
||||
def init():
|
||||
pass
|
||||
|
||||
type.register('IDL', ['idl'])
|
||||
|
||||
# A type library (.tlb) is generated by MIDL compiler and can be included
|
||||
# to resources of an application (.rc). In order to be found by a resource
|
||||
# compiler its target type should be derived from 'H' - otherwise
|
||||
# the property '<implicit-dependency>' will be ignored.
|
||||
type.register('MSTYPELIB', 'tlb', 'H')
|
||||
|
||||
# Register scanner for MIDL files
|
||||
class MidlScanner(scanner.Scanner):
|
||||
def __init__ (self, includes=[]):
|
||||
scanner.Scanner.__init__(self)
|
||||
self.includes = includes
|
||||
|
||||
# List of quoted strings
|
||||
re_strings = "[ \t]*\"([^\"]*)\"([ \t]*,[ \t]*\"([^\"]*)\")*[ \t]*" ;
|
||||
|
||||
# 'import' and 'importlib' directives
|
||||
self.re_import = "import" + re_strings + "[ \t]*;" ;
|
||||
self.re_importlib = "importlib[ \t]*[(]" + re_strings + "[)][ \t]*;" ;
|
||||
|
||||
# C preprocessor 'include' directive
|
||||
self.re_include_angle = "#[ \t]*include[ \t]*<(.*)>" ;
|
||||
self.re_include_quoted = "#[ \t]*include[ \t]*\"(.*)\"" ;
|
||||
|
||||
def pattern():
|
||||
# Match '#include', 'import' and 'importlib' directives
|
||||
return "((#[ \t]*include|import(lib)?).+(<(.*)>|\"(.*)\").+)"
|
||||
|
||||
def process(self, target, matches, binding):
|
||||
included_angle = regex.transform(matches, self.re_include_angle)
|
||||
included_quoted = regex.transform(matches, self.re_include_quoted)
|
||||
imported = regex.transform(matches, self.re_import, [1, 3])
|
||||
imported_tlbs = regex.transform(matches, self.re_importlib, [1, 3])
|
||||
|
||||
# CONSIDER: the new scoping rule seem to defeat "on target" variables.
|
||||
g = bjam.call('get-target-variable', target, 'HDRGRIST')
|
||||
b = os.path.normalize_path(os.path.dirname(binding))
|
||||
|
||||
# Attach binding of including file to included targets.
|
||||
# When target is directly created from virtual target
|
||||
# this extra information is unnecessary. But in other
|
||||
# cases, it allows to distinguish between two headers of the
|
||||
# same name included from different places.
|
||||
g2 = g + "#" + b
|
||||
|
||||
g = "<" + g + ">"
|
||||
g2 = "<" + g2 + ">"
|
||||
|
||||
included_angle = [ g + x for x in included_angle ]
|
||||
included_quoted = [ g + x for x in included_quoted ]
|
||||
imported = [ g + x for x in imported ]
|
||||
imported_tlbs = [ g + x for x in imported_tlbs ]
|
||||
|
||||
all = included_angle + included_quoted + imported
|
||||
|
||||
bjam.call('INCLUDES', [target], all)
|
||||
bjam.call('DEPENDS', [target], imported_tlbs)
|
||||
bjam.call('NOCARE', all + imported_tlbs)
|
||||
engine.set_target_variable(included_angle , 'SEARCH', ungrist(self.includes))
|
||||
engine.set_target_variable(included_quoted, 'SEARCH', b + ungrist(self.includes))
|
||||
engine.set_target_variable(imported , 'SEARCH', b + ungrist(self.includes))
|
||||
engine.set_target_variable(imported_tlbs , 'SEARCH', b + ungrist(self.includes))
|
||||
|
||||
get_manager().scanners().propagate(type.get_scanner('CPP', PropertySet(self.includes)), included_angle + included_quoted)
|
||||
get_manager().scanners().propagate(self, imported)
|
||||
|
||||
scanner.register(MidlScanner, 'include')
|
||||
type.set_scanner('IDL', MidlScanner)
|
||||
|
||||
|
||||
# Command line options
|
||||
feature('midl-stubless-proxy', ['yes', 'no'], ['propagated'] )
|
||||
feature('midl-robust', ['yes', 'no'], ['propagated'] )
|
||||
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-stubless-proxy>yes'], ['/Oicf' ])
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-stubless-proxy>no' ], ['/Oic' ])
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-robust>yes' ], ['/robust' ])
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-robust>no' ], ['/no_robust'])
|
||||
|
||||
# Architecture-specific options
|
||||
architecture_x86 = ['<architecture>' , '<architecture>x86']
|
||||
address_model_32 = ['<address-model>', '<address-model>32']
|
||||
address_model_64 = ['<address-model>', '<address-model>64']
|
||||
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', [ar + '/' + m for ar in architecture_x86 for m in address_model_32 ], ['/win32'])
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', [ar + '/<address-model>64' for ar in architecture_x86], ['/x64'])
|
||||
flags('midl.compile.idl', 'MIDLFLAGS', ['<architecture>ia64/' + m for m in address_model_64], ['/ia64'])
|
||||
|
||||
flags('midl.compile.idl', 'DEFINES', [], ['<define>'])
|
||||
flags('midl.compile.idl', 'UNDEFS', [], ['<undef>'])
|
||||
flags('midl.compile.idl', 'INCLUDES', [], ['<include>'])
|
||||
|
||||
|
||||
builtin.register_c_compiler('midl.compile.idl', ['IDL'], ['MSTYPELIB', 'H', 'C(%_i)', 'C(%_proxy)', 'C(%_dlldata)'], [])
|
||||
|
||||
|
||||
# MIDL does not always generate '%_proxy.c' and '%_dlldata.c'. This behavior
|
||||
# depends on contents of the source IDL file. Calling TOUCH_FILE below ensures
|
||||
# that both files will be created so bjam will not try to recreate them
|
||||
# constantly.
|
||||
get_manager().engine().register_action(
|
||||
'midl.compile.idl',
|
||||
'''midl /nologo @"@($(<[1]:W).rsp:E=
|
||||
"$(>:W)"
|
||||
-D$(DEFINES)
|
||||
"-I$(INCLUDES)"
|
||||
-U$(UNDEFS)
|
||||
$(MIDLFLAGS)
|
||||
/tlb "$(<[1]:W)"
|
||||
/h "$(<[2]:W)"
|
||||
/iid "$(<[3]:W)"
|
||||
/proxy "$(<[4]:W)"
|
||||
/dlldata "$(<[5]:W)")"
|
||||
{touch} "$(<[4]:W)"
|
||||
{touch} "$(<[5]:W)"'''.format(touch=common.file_creation_command()))
|
||||
2379
v2/tools/msvc.py
Normal file
2379
v2/tools/msvc.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@ __all__ = [
|
||||
'html',
|
||||
'lib',
|
||||
'obj',
|
||||
'preprocessed',
|
||||
'rsp',
|
||||
]
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
from b2.build import type
|
||||
|
||||
def register ():
|
||||
type.register_type ('CPP', ['cpp', 'cxx', 'cc'])
|
||||
type.register_type('CPP', ['cpp', 'cxx', 'cc'])
|
||||
type.register_type('H', ['h'])
|
||||
type.register_type('HPP', ['hpp'], 'H')
|
||||
type.register_type('C', ['c'])
|
||||
|
||||
register ()
|
||||
|
||||
22
v2/tools/types/preprocessed.py
Normal file
22
v2/tools/types/preprocessed.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright David Abrahams 2004. 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)
|
||||
|
||||
from b2.build import type
|
||||
|
||||
def register ():
|
||||
type.register_type('PREPROCESSED_C', ['i'], 'C')
|
||||
type.register_type('PREPROCESSED_CPP', ['ii'], 'CPP')
|
||||
|
||||
register ()
|
||||
# Copyright David Abrahams 2004. 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)
|
||||
|
||||
from b2.build import type
|
||||
|
||||
def register ():
|
||||
type.register_type ('PREPROCESSED_C', ['i'], 'C')
|
||||
type.register_type ('PREPROCESSED_CPP', ['ii'], 'CPP')
|
||||
|
||||
register ()
|
||||
Reference in New Issue
Block a user