]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/tools/rc.py
1 # Status: being ported by Steven Watanabe
4 # Copyright (C) Andre Hentz 2003. Permission to copy, use, modify, sell and
5 # distribute this software is granted provided this copyright notice appears in
6 # all copies. This software is provided "as is" without express or implied
7 # warranty, and with no claim as to its suitability for any purpose.
9 # Copyright (c) 2006 Rene Rivera.
11 # Copyright (c) 2008 Steven Watanabe
13 # Use, modification and distribution is subject to the Boost Software
14 # License Version 1.0. (See accompanying file LICENSE.txt or
15 # https://www.bfgroup.xyz/b2/LICENSE.txt)
22 ##import toolset : flags ;
29 from b2
.build
import type, toolset
, generators
, scanner
, feature
30 from b2
.exceptions
import AlreadyDefined
31 from b2
.tools
import builtin
32 from b2
.util
import regex
33 from b2
.build
.toolset
import flags
34 from b2
.manager
import get_manager
35 from b2
.util
import utility
42 __debug
= "--debug-configuration" in bjam
.variable("ARGV")
45 type.register('RC', ['rc'])
50 def configure (command
= None, condition
= None, options
= None):
52 Configures a new resource compilation command specific to a condition,
53 usually a toolset selection condition. The possible options are:
55 * <rc-type>(rc|windres) - Indicates the type of options the command
58 Even though the arguments are all optional, only when a command, condition,
59 and at minimum the rc-type option are given will the command be configured.
60 This is so that callers don't have to check auto-configuration values
61 before calling this. And still get the functionality of build failures when
62 the resource compiler can't be found.
64 rc_type
= feature
.get_values('<rc-type>', options
)
66 assert(len(rc_type
) == 1)
69 if command
and condition
and rc_type
:
70 flags('rc.compile.resource', '.RC', condition
, command
)
71 flags('rc.compile.resource', '.RC_TYPE', condition
, [rc_type
.lower()])
72 flags('rc.compile.resource', 'DEFINES', [], ['<define>'])
73 flags('rc.compile.resource', 'INCLUDES', [], ['<include>'])
75 print 'notice: using rc compiler ::', condition
, '::', command
77 engine
= get_manager().engine()
80 """Class representing bjam action defined from Python.
81 The function must register the action to execute."""
83 def __init__(self
, action_name
, function
):
84 self
.action_name
= action_name
85 self
.function
= function
87 def __call__(self
, targets
, sources
, property_set
):
89 self
.function(targets
, sources
, property_set
)
91 # FIXME: What is the proper way to dispatch actions?
92 def rc_register_action(action_name
, function
= None):
94 if action_name
in engine
.actions
:
95 raise AlreadyDefined("Bjam action %s is already defined" % action_name
)
96 engine
.actions
[action_name
] = RCAction(action_name
, function
)
98 def rc_compile_resource(targets
, sources
, properties
):
99 rc_type
= bjam
.call('get-target-variable', targets
, '.RC_TYPE')
100 rc_type
= rc_type
[0] if rc_type
else ''
102 engine
.set_update_action('rc.compile.resource.' + rc_type
, targets
, sources
, properties
)
104 rc_register_action('rc.compile.resource', rc_compile_resource
)
107 engine
.register_action(
108 'rc.compile.resource.rc',
109 '"$(.RC)" -l 0x409 "-U$(UNDEFS)" "-D$(DEFINES)" -I"$(>:D)" -I"$(<:D)" -I"$(INCLUDES)" -fo "$(<)" "$(>)"')
111 engine
.register_action(
112 'rc.compile.resource.windres',
113 '"$(.RC)" "-U$(UNDEFS)" "-D$(DEFINES)" -I"$(>:D)" -I"$(<:D)" -I"$(INCLUDES)" -o "$(<)" -i "$(>)"')
115 # FIXME: this was originally declared quietly
116 engine
.register_action(
117 'compile.resource.null',
118 'as /dev/null -o "$(<)"')
120 # Since it's a common practice to write
121 # exe hello : hello.cpp hello.rc
122 # we change the name of object created from RC file, to
123 # avoid conflict with hello.cpp.
124 # The reason we generate OBJ and not RES, is that gcc does not
125 # seem to like RES files, but works OK with OBJ.
126 # See http://article.gmane.org/gmane.comp.lib.boost.build/5643/
128 # Using 'register-c-compiler' adds the build directory to INCLUDES
129 # FIXME: switch to generators
130 builtin
.register_c_compiler('rc.compile.resource', ['RC'], ['OBJ(%_res)'], [])
132 __angle_include_re
= "#include[ ]*<([^<]+)>"
134 # Register scanner for resources
135 class ResScanner(scanner
.Scanner
):
137 def __init__(self
, includes
):
139 self
.includes
= includes
142 return "(([^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)" +\
143 "[ ]+([^ \"]+|\"[^\"]+\"))|(#include[ ]*(<[^<]+>|\"[^\"]+\")))" ;
145 def process(self
, target
, matches
, binding
):
147 angle
= regex
.transform(matches
, "#include[ ]*<([^<]+)>")
148 quoted
= regex
.transform(matches
, "#include[ ]*\"([^\"]+)\"")
149 res
= regex
.transform(matches
,
150 "[^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)" +\
151 "[ ]+(([^ \"]+)|\"([^\"]+)\")", [3, 4])
153 # Icons and other includes may referenced as
155 # IDR_MAINFRAME ICON "res\\icon.ico"
157 # so we have to replace double backslashes to single ones.
158 res
= [ re
.sub(r
'\\\\', '/', match
) for match
in res
if match
is not None ]
160 # CONSIDER: the new scoping rule seem to defeat "on target" variables.
161 g
= bjam
.call('get-target-variable', target
, 'HDRGRIST')[0]
162 b
= os
.path
.normpath(os
.path
.dirname(binding
))
164 # Attach binding of including file to included targets.
165 # When target is directly created from virtual target
166 # this extra information is unnecessary. But in other
167 # cases, it allows to distinguish between two headers of the
168 # same name included from different places.
169 # We don't need this extra information for angle includes,
170 # since they should not depend on including file (we can't
171 # get literal "." in include path).
176 angle
= [g
+ x
for x
in angle
]
177 quoted
= [g2
+ x
for x
in quoted
]
178 res
= [g2
+ x
for x
in res
]
182 bjam
.call('mark-included', target
, all
)
184 engine
= get_manager().engine()
186 engine
.add_dependency(target
, res
)
187 bjam
.call('NOCARE', all
+ res
)
188 engine
.set_target_variable(angle
, 'SEARCH', [utility
.get_value(inc
) for inc
in self
.includes
])
189 engine
.set_target_variable(quoted
, 'SEARCH', [b
+ utility
.get_value(inc
) for inc
in self
.includes
])
190 engine
.set_target_variable(res
, 'SEARCH', [b
+ utility
.get_value(inc
) for inc
in self
.includes
])
192 # Just propagate current scanner to includes, in a hope
193 # that includes do not change scanners.
194 get_manager().scanners().propagate(self
, angle
+ quoted
)
196 scanner
.register(ResScanner
, 'include')
197 type.set_scanner('RC', ResScanner
)