summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Tool
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons/Tool')
-rw-r--r--src/engine/SCons/Tool/applelink.py6
-rw-r--r--src/engine/SCons/Tool/gfortran.py62
-rw-r--r--src/engine/SCons/Tool/gfortran.xml15
-rw-r--r--src/engine/SCons/Tool/intelc.py77
-rw-r--r--src/engine/SCons/Tool/jar.py25
-rw-r--r--src/engine/SCons/Tool/jar.xml5
-rw-r--r--src/engine/SCons/Tool/link.py9
-rw-r--r--src/engine/SCons/Tool/mslink.py48
-rw-r--r--src/engine/SCons/Tool/qt.py2
-rw-r--r--src/engine/SCons/Tool/rmic.py6
-rw-r--r--src/engine/SCons/Tool/swig.py3
-rw-r--r--src/engine/SCons/Tool/tex.py98
-rw-r--r--src/engine/SCons/Tool/yacc.py11
-rw-r--r--src/engine/SCons/Tool/yacc.xml8
14 files changed, 298 insertions, 77 deletions
diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py
index a65a4af..532301f 100644
--- a/src/engine/SCons/Tool/applelink.py
+++ b/src/engine/SCons/Tool/applelink.py
@@ -35,12 +35,14 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Util
-import gnulink
+# Even though the Mac is based on the GNU toolchain, it doesn't understand
+# the -rpath option, so we use the "link" tool instead of "gnulink".
+import link
def generate(env):
"""Add Builders and construction variables for applelink to an
Environment."""
- gnulink.generate(env)
+ link.generate(env)
env['FRAMEWORKPATHPREFIX'] = '-F'
env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}'
diff --git a/src/engine/SCons/Tool/gfortran.py b/src/engine/SCons/Tool/gfortran.py
new file mode 100644
index 0000000..f3db693
--- /dev/null
+++ b/src/engine/SCons/Tool/gfortran.py
@@ -0,0 +1,62 @@
+"""SCons.Tool.gfortran
+
+Tool-specific initialization for gfortran, the GNU Fortran 95/Fortran
+2003 compiler.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Util
+
+import fortran
+
+def generate(env):
+ """Add Builders and construction variables for gfortran to an
+ Environment."""
+ fortran.generate(env)
+
+ # which one is the good one ? ifort uses _FORTRAND, ifl FORTRAN,
+ # aixf77 F77 ...
+ #env['_FORTRAND'] = 'gfortran'
+ env['FORTRAN'] = 'gfortran'
+
+ # XXX does this need to be set too ?
+ #env['SHFORTRAN'] = 'gfortran'
+
+ if env['PLATFORM'] in ['cygwin', 'win32']:
+ env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS')
+ else:
+ env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -fPIC')
+
+ # XXX; Link problems: we need to add -lgfortran somewhere...
+
+def exists(env):
+ return env.Detect('gfortran')
diff --git a/src/engine/SCons/Tool/gfortran.xml b/src/engine/SCons/Tool/gfortran.xml
new file mode 100644
index 0000000..ba0fe76
--- /dev/null
+++ b/src/engine/SCons/Tool/gfortran.xml
@@ -0,0 +1,15 @@
+<!--
+__COPYRIGHT__
+
+This file is processed by the bin/SConsDoc.py module.
+See its __doc__ string for a discussion of the format.
+-->
+<tool name="gfortran">
+<summary>
+Sets construction variables for the GNU F95/F2003 GNU compiler.
+</summary>
+<sets>
+FORTRAN
+SHFORTRANFLAGS
+</sets>
+</tool>
diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py
index 673c848..02cc52a 100644
--- a/src/engine/SCons/Tool/intelc.py
+++ b/src/engine/SCons/Tool/intelc.py
@@ -41,11 +41,14 @@ is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or
(os.environ.has_key('PROCESSOR_ARCHITEW6432') and
os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64'))
is_linux = sys.platform == 'linux2'
+is_mac = sys.platform == 'darwin'
if is_windows:
import SCons.Tool.msvc
elif is_linux:
import SCons.Tool.gcc
+elif is_mac:
+ import SCons.Tool.gcc
import SCons.Util
import SCons.Warnings
@@ -106,6 +109,11 @@ def check_abi(abi):
'x86_64' : 'x86_64',
'em64t' : 'x86_64',
'amd64' : 'x86_64'}
+ if is_mac:
+ valid_abis = {'ia32' : 'ia32',
+ 'x86' : 'ia32',
+ 'x86_64' : 'x86_64',
+ 'em64t' : 'x86_64'}
try:
abi = valid_abis[abi]
except KeyError:
@@ -196,8 +204,22 @@ def get_all_compiler_versions():
if ok:
versions.append(subkey)
else:
- # Registry points to nonexistent dir. Ignore this version.
- print "Ignoring "+str(get_intel_registry_value('ProductDir', subkey, 'IA32'))
+ try:
+ # Registry points to nonexistent dir. Ignore this
+ # version.
+ value = get_intel_registry_value('ProductDir', subkey, 'IA32')
+ except MissingRegistryError, e:
+
+ # Registry key is left dangling (potentially
+ # after uninstalling).
+
+ print \
+ "scons: *** Ignoring the registry key for the Intel compiler version %s.\n" \
+ "scons: *** It seems that the compiler was uninstalled and that the registry\n" \
+ "scons: *** was not cleaned up properly.\n" % subkey
+ else:
+ print "scons: *** Ignoring "+str(value)
+
i = i + 1
except EnvironmentError:
# no more subkeys
@@ -205,11 +227,22 @@ def get_all_compiler_versions():
elif is_linux:
for d in glob.glob('/opt/intel_cc_*'):
# Typical dir here is /opt/intel_cc_80.
- versions.append(re.search(r'cc_(.*)$', d).group(1))
+ m = re.search(r'cc_(.*)$', d)
+ if m:
+ versions.append(m.group(1))
+ for d in glob.glob('/opt/intel/cc*/*'):
+ # Typical dir here is /opt/intel/cc/9.0 for IA32,
+ # /opt/intel/cce/9.0 for EMT64 (AMD64)
+ m = re.search(r'([0-9.]+)$', d)
+ if m:
+ versions.append(m.group(1))
+ elif is_mac:
for d in glob.glob('/opt/intel/cc*/*'):
# Typical dir here is /opt/intel/cc/9.0 for IA32,
# /opt/intel/cce/9.0 for EMT64 (AMD64)
- versions.append(re.search(r'([0-9.]+)$', d).group(1))
+ m = re.search(r'([0-9.]+)$', d)
+ if m:
+ versions.append(m.group(1))
versions = uniquify(versions) # remove dups
versions.sort(vercmp)
return versions
@@ -229,7 +262,7 @@ def get_intel_compiler_top(version, abi):
if not os.path.exists(os.path.join(top, "Bin", "icl.exe")):
raise MissingDirError, \
"Can't find Intel compiler in %s"%(top)
- elif is_linux:
+ elif is_mac or is_linux:
# first dir is new (>=9.0) style, second is old (8.0) style.
dirs=('/opt/intel/cc/%s', '/opt/intel_cc_%s')
if abi == 'x86_64':
@@ -256,7 +289,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
If topdir is used, version and abi are ignored.
verbose: (int) if >0, prints compiler version used.
"""
- if not (is_linux or is_windows):
+ if not (is_mac or is_linux or is_windows):
# can't handle this platform
return
@@ -264,6 +297,8 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
SCons.Tool.msvc.generate(env)
elif is_linux:
SCons.Tool.gcc.generate(env)
+ elif is_mac:
+ SCons.Tool.gcc.generate(env)
# if version is unspecified, use latest
vlist = get_all_compiler_versions()
@@ -284,7 +319,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
# alternatives are ia64 for Itanium, or amd64 or em64t or x86_64 (all synonyms here)
abi = check_abi(abi)
if abi is None:
- if is_linux:
+ if is_mac or is_linux:
# Check if we are on 64-bit linux, default to 64 then.
uname_m = os.uname()[4]
if uname_m == 'x86_64':
@@ -308,7 +343,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
# on $PATH and the user is importing their env.
class ICLTopDirWarning(SCons.Warnings.Warning):
pass
- if is_linux and not env.Detect('icc') or \
+ if (is_mac or is_linux) and not env.Detect('icc') or \
is_windows and not env.Detect('icl'):
SCons.Warnings.enableWarningClass(ICLTopDirWarning)
@@ -325,11 +360,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
if topdir:
if verbose:
- print "Intel C compiler: using version '%s' (%g), abi %s, in '%s'"%\
- (version, linux_ver_normalize(version),abi,topdir)
+ print "Intel C compiler: using version %s (%g), abi %s, in '%s'"%\
+ (repr(version), linux_ver_normalize(version),abi,topdir)
if is_linux:
# Show the actual compiler version by running the compiler.
os.system('%s/bin/icc --version'%topdir)
+ if is_mac:
+ # Show the actual compiler version by running the compiler.
+ os.system('%s/bin/icc --version'%topdir)
env['INTEL_C_COMPILER_TOP'] = topdir
if is_linux:
@@ -339,11 +377,22 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
'LD_LIBRARY_PATH' : 'lib'}
for p in paths:
env.PrependENVPath(p, os.path.join(topdir, paths[p]))
+ if is_mac:
+ paths={'INCLUDE' : 'include',
+ 'LIB' : 'lib',
+ 'PATH' : 'bin',
+ 'LD_LIBRARY_PATH' : 'lib'}
+ for p in paths:
+ env.PrependENVPath(p, os.path.join(topdir, paths[p]))
if is_windows:
# env key reg valname default subdir of top
paths=(('INCLUDE', 'IncludeDir', 'Include'),
('LIB' , 'LibDir', 'Lib'),
('PATH' , 'BinDir', 'Bin'))
+ # We are supposed to ignore version if topdir is set, so set
+ # it to the emptry string if it's not already set.
+ if version is None:
+ version = ''
# Each path has a registry entry, use that or default to subdir
for p in paths:
try:
@@ -392,7 +441,9 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
licdir = None
for ld in [envlicdir, reglicdir]:
- if ld and os.path.exists(ld):
+ # If the string contains an '@', then assume it's a network
+ # license (port@system) and good by definition.
+ if ld and (string.find(ld, '@') != -1 or os.path.exists(ld)):
licdir = ld
break
if not licdir:
@@ -409,7 +460,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
env['ENV']['INTEL_LICENSE_FILE'] = licdir
def exists(env):
- if not (is_linux or is_windows):
+ if not (is_mac or is_linux or is_windows):
# can't handle this platform
return 0
@@ -424,6 +475,8 @@ def exists(env):
return env.Detect('icl')
elif is_linux:
return env.Detect('icc')
+ elif is_mac:
+ return env.Detect('icc')
return detected
# end of file
diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py
index 4f221c0..6594ecc 100644
--- a/src/engine/SCons/Tool/jar.py
+++ b/src/engine/SCons/Tool/jar.py
@@ -38,19 +38,32 @@ import SCons.Util
def jarSources(target, source, env, for_signature):
"""Only include sources that are not a manifest file."""
- jarchdir = env.subst('$JARCHDIR', target=target, source=source)
- if jarchdir:
- jarchdir = env.fs.Dir(jarchdir)
+ try:
+ env['JARCHDIR']
+ except KeyError:
+ jarchdir_set = False
+ else:
+ jarchdir_set = True
+ jarchdir = env.subst('$JARCHDIR', target=target, source=source)
+ if jarchdir:
+ jarchdir = env.fs.Dir(jarchdir)
result = []
for src in source:
contents = src.get_contents()
if contents[:16] != "Manifest-Version":
- if jarchdir:
+ if jarchdir_set:
+ _chdir = jarchdir
+ else:
+ try:
+ _chdir = src.attributes.java_classdir
+ except AttributeError:
+ _chdir = None
+ if _chdir:
# If we are changing the dir with -C, then sources should
# be relative to that directory.
- src = SCons.Subst.Literal(src.get_path(jarchdir))
+ src = SCons.Subst.Literal(src.get_path(_chdir))
result.append('-C')
- result.append(jarchdir)
+ result.append(_chdir)
result.append(src)
return result
diff --git a/src/engine/SCons/Tool/jar.xml b/src/engine/SCons/Tool/jar.xml
index a0d730e..9e8fefa 100644
--- a/src/engine/SCons/Tool/jar.xml
+++ b/src/engine/SCons/Tool/jar.xml
@@ -34,6 +34,11 @@ If the &cv-link-JARCHDIR; value is set, the
command will change to the specified directory using the
<option>-C</option>
option.
+If &cv-JARCHDIR; is not set explicitly,
+&SCons; will use the top of any subdirectory tree
+in which Java <filename>.class</filename>
+were built by the &b-link-Java; Builder.
+
If the contents any of the source files begin with the string
<literal>Manifest-Version</literal>,
the file is assumed to be a manifest
diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py
index be1a81a..b60aa87 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -44,6 +44,11 @@ def smart_link(source, target, env, for_signature):
return '$CXX'
return '$CC'
+def shlib_emitter(target, source, env):
+ for tgt in target:
+ tgt.attributes.shared = 1
+ return (target, source)
+
def generate(env):
"""Add Builders and construction variables for gnulink to an Environment."""
SCons.Tool.createSharedLibBuilder(env)
@@ -54,14 +59,14 @@ def generate(env):
env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
# don't set up the emitter, cause AppendUnique will generate a list
# starting with None :-(
- #env['SHLIBEMITTER']= None
+ env.Append(SHLIBEMITTER = [shlib_emitter])
env['SMARTLINK'] = smart_link
env['LINK'] = "$SMARTLINK"
env['LINKFLAGS'] = SCons.Util.CLVar('')
env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
env['LIBDIRPREFIX']='-L'
env['LIBDIRSUFFIX']=''
- env['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIX, LIBSUFFIX, __env__)}'
+ env['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}'
env['LIBLINKPREFIX']='-l'
env['LIBLINKSUFFIX']=''
diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py
index 25f3564..42eabaf 100644
--- a/src/engine/SCons/Tool/mslink.py
+++ b/src/engine/SCons/Tool/mslink.py
@@ -76,6 +76,9 @@ def windowsShlinkSources(target, source, env, for_signature):
def windowsLibEmitter(target, source, env):
SCons.Tool.msvc.validate_vars(env)
+ extratargets = []
+ extrasources = []
+
dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX")
no_import_lib = env.get('no_import_lib', 0)
@@ -87,38 +90,44 @@ def windowsLibEmitter(target, source, env):
not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"):
# append a def file to the list of sources
- source.append(env.ReplaceIxes(dll,
- "SHLIBPREFIX", "SHLIBSUFFIX",
- "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))
+ extrasources.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))
version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0'))
if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0):
# MSVC 8 automatically generates .manifest files that must be installed
- target.append(env.ReplaceIxes(dll,
- "SHLIBPREFIX", "SHLIBSUFFIX",
- "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX"))
+ extratargets.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX"))
if env.has_key('PDB') and env['PDB']:
pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
- target.append(pdb)
+ extratargets.append(pdb)
target[0].attributes.pdb = pdb
if not no_import_lib and \
not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"):
# Append an import library to the list of targets.
- target.append(env.ReplaceIxes(dll,
- "SHLIBPREFIX", "SHLIBSUFFIX",
- "LIBPREFIX", "LIBSUFFIX"))
+ extratargets.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "LIBPREFIX", "LIBSUFFIX"))
# and .exp file is created if there are exports from a DLL
- target.append(env.ReplaceIxes(dll,
- "SHLIBPREFIX", "SHLIBSUFFIX",
- "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))
+ extratargets.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))
- return (target, source)
+ return (target+extratargets, source+extrasources)
def prog_emitter(target, source, env):
SCons.Tool.msvc.validate_vars(env)
+ extratargets = []
+
exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX")
if not exe:
raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX")
@@ -126,16 +135,17 @@ def prog_emitter(target, source, env):
version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0'))
if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0):
# MSVC 8 automatically generates .manifest files that have to be installed
- target.append(env.ReplaceIxes(exe,
- "PROGPREFIX", "PROGSUFFIX",
- "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX"))
+ extratargets.append(
+ env.ReplaceIxes(exe,
+ "PROGPREFIX", "PROGSUFFIX",
+ "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX"))
if env.has_key('PDB') and env['PDB']:
pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
- target.append(pdb)
+ extratargets.append(pdb)
target[0].attributes.pdb = pdb
- return (target,source)
+ return (target+extratargets,source)
def RegServerFunc(target, source, env):
if env.has_key('register') and env['register']:
diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py
index 105f42e..d67cddb 100644
--- a/src/engine/SCons/Tool/qt.py
+++ b/src/engine/SCons/Tool/qt.py
@@ -66,7 +66,7 @@ def checkMocIncluded(target, source, env):
cpp = source[0]
# looks like cpp.includes is cleared before the build stage :-(
# not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/
- path = SCons.Defaults.CScan.path_function(env, moc.cwd)
+ path = SCons.Defaults.CScan.path(env, moc.cwd)
includes = SCons.Defaults.CScan(cpp, env, path)
if not moc in includes:
SCons.Warnings.warn(
diff --git a/src/engine/SCons/Tool/rmic.py b/src/engine/SCons/Tool/rmic.py
index 4b48e0b..ed5c8ee 100644
--- a/src/engine/SCons/Tool/rmic.py
+++ b/src/engine/SCons/Tool/rmic.py
@@ -79,9 +79,13 @@ def emit_rmic_classes(target, source, env):
s.attributes.java_classname = classname
slist.append(s)
+ stub_suffixes = ['_Stub']
+ if env.get('JAVAVERSION') == '1.4':
+ stub_suffixes.append('_Skel')
+
tlist = []
for s in source:
- for suff in ['_Skel', '_Stub']:
+ for suff in stub_suffixes:
fname = string.replace(s.attributes.java_classname, '.', os.sep) + \
suff + class_suffix
t = target[0].File(fname)
diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py
index 8ca1b89..eba49a7 100644
--- a/src/engine/SCons/Tool/swig.py
+++ b/src/engine/SCons/Tool/swig.py
@@ -50,7 +50,8 @@ def swigSuffixEmitter(env, source):
else:
return '$SWIGCFILESUFFIX'
-_reModule = re.compile(r'%module\s+(.+)')
+# Match '%module test', as well as '%module(directors="1") test'
+_reModule = re.compile(r'%module(?:\s*\(.*\))?\s+(.+)')
def _swigEmitter(target, source, env):
swigflags = env.subst("$SWIGFLAGS", target=target, source=source)
diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py
index bbae25e..c3156a3 100644
--- a/src/engine/SCons/Tool/tex.py
+++ b/src/engine/SCons/Tool/tex.py
@@ -42,7 +42,7 @@ import SCons.Node
import SCons.Node.FS
import SCons.Util
-warning_rerun_re = re.compile("^LaTeX Warning:.*Rerun", re.MULTILINE)
+warning_rerun_re = re.compile('(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)', re.MULTILINE)
rerun_citations_str = "^LaTeX Warning:.*\n.*Rerun to get citations correct"
rerun_citations_re = re.compile(rerun_citations_str, re.MULTILINE)
@@ -76,26 +76,52 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
basename = SCons.Util.splitext(str(source[0]))[0]
basedir = os.path.split(str(source[0]))[0]
-
- # Notice that all the filenames are not prefixed with the basedir.
- # That's because the *COM variables have the cd command in the prolog.
-
- bblfilename = basename + '.bbl'
+ basefile = os.path.split(str(basename))[1]
+ abspath = os.path.abspath(basedir)
+ targetbase = SCons.Util.splitext(str(target[0]))[0]
+ targetdir = os.path.split(str(target[0]))[0]
+
+ # Not sure if these environment changes should go here or make the
+ # user do them I undo all but TEXPICTS but there is still the side
+ # effect of creating the empty (':') entries in the environment.
+
+ def modify_env_var(env, var, abspath):
+ try:
+ save = env['ENV'][var]
+ except KeyError:
+ save = ':'
+ env['ENV'][var] = ''
+ if SCons.Util.is_List(env['ENV'][var]):
+ env['ENV'][var] = [abspath] + env['ENV'][var]
+ else:
+ env['ENV'][var] = abspath + os.pathsep + env['ENV'][var]
+ return save
+
+ texinputs_save = modify_env_var(env, 'TEXINPUTS', abspath)
+ bibinputs_save = modify_env_var(env, 'BIBINPUTS', abspath)
+ bstinputs_save = modify_env_var(env, 'BSTINPUTS', abspath)
+ texpicts_save = modify_env_var(env, 'TEXPICTS', abspath)
+
+ # Create these file names with the target directory since they will
+ # be made there. That's because the *COM variables have the cd
+ # command in the prolog.
+
+ bblfilename = os.path.join(targetdir, basefile + '.bbl')
bblContents = ""
if os.path.exists(bblfilename):
bblContents = open(bblfilename, "rb").read()
- idxfilename = basename + '.idx'
+ idxfilename = os.path.join(targetdir, basefile + '.idx')
idxContents = ""
if os.path.exists(idxfilename):
idxContents = open(idxfilename, "rb").read()
- tocfilename = basename + '.toc'
+ tocfilename = os.path.join(targetdir, basefile + '.toc')
tocContents = ""
if os.path.exists(tocfilename):
tocContents = open(tocfilename, "rb").read()
- # Run LaTeX once to generate a new aux file.
+ # Run LaTeX once to generate a new aux file and log file.
XXXLaTeXAction(target, source, env)
# Decide if various things need to be run, or run again. We check
@@ -104,7 +130,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
# with stubs that don't necessarily generate all of the same files.
# Read the log file to find all .aux files
- logfilename = basename + '.log'
+ logfilename = os.path.join(targetbase + '.log')
auxfiles = []
if os.path.exists(logfilename):
content = open(logfilename, "rb").read()
@@ -112,10 +138,11 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
# Now decide if bibtex will need to be run.
for auxfilename in auxfiles:
- if os.path.exists(os.path.join(basedir, auxfilename)):
- content = open(os.path.join(basedir, auxfilename), "rb").read()
+ target_aux = os.path.join(targetdir, auxfilename)
+ if os.path.exists(target_aux):
+ content = open(target_aux, "rb").read()
if string.find(content, "bibdata") != -1:
- bibfile = env.fs.File(basename)
+ bibfile = env.fs.File(targetbase)
BibTeXAction(bibfile, bibfile, env)
break
@@ -131,7 +158,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
# Now decide if latex will need to be run again due to index.
if os.path.exists(idxfilename) and idxContents != open(idxfilename, "rb").read():
# We must run makeindex
- idxfile = env.fs.File(basename)
+ idxfile = env.fs.File(targetbase)
MakeIndexAction(idxfile, idxfile, env)
must_rerun_latex = 1
@@ -139,7 +166,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
XXXLaTeXAction(target, source, env)
# Now decide if latex needs to be run yet again to resolve warnings.
- logfilename = basename + '.log'
+ logfilename = targetbase + '.log'
for _ in range(int(env.subst('$LATEXRETRIES'))):
if not os.path.exists(logfilename):
break
@@ -149,6 +176,15 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
not undefined_references_re.search(content):
break
XXXLaTeXAction(target, source, env)
+
+ env['ENV']['TEXINPUTS'] = texinputs_save
+ env['ENV']['BIBINPUTS'] = bibinputs_save
+ env['ENV']['BSTINPUTS'] = bibinputs_save
+
+ # The TEXPICTS enviroment variable is needed by a dvi -> pdf step
+ # later on Mac OSX so leave it,
+ # env['ENV']['TEXPICTS'] = texpicts_save
+
return 0
def LaTeXAuxAction(target = None, source= None, env=None):
@@ -176,27 +212,29 @@ def TeXLaTeXFunction(target = None, source= None, env=None):
def tex_emitter(target, source, env):
base = SCons.Util.splitext(str(source[0]))[0]
- target.append(base + '.aux')
- env.Precious(base + '.aux')
- target.append(base + '.log')
+ targetbase = SCons.Util.splitext(str(target[0]))[0]
+
+ target.append(targetbase + '.aux')
+ env.Precious(targetbase + '.aux')
+ target.append(targetbase + '.log')
for f in source:
content = f.get_contents()
if tableofcontents_re.search(content):
- target.append(base + '.toc')
- env.Precious(base + '.toc')
+ target.append(targetbase + '.toc')
+ env.Precious(targetbase + '.toc')
if makeindex_re.search(content):
- target.append(base + '.ilg')
- target.append(base + '.ind')
- target.append(base + '.idx')
- env.Precious(base + '.idx')
+ target.append(targetbase + '.ilg')
+ target.append(targetbase + '.ind')
+ target.append(targetbase + '.idx')
+ env.Precious(targetbase + '.idx')
if bibliography_re.search(content):
- target.append(base + '.bbl')
- env.Precious(base + '.bbl')
- target.append(base + '.blg')
+ target.append(targetbase + '.bbl')
+ env.Precious(targetbase + '.bbl')
+ target.append(targetbase + '.blg')
- # read log file to get all output file (include .aux files)
- logfilename = base + '.log'
- dir, base_nodir = os.path.split(base)
+ # read log file to get all .aux files
+ logfilename = targetbase + '.log'
+ dir, base_nodir = os.path.split(targetbase)
if os.path.exists(logfilename):
content = open(logfilename, "rb").read()
out_files = openout_re.findall(content)
diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py
index 34f60cb..0b648e8 100644
--- a/src/engine/SCons/Tool/yacc.py
+++ b/src/engine/SCons/Tool/yacc.py
@@ -54,7 +54,7 @@ def _yaccEmitter(target, source, env, ysuf, hsuf):
# If -d is specified on the command line, yacc will emit a .h
# or .hpp file with the same name as the .c or .cpp output file.
if '-d' in flags:
- target.append(targetBase + env.subst(hsuf))
+ target.append(targetBase + env.subst(hsuf, target=target, source=source))
# If -g is specified on the command line, yacc will emit a .vcg
# file with the same base name as the .y, .yacc, .ym or .yy file.
@@ -108,7 +108,14 @@ def generate(env):
env['YACCFLAGS'] = SCons.Util.CLVar('')
env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES'
env['YACCHFILESUFFIX'] = '.h'
- env['YACCHXXFILESUFFIX'] = '.hpp'
+
+ if env['PLATFORM'] == 'darwin':
+ # Bison on Mac OS X just appends ".h" to the generated target .cc
+ # or .cpp file name. Hooray for delayed expansion of variables.
+ env['YACCHXXFILESUFFIX'] = '${TARGET.suffix}.h'
+ else:
+ env['YACCHXXFILESUFFIX'] = '.hpp'
+
env['YACCVCGFILESUFFIX'] = '.vcg'
def exists(env):
diff --git a/src/engine/SCons/Tool/yacc.xml b/src/engine/SCons/Tool/yacc.xml
index 2db0603..aa648b1 100644
--- a/src/engine/SCons/Tool/yacc.xml
+++ b/src/engine/SCons/Tool/yacc.xml
@@ -87,7 +87,13 @@ file with the specified suffix,
it exists to allow you to specify
what suffix the parser generator will use of its own accord.
The default value is
-<filename>.hpp</filename>.
+<filename>.hpp</filename>,
+except on Mac OS X,
+where the default is
+<filename>${TARGET.suffix}.h</filename>.
+because the default &bison; parser generator just
+appends <filename>.h</filename>
+to the name of the generated C++ file.
</summary>
</cvar>