3 Builders and other things for the local site. Here's where we'll
4 duplicate the functionality of autoconf until we move it into the
5 installation procedure or use something like qmconf.
7 The code that reads the registry to find MSVC components was borrowed
8 from distutils.msvccompiler.
15 # Permission is hereby granted, free of charge, to any person obtaining
16 # a copy of this software and associated documentation files (the
17 # "Software"), to deal in the Software without restriction, including
18 # without limitation the rights to use, copy, modify, merge, publish,
19 # distribute, sublicense, and/or sell copies of the Software, and to
20 # permit persons to whom the Software is furnished to do so, subject to
21 # the following conditions:
23 # The above copyright notice and this permission notice shall be included
24 # in all copies or substantial portions of the Software.
26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
27 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
28 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
45 import SCons.Node.Alias
47 import SCons.Scanner.C
48 import SCons.Scanner.Fortran
49 import SCons.Scanner.Prog
51 def alias_builder(env, target, source):
54 Alias = SCons.Builder.Builder(action = alias_builder,
55 target_factory = SCons.Node.Alias.default_ans.Alias,
56 source_factory = SCons.Node.FS.default_fs.Entry,
59 CScan = SCons.Scanner.C.CScan()
61 FortranScan = SCons.Scanner.Fortran.FortranScan()
63 def yaccEmitter(target, source, env, **kw):
64 # Yacc can be configured to emit a .h file as well
65 # as a .c file, if -d is specified on the command line.
67 os.path.splitext(SCons.Util.to_String(source[0]))[1] in \
69 '-d' in string.split(env.subst("$YACCFLAGS")):
70 target.append(os.path.splitext(SCons.Util.to_String(target[0]))[0] + \
72 return (target, source)
75 """Common function to generate a C file Builder."""
76 return SCons.Builder.Builder(action = {},
77 emitter = yaccEmitter,
78 suffix = '$CFILESUFFIX')
81 """Common function to generate a C++ file Builder."""
82 return SCons.Builder.Builder(action = {},
83 emitter = yaccEmitter,
84 suffix = '$CXXFILESUFFIX')
86 class SharedFlagChecker:
87 """This is a callable class that is used as
88 a build action for all objects, libraries, and programs.
89 Its job is to run before the "real" action that builds the
90 file, to make sure we aren't trying to link shared objects
91 into a static library/program, or static objects into a
94 def __init__(self, shared, set_target_flag):
96 self.set_target_flag = set_target_flag
98 def __call__(self, source, target, env, **kw):
99 if kw.has_key('shared'):
100 raise SCons.Errors.UserError, "The shared= parameter to Library() or Object() no longer works.\nUse SharedObject() or SharedLibrary() instead."
101 if self.set_target_flag:
103 tgt.attributes.shared = self.shared
105 same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
106 if same == '0' or same == '' or same == 'False':
108 if hasattr(src.attributes, 'shared'):
109 if self.shared and not src.attributes.shared:
110 raise SCons.Errors.UserError, "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])
112 SharedCheck = SCons.Action.Action(SharedFlagChecker(1, 0), None)
113 StaticCheck = SCons.Action.Action(SharedFlagChecker(0, 0), None)
114 SharedCheckSet = SCons.Action.Action(SharedFlagChecker(1, 1), None)
115 StaticCheckSet = SCons.Action.Action(SharedFlagChecker(0, 1), None)
117 CAction = SCons.Action.Action([ StaticCheckSet, "$CCCOM" ])
118 ShCAction = SCons.Action.Action([ SharedCheckSet, "$SHCCCOM" ])
119 CXXAction = SCons.Action.Action([ StaticCheckSet, "$CXXCOM" ])
120 ShCXXAction = SCons.Action.Action([ SharedCheckSet, "$SHCXXCOM" ])
122 F77Action = SCons.Action.Action([ StaticCheckSet, "$F77COM" ])
123 ShF77Action = SCons.Action.Action([ SharedCheckSet, "$SHF77COM" ])
124 F77PPAction = SCons.Action.Action([ StaticCheckSet, "$F77PPCOM" ])
125 ShF77PPAction = SCons.Action.Action([ SharedCheckSet, "$SHF77PPCOM" ])
127 ASAction = SCons.Action.Action([ StaticCheckSet, "$ASCOM" ])
128 ASPPAction = SCons.Action.Action([ StaticCheckSet, "$ASPPCOM" ])
132 """A function for generating the static object Builder."""
133 return SCons.Builder.Builder(action = {},
134 emitter="$OBJEMITTER",
135 prefix = '$OBJPREFIX',
136 suffix = '$OBJSUFFIX',
137 src_builder = ['CFile', 'CXXFile'])
140 """A function for generating the shared object Builder."""
141 return SCons.Builder.Builder(action = {},
142 prefix = '$SHOBJPREFIX',
143 suffix = '$SHOBJSUFFIX',
144 emitter="$OBJEMITTER",
145 src_builder = ['CFile', 'CXXFile'])
147 ProgScan = SCons.Scanner.Prog.ProgScan()
149 StaticLibrary = SCons.Builder.Builder(action=[ StaticCheck, "$ARCOM" ],
150 prefix = '$LIBPREFIX',
151 suffix = '$LIBSUFFIX',
152 src_suffix = '$OBJSUFFIX',
153 src_builder = 'Object')
155 SharedLibrary = SCons.Builder.Builder(action=[ SharedCheck, "$SHLINKCOM" ],
156 emitter="$SHLIBEMITTER",
157 prefix = '$SHLIBPREFIX',
158 suffix = '$SHLIBSUFFIX',
160 src_suffix = '$SHOBJSUFFIX',
161 src_builder = 'SharedObject')
164 """Common function to generate a DVI file Builder."""
165 return SCons.Builder.Builder(action = {},
166 # The suffix is not configurable via a
167 # construction variable like $DVISUFFIX
168 # because the output file name is
169 # hard-coded within TeX.
173 """A function for generating the PDF Builder."""
174 return SCons.Builder.Builder(action = { },
175 prefix = '$PDFPREFIX',
176 suffix = '$PDFSUFFIX')
178 Program = SCons.Builder.Builder(action=[ StaticCheck, '$LINKCOM' ],
179 emitter='$PROGEMITTER',
180 prefix='$PROGPREFIX',
181 suffix='$PROGSUFFIX',
182 src_suffix='$OBJSUFFIX',
183 src_builder='Object',
186 def _concat(prefix, list, suffix, locals, globals, f=lambda x: x):
187 """Creates a new list from 'list' by first interpolating each
188 element in the list using 'locals' and 'globals' and then calling f
189 on the list, and finally concatenating 'prefix' and 'suffix' onto
190 each element of the list. A trailing space on 'prefix' or leading
191 space on 'suffix' will cause them to be put into seperate list
192 elements rather than being concatenated."""
197 if not SCons.Util.is_List(list):
200 def subst(x, locals=locals, globals=globals):
201 if SCons.Util.is_String(x):
202 return SCons.Util.scons_subst(x, locals, globals)
206 list = map(subst, list)
212 # ensure that prefix and suffix are strings
219 if prefix and prefix[-1] == ' ':
220 ret.append(prefix[:-1])
225 if suffix and suffix[0] == ' ':
226 ret.append(suffix[1:])
228 ret[-1] = ret[-1]+suffix
232 def _stripixes(prefix, list, suffix, locals, globals, stripprefix, stripsuffix, c=_concat):
233 """This is a wrapper around _concat() that checks for the existence
234 of prefixes or suffixes on list elements and strips them where it
235 finds them. This is used by tools (like the GNU linker) that need
236 to turn something like 'libfoo.a' into '-lfoo'."""
237 def f(list, sp=stripprefix, ss=stripsuffix):
240 if l[:len(sp)] == sp:
242 if l[-len(ss):] == ss:
246 return c(prefix, list, suffix, locals, globals, f)
248 ConstructionEnvironment = {
249 'BUILDERS' : { 'SharedLibrary' : SharedLibrary,
250 'Library' : StaticLibrary,
251 'StaticLibrary' : StaticLibrary,
253 'Program' : Program },
254 'SCANNERS' : [CScan, FortranScan],
256 'PDFSUFFIX' : '.pdf',
261 '_stripixes' : _stripixes,
262 '_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, locals(), globals())}',
263 '_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, locals(), globals(), RDirs)} $)',
264 '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, locals(), globals(), RDirs)} $)',
265 '_F77INCFLAGS' : '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, locals(), globals(), RDirs)} $)'