diff options
author | Steven Knight <knight@baldmt.com> | 2003-08-03 19:48:29 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-08-03 19:48:29 (GMT) |
commit | 1a7fcd1d270120232358e875bf53a95194352204 (patch) | |
tree | 51ec6a084612a69f96c1ae5747757d3559bd7979 | |
parent | 7500d447bdc3bd94db8ffbc8b90298fd9479e8c3 (diff) | |
download | SCons-1a7fcd1d270120232358e875bf53a95194352204.zip SCons-1a7fcd1d270120232358e875bf53a95194352204.tar.gz SCons-1a7fcd1d270120232358e875bf53a95194352204.tar.bz2 |
Refactor extension splitting to make it more flexible (for SWIG).
-rw-r--r-- | doc/man/scons.1 | 33 | ||||
-rw-r--r-- | src/CHANGES.txt | 3 | ||||
-rw-r--r-- | src/engine/SCons/Builder.py | 48 | ||||
-rw-r--r-- | src/engine/SCons/BuilderTests.py | 47 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 10 | ||||
-rw-r--r-- | src/engine/SCons/Tool/gnulink.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/midl.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Tool/msvc.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Tool/msvs.py | 10 | ||||
-rw-r--r-- | src/engine/SCons/Tool/qt.py | 13 |
10 files changed, 137 insertions, 41 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 3f5e4d5..862b65f 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -4901,9 +4901,42 @@ builder with the target. .IP prefix The prefix that will be prepended to the target file name. +This may be a simple string, or a callable object that takes +a construction environment as its argument +and returns a prefix. + +.ES +b = Builder("build_it < $SOURCE > $TARGET" + prefix = "file-") + +def gen_prefix(env): + return "file-" + env['PLATFORM'] + '-' +b = Builder("build_it < $SOURCE > $TARGET" + prefix = gen_prefix) +.EE .IP suffix The suffix that will be appended to the target file name. +This may be a simple string, or a callable object that takes +a construction environment as its argument +and returns a suffix. +If the suffix is a string, then +.B scons +will append a '.' to the beginning of the +suffix if it's not already there. +The string returned by callable object +is untouched and must append its own '.' +to the beginning if one is desired. + +.ES +b = Builder("build_it < $SOURCE > $TARGET" + suffix = "file-" + +def gen_suffix(env): + return "." + env['PLATFORM'] + "-file" +b = Builder("build_it < $SOURCE > $TARGET" + suffix = gen_suffix) +.EE .IP src_suffix The expected source file name suffix. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index acf7e88..9a1966d 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -77,6 +77,9 @@ RELEASE 0.XX - XXX - Add /TP to the default CXXFLAGS for msvc, so it can compile all of the suffixes we use as C++ files. + - Allow the "prefix" and "suffix" attributes of a Builder to be + callable objects that return generated strings. + From Gary Oberbrunner: - Report the target being built in error messages when building diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 4b6464a..b7bc1a3 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -238,12 +238,6 @@ def _init_nodes(builder, env, overrides, tlist, slist): if scanner: s.source_scanner = scanner - -def _adjust_suffix(suff): - if suff and not suff[0] in [ '.', '$' ]: - return '.' + suff - return suff - class EmitterProxy: """This is a callable class that can act as a Builder emitter. It holds on to a string that @@ -322,10 +316,13 @@ class BuilderBase: def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) + def splitext(self, path): + return SCons.Util.splitext(path) + def _create_nodes(self, env, overrides, target = None, source = None): """Create and return lists of target and source nodes. """ - def adjustixes(files, pre, suf): + def adjustixes(files, pre, suf, self=self): if not files: return [] ret = [] @@ -339,7 +336,7 @@ class BuilderBase: if fn[:len(pre)] != pre: f = os.path.join(path, pre + fn) # Only append a suffix if the file does not have one. - if suf and not SCons.Util.splitext(f)[1]: + if suf and not self.splitext(f)[1]: if f[-len(suf):] != suf: f = f + suf ret.append(f) @@ -357,7 +354,7 @@ class BuilderBase: if isinstance(s, SCons.Node.Node): s = str(s) dir, s = os.path.split(s) - target = pre + os.path.splitext(s)[0] + suf + target = pre + self.splitext(s)[0] + suf if dir: target = [ os.path.join(dir, target) ] else: @@ -410,8 +407,27 @@ class BuilderBase: return tlist + def adjust_suffix(self, suff): + if suff and not suff[0] in [ '.', '$' ]: + return '.' + suff + return suff + + def get_prefix(self, env): + prefix = self.prefix + if callable(prefix): + prefix = prefix(env) + return env.subst(prefix) + + def get_suffix(self, env): + suffix = self.suffix + if callable(suffix): + suffix = suffix(env) + else: + suffix = self.adjust_suffix(suffix) + return env.subst(suffix) + def src_suffixes(self, env): - return map(lambda x, e=env: e.subst(_adjust_suffix(x)), + return map(lambda x, s=self, e=env: e.subst(s.adjust_suffix(x)), self.src_suffix) def set_src_suffix(self, src_suffix): @@ -428,12 +444,6 @@ class BuilderBase: return '' return ret[0] - def get_suffix(self, env): - return env.subst(_adjust_suffix(self.suffix)) - - def get_prefix(self, env): - return env.subst(self.prefix) - def targets(self, node): """Return the list of targets for this builder instance. @@ -532,15 +542,15 @@ class MultiStepBuilder(BuilderBase): src_suffixes = self.src_suffixes(env) for snode in slist: - path, ext = SCons.Util.splitext(snode.get_abspath()) + path, ext = self.splitext(snode.get_abspath()) if sdict.has_key(ext): src_bld = sdict[ext] tgt = apply(src_bld, (env, path, snode), kw) # Only supply the builder with sources it is capable # of building. if SCons.Util.is_List(tgt): - tgt = filter(lambda x, suf=src_suffixes: - SCons.Util.splitext(SCons.Util.to_String(x))[1] in suf, + tgt = filter(lambda x, self=self, suf=src_suffixes: + self.splitext(SCons.Util.to_String(x))[1] in suf, tgt) if not SCons.Util.is_List(tgt): final_sources.append(tgt) diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index ded5354..a7c2f12 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -287,6 +287,37 @@ class BuilderTestCase(unittest.TestCase): assert not builder.target_factory is FooFactory assert builder.source_factory is FooFactory + def test_splitext(self): + """Test the splitext() method attached to a Builder.""" + b = SCons.Builder.Builder() + assert b.splitext('foo') == ('foo','') + assert b.splitext('foo.bar') == ('foo','.bar') + assert b.splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'') + + class MyBuilder(SCons.Builder.BuilderBase): + def splitext(self, path): + return "called splitext()" + + b = MyBuilder() + ret = b.splitext('xyz.c') + assert ret == "called splitext()", ret + + def test_adjust_suffix(self): + """Test how a Builder adjusts file suffixes + """ + b = SCons.Builder.Builder() + assert b.adjust_suffix('.foo') == '.foo' + assert b.adjust_suffix('foo') == '.foo' + assert b.adjust_suffix('$foo') == '$foo' + + class MyBuilder(SCons.Builder.BuilderBase): + def adjust_suffix(self, suff): + return "called adjust_suffix()" + + b = MyBuilder() + ret = b.adjust_suffix('.foo') + assert ret == "called adjust_suffix()", ret + def test_prefix(self): """Test Builder creation with a specified target prefix @@ -312,6 +343,14 @@ class BuilderTestCase(unittest.TestCase): assert tgt.path == os.path.join('lib', 'libtgt5'), \ "Target has unexpected name: %s" % tgt.path + def gen_prefix(env): + return "gen_prefix() says " + env['FOO'] + my_env = Environment(FOO = 'xyzzy') + builder = SCons.Builder.Builder(prefix = gen_prefix) + assert builder.get_prefix(my_env) == "gen_prefix() says xyzzy" + my_env['FOO'] = 'abracadabra' + assert builder.get_prefix(my_env) == "gen_prefix() says abracadabra" + def test_src_suffix(self): """Test Builder creation with a specified source file suffix @@ -366,6 +405,14 @@ class BuilderTestCase(unittest.TestCase): assert tgt.path == 'src5.o', \ "Target has unexpected name: %s" % tgt.path + def gen_suffix(env): + return "gen_suffix() says " + env['BAR'] + my_env = Environment(BAR = 'hocus pocus') + builder = SCons.Builder.Builder(suffix = gen_suffix) + assert builder.get_suffix(my_env) == "gen_suffix() says hocus pocus", builder.get_suffix(my_env) + my_env['BAR'] = 'presto chango' + assert builder.get_suffix(my_env) == "gen_suffix() says presto chango" + def test_ListBuilder(self): """Testing ListBuilder class.""" def function2(target, source, env, tlist = [outfile, outfile2], **kw): diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 0951935..d12a504 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -232,12 +232,12 @@ class EntryProxy(SCons.Util.Proxy): def __get_filebase(self): name = self.get().name - return SCons.Util.SpecialAttrWrapper(os.path.splitext(name)[0], + return SCons.Util.SpecialAttrWrapper(SCons.Util.splitext(name)[0], name + "_filebase") def __get_suffix(self): name = self.get().name - return SCons.Util.SpecialAttrWrapper(os.path.splitext(name)[1], + return SCons.Util.SpecialAttrWrapper(SCons.Util.splitext(name)[1], name + "_suffix") def __get_file(self): @@ -248,7 +248,7 @@ class EntryProxy(SCons.Util.Proxy): """Return the file's directory and file name, with the suffix stripped.""" entry = self.get() - return SCons.Util.SpecialAttrWrapper(os.path.splitext(entry.get_path())[0], + return SCons.Util.SpecialAttrWrapper(SCons.Util.splitext(entry.get_path())[0], entry.name + "_base") def __get_posix_path(self): @@ -499,7 +499,7 @@ class Entry(Base): return node.get_found_includes(env, scanner, target) def scanner_key(self): - return os.path.splitext(self.name)[1] + return SCons.Util.splitext(self.name)[1] def get_contents(self): """Fetch the contents of the entry. @@ -1154,7 +1154,7 @@ class File(Base): return self.dir.root() def scanner_key(self): - return os.path.splitext(self.name)[1] + return SCons.Util.splitext(self.name)[1] def get_contents(self): if not self.rexists(): diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 4c14383..0f92b35 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -45,7 +45,7 @@ linkers = ['g++', 'gcc', 'c++', 'cc'] def cxxSource(sources): for s in sources: - if os.path.splitext(str(s))[1] in cc.CXXSuffixes: + if SCons.Util.splitext(str(s))[1] in cc.CXXSuffixes: return 1 if cxxSource(s.sources): return 1 diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py index 77769db..a1f079b 100644 --- a/src/engine/SCons/Tool/midl.py +++ b/src/engine/SCons/Tool/midl.py @@ -33,13 +33,15 @@ selection method. __revision__ = "__REVISION__" +import os.path + import SCons.Defaults import SCons.Scanner.IDL -import os.path +import SCons.Util def midl_emitter(target, source, env): """Produces a list of outputs from the MIDL compiler""" - base, ext = os.path.splitext(str(source[0])) + base, ext = SCons.Util.splitext(str(source[0])) tlb = base + '.tlb' incl = base + '.h' interface = base + '_i.c' diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index 3d6f3ab..2c8a004 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -327,13 +327,13 @@ def pch_emitter(target, source, env): obj = None for t in target: - if os.path.splitext(str(t))[1] == '.pch': + if SCons.Util.splitext(str(t))[1] == '.pch': pch = t - if os.path.splitext(str(t))[1] == '.obj': + if SCons.Util.splitext(str(t))[1] == '.obj': obj = t if not obj: - obj = os.path.splitext(str(pch))[0]+'.obj' + obj = SCons.Util.splitext(str(pch))[0]+'.obj' target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 1a9a7bb..40361a1 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -126,7 +126,7 @@ class _DSPGenerator: if self.env.has_key('name'): self.name = self.env['name'] else: - self.name = os.path.basename(os.path.splitext(self.dspfile)[0]) + self.name = os.path.basename(SCons.Util.splitext(self.dspfile)[0]) print "Adding '" + self.name + ' - ' + self.config.variant + "' to Visual Studio Project '" + str(dspfile) + "'" @@ -515,7 +515,7 @@ class _DSWGenerator: if self.env.has_key('name'): self.name = self.env['name'] else: - self.name = os.path.basename(os.path.splitext(self.dspfile)[0]) + self.name = os.path.basename(SCons.Util.splitext(self.dspfile)[0]) def Build(self): pass @@ -961,19 +961,19 @@ def projectEmitter(target, source, env): source = [] # make sure the suffix is correct for the version of MSVS we're running. - (base, suff) = os.path.splitext(str(target[0])) + (base, suff) = SCons.Util.splitext(str(target[0])) suff = env['MSVSPROJECTSUFFIX'] target[0] = base + suff dspfile = SCons.Node.FS.default_fs.File(target[0]).srcnode() - dswfile = SCons.Node.FS.default_fs.File(os.path.splitext(str(dspfile))[0] + env['MSVSSOLUTIONSUFFIX']) + dswfile = SCons.Node.FS.default_fs.File(SCons.Util.splitext(str(dspfile))[0] + env['MSVSSOLUTIONSUFFIX']) if not source: source = [SCons.Script.SConscript.stack[-1].sconscript.srcnode()] source[0].attributes.sconstruct = SCons.Script.SConscript.stack[0].sconscript - bdswpath = os.path.splitext(str(target[0]))[0] + env['MSVSSOLUTIONSUFFIX'] + bdswpath = SCons.Util.splitext(str(target[0]))[0] + env['MSVSSOLUTIONSUFFIX'] bdswfile = SCons.Node.FS.default_fs.File(bdswpath) # only make these side effects if they're diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py index 65e7649..d9f690a 100644 --- a/src/engine/SCons/Tool/qt.py +++ b/src/engine/SCons/Tool/qt.py @@ -36,8 +36,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os.path import re -import SCons.Tool import SCons.Defaults +import SCons.Tool +import SCons.Util header_extensions = (".h", ".H", ".hxx", ".hpp", ".hh") @@ -71,17 +72,17 @@ class _Automoc: # out_sources contains at least all sources for the Library or Prog out_sources = source[:] for s in source: - prefix, suffix = os.path.splitext(str(s)) + prefix, suffix = SCons.Util.splitext(str(s)) # Nodes for header (h) / moc file (moc_cpp) / cpp file (cpp) # and ui.h file (ui_h) cpp = s.sources[0] ui = None if cpp.sources != None and len(cpp.sources) > 0: - src_src_suffix = os.path.splitext(str(cpp.sources[0]))[1] + src_src_suffix = SCons.Util.splitext(str(cpp.sources[0]))[1] if src_src_suffix == env.subst('$QT_UISUFFIX'): ui = cpp.sources[0] - src_prefix, src_suffix = os.path.splitext(str(cpp.srcnode())) + src_prefix, src_suffix = SCons.Util.splitext(str(cpp.srcnode())) h=None for h_ext in header_extensions: if os.path.exists(src_prefix + h_ext): @@ -99,7 +100,7 @@ class _Automoc: if (h and q_object_search.search(h.get_contents())) or ui: # h file with the Q_OBJECT macro found -> add moc_cpp dir,base = os.path.split(prefix) - src_ext = os.path.splitext(str(h))[1] + src_ext = SCons.Util.splitext(str(h))[1] moc_cpp = SCons.Node.FS.default_fs.File(os.path.join(dir, env['QT_MOCNAMEGENERATOR'](base, src_ext, env))) moc_o = self.objBuilder(source=moc_cpp) @@ -111,7 +112,7 @@ class _Automoc: # cpp file with Q_OBJECT macro found -> add moc # (to be included in cpp) dir,base = os.path.split(prefix) - src_ext = os.path.splitext(str(cpp))[1] + src_ext = SCons.Util.splitext(str(cpp))[1] moc = SCons.Node.FS.default_fs.File(os.path.join(dir, env['QT_MOCNAMEGENERATOR'](base, src_ext, env))) self.mocFromCppBld(env, moc, cpp) |