From 852e7119fb7c6d6ccc2a4cb2c159445376b97fef Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Sun, 24 Aug 2003 14:44:10 +0000 Subject: Support for additional UNIX variants: (Christian Engel) --- bin/files | 4 ++ doc/man/scons.1 | 29 +++++++++++-- src/CHANGES.txt | 10 +++++ src/engine/MANIFEST.in | 4 ++ src/engine/SCons/Platform/aix.py | 24 +++++++++++ src/engine/SCons/Tool/__init__.py | 41 ++++++++++-------- src/engine/SCons/Tool/aixc++.py | 53 ++++++++++++++++++++++++ src/engine/SCons/Tool/aixcc.py | 38 ++++++++++++----- src/engine/SCons/Tool/aixf77.py | 33 ++++++++++++--- src/engine/SCons/Tool/aixlink.py | 29 +++++++++---- src/engine/SCons/Tool/ar.py | 3 -- src/engine/SCons/Tool/c++.py | 87 +++++++++++++++++++++++++++++++++++++++ src/engine/SCons/Tool/cc.py | 20 ++------- src/engine/SCons/Tool/g++.py | 48 ++++++++++++++------- src/engine/SCons/Tool/gnulink.py | 33 ++------------- src/engine/SCons/Tool/hpc++.py | 44 ++++++++++++++++++++ src/engine/SCons/Tool/hplink.py | 21 ++++++++-- src/engine/SCons/Tool/link.py | 20 +++++++-- src/engine/SCons/Tool/sunc++.py | 58 ++++++++++++++++++++++++++ src/engine/SCons/Tool/sunlink.py | 15 +++++-- test/ToolSurrogate.py | 2 +- test/import.py | 35 ++++++++++++---- 22 files changed, 526 insertions(+), 125 deletions(-) create mode 100644 src/engine/SCons/Tool/aixc++.py create mode 100644 src/engine/SCons/Tool/c++.py create mode 100644 src/engine/SCons/Tool/hpc++.py create mode 100644 src/engine/SCons/Tool/sunc++.py diff --git a/bin/files b/bin/files index a2facbc..252c98f 100644 --- a/bin/files +++ b/bin/files @@ -31,11 +31,13 @@ ./SCons/Sig/__init__.py ./SCons/Taskmaster.py ./SCons/Tool/__init__.py +./SCons/Tool/aixc++.py ./SCons/Tool/aixcc.py ./SCons/Tool/aixf77.py ./SCons/Tool/aixlink.py ./SCons/Tool/ar.py ./SCons/Tool/as.py +./SCons/Tool/c++.py ./SCons/Tool/cc.py ./SCons/Tool/default.py ./SCons/Tool/dvipdf.py @@ -46,6 +48,7 @@ ./SCons/Tool/gas.py ./SCons/Tool/gcc.py ./SCons/Tool/gnulink.py +./SCons/Tool/hpc++.py ./SCons/Tool/hpcc.py ./SCons/Tool/hplink.py ./SCons/Tool/icc.py @@ -76,6 +79,7 @@ ./SCons/Tool/sgicc.py ./SCons/Tool/sgilink.py ./SCons/Tool/sunar.py +./SCons/Tool/sunc++.py ./SCons/Tool/suncc.py ./SCons/Tool/sunlink.py ./SCons/Tool/swig.py diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 640dc67..3919a6e 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -893,24 +893,36 @@ be redetected. SCons supports the following tool specifications out of the box: .ES 386asm +aixc++ +aixcc +aixf77 +aixlink ar +as +c++ +cc dvipdf dvips +f77 g++ g77 +gas +gcc +gnulink gs +hpc++ +hpcc +hplink icc icl ifl ilink -gas -gcc -gnulink jar javac javah latex lex +link linkloc m4 masm @@ -929,6 +941,7 @@ sgiar sgicc sgilink sunar +sunc++ suncc sunlink swig @@ -2332,6 +2345,11 @@ SCons also treats (upper case) files as C files. +.IP CCVERSION +The version number of the C compiler. +This may or may not be set, +depending on the specific C compiler being used. + .IP _concat A function used to produce variables like $_CPPINCFLAGS. It takes five arguments: a prefix to concatenate onto each element, a list of @@ -2554,6 +2572,11 @@ are included on this command line. .IP CXXFLAGS General options that are passed to the C++ compiler. +.IP CXXVERSION +The version number of the C++ compiler. +This may or may not be set, +depending on the specific C++ compiler being used. + .IP Dir A function that converts a file name into a Dir instance relative to the target being built. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 3619167..61cdb44 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -10,6 +10,16 @@ RELEASE X.XX - XXX + From Christian Engel: + + - Support more flexible inclusion of separate C and C++ compilers. + + - Use package management tools on AIX and Solaris to find where + the comilers are installed, and what version they are. + + - Add support for CCVERSION and CXXVERSION variables for a number + of C and C++ compilers. + From Steven Knight: - The -Q option suppressed too many messages; fix it so that it only diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index b97cd29..4c22f1d 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -39,12 +39,14 @@ SCons/Sig/TimeStamp.py SCons/Taskmaster.py SCons/Tool/__init__.py SCons/Tool/386asm.py +SCons/Tool/aixc++.py SCons/Tool/aixcc.py SCons/Tool/aixf77.py SCons/Tool/aixlink.py SCons/Tool/ar.py SCons/Tool/as.py SCons/Tool/BitKeeper.py +SCons/Tool/c++.py SCons/Tool/cc.py SCons/Tool/CVS.py SCons/Tool/default.py @@ -57,6 +59,7 @@ SCons/Tool/gas.py SCons/Tool/gcc.py SCons/Tool/gnulink.py SCons/Tool/gs.py +SCons/Tool/hpc++.py SCons/Tool/hpcc.py SCons/Tool/hplink.py SCons/Tool/jar.py @@ -92,6 +95,7 @@ SCons/Tool/sgiar.py SCons/Tool/sgicc.py SCons/Tool/sgilink.py SCons/Tool/sunar.py +SCons/Tool/sunc++.py SCons/Tool/suncc.py SCons/Tool/sunlink.py SCons/Tool/Subversion.py diff --git a/src/engine/SCons/Platform/aix.py b/src/engine/SCons/Platform/aix.py index 542f548..727aa9b 100644 --- a/src/engine/SCons/Platform/aix.py +++ b/src/engine/SCons/Platform/aix.py @@ -32,7 +32,31 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os +import string + import posix +def get_xlc(env, xlc, xlc_r, packages): + # Use the AIX package installer tool lslpp to figure out where a + # given xl* compiler is installed and what version it is. + xlcPath = None + xlcVersion = None + + try: + xlc = env['CC'] + except KeyError: + xlc = 'xlc' + for package in packages: + cmd = "lslpp -fc " + package + " 2>/dev/null | egrep '" + xlc + "([^-_a-zA-Z0-9].*)?$'" + line = os.popen(cmd).readline() + if line: + v, p = string.split(line, ':')[1:3] + xlcVersion = string.split(v)[1] + xlcPath = string.split(p)[0] + xlcPath = xlcPath[:xlcPath.rindex('/')] + break + return (xlcPath, xlc, xlc_r, xlcVersion) + def generate(env): posix.generate(env) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 3aa5df8..9ddfdf3 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -65,8 +65,8 @@ def Tool(name): sys.modules['SCons.Tool'].__path__) mod = imp.load_module(full_name, file, path, desc) setattr(SCons.Tool, name, mod) - except ImportError: - raise SCons.Errors.UserError, "No tool named '%s'" % name + except ImportError, e: + raise SCons.Errors.UserError, "No tool named '%s': %s" % (name, e) if file: file.close() spec = ToolSpec(name) @@ -231,49 +231,56 @@ def tool_list(platform, env): if str(platform) == 'win32': "prefer Microsoft tools on Windows" linkers = ['mslink', 'gnulink', 'ilink', 'linkloc' ] - c_compilers = ['msvc', 'mingw', 'gcc', 'icl', 'icc' ] + c_compilers = ['msvc', 'mingw', 'gcc', 'icl', 'icc', 'cc' ] + cxx_compilers = ['msvc', 'icc', 'g++', 'c++'] assemblers = ['masm', 'nasm', 'gas', '386asm' ] fortran_compilers = ['g77', 'ifl'] ars = ['mslib', 'ar'] elif str(platform) == 'os2': "prefer IBM tools on OS/2" linkers = ['ilink', 'gnulink', 'mslink'] - c_compilers = ['icc', 'gcc', 'msvc'] + c_compilers = ['icc', 'gcc', 'msvc', 'cc'] + cxx_compilers = ['icc', 'g++', 'msvc', 'c++'] assemblers = ['nasm', 'masm', 'gas'] fortran_compilers = ['ifl', 'g77'] ars = ['ar', 'mslib'] elif str(platform) == 'irix': "prefer MIPSPro on IRIX" linkers = ['sgilink', 'gnulink'] - c_compilers = ['sgicc', 'gcc'] + c_compilers = ['sgicc', 'gcc', 'cc'] + cxx_compilers = ['sgicc', 'g++', 'c++'] assemblers = ['as', 'gas'] fortran_compilers = ['f77', 'g77'] ars = ['sgiar'] elif str(platform) == 'sunos': "prefer Forte tools on SunOS" linkers = ['sunlink', 'gnulink'] - c_compilers = ['suncc', 'gcc'] + c_compilers = ['suncc', 'gcc', 'cc'] + cxx_compilers = ['sunc++', 'g++', 'c++'] assemblers = ['as', 'gas'] fortran_compilers = ['f77', 'g77'] ars = ['sunar'] elif str(platform) == 'hpux': "prefer aCC tools on HP-UX" linkers = ['hplink', 'gnulink'] - c_compilers = ['hpcc', 'gcc'] + c_compilers = ['hpcc', 'gcc', 'cc'] + cxx_compilers = ['hpc++', 'g++', 'c++'] assemblers = ['as', 'gas'] fortran_compilers = ['f77', 'g77'] ars = ['ar'] elif str(platform) == 'aix': "prefer AIX Visual Age tools on AIX" linkers = ['aixlink', 'gnulink'] - c_compilers = ['aixcc', 'gcc'] + c_compilers = ['aixcc', 'gcc', 'cc'] + cxx_compilers = ['aixc++', 'g++', 'c++'] assemblers = ['as', 'gas'] fortran_compilers = ['aixf77', 'g77'] ars = ['ar'] else: "prefer GNU tools on all other platforms" linkers = ['gnulink', 'mslink', 'ilink'] - c_compilers = ['gcc', 'msvc', 'icc'] + c_compilers = ['gcc', 'msvc', 'icc', 'cc'] + cxx_compilers = ['g++', 'msvc', 'icc', 'c++'] assemblers = ['gas', 'nasm', 'masm'] fortran_compilers = ['g77', 'ifl'] ars = ['ar', 'mslib'] @@ -284,25 +291,23 @@ def tool_list(platform, env): # moved into the tool files themselves. if c_compiler and c_compiler == 'mingw': # MinGW contains a linker, C compiler, C++ compiler, - # Fortran compiler, archiver and assember: + # Fortran compiler, archiver and assembler: + cxx_compiler = None linker = None assembler = None fortran_compiler = None ar = None - cxx_compiler = None else: + # Don't use g++ if the C compiler has built-in C++ support: + if c_compiler in ('msvc', 'icc', 'sgicc'): + cxx_compiler = None + else: + cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0] linker = FindTool(linkers, env) or linkers[0] assembler = FindTool(assemblers, env) or assemblers[0] fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0] ar = FindTool(ars, env) or ars[0] - # Don't use g++ if the C compiler has built-in C++ support: - if c_compiler and (c_compiler == 'msvc' or c_compiler == 'icc' or - c_compiler == 'sgicc'): - cxx_compiler = None - else: - cxx_compiler = FindTool(['g++'], env) - other_tools = FindAllTools(['BitKeeper', 'CVS', 'dvipdf', 'dvips', 'gs', 'jar', 'javac', 'javah', diff --git a/src/engine/SCons/Tool/aixc++.py b/src/engine/SCons/Tool/aixc++.py new file mode 100644 index 0000000..634b40e --- /dev/null +++ b/src/engine/SCons/Tool/aixc++.py @@ -0,0 +1,53 @@ +"""SCons.Tool.aixc++ + +Tool-specific initialization for IBM xlC / Visual Age C++ 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. + +""" +__revision__ = "" + +import os.path + +import SCons.Platform.aix +import SCons.Script.SConscript + +cplusplus = __import__('c++', globals(), locals(), []) + +packages = ['vacpp.cmp.core', 'vacpp.cmp.batch', 'vacpp.cmp.C', 'ibmcxx.cmp'] + +def get_xlc(env): + xlc = env.get('CXX', 'xlC') + xlc_r = env.get('SHCXX', 'xlC_r') + return SCons.Platform.aix.get_xlc(env, xlc, xlc_r, packages) + +def smart_cxxflags(source, target, env, for_signature): + build_dir = SCons.Script.SConscript.GetBuildPath() + if build_dir: + return '-qtempinc=' + os.path.join(build_dir, 'tempinc') + return '' + +def generate(env): + """Add Builders and construction variables for xlC / Visual Age + suite to an Environment.""" + path, _cxx, _shcxx, version = get_xlc(env) + if path: + _cxx = os.path.join(path, cxx) + _shcxx = os.path.join(path, shcxx) + + cplusplus.generate(env) + + env['CXX'] = _cxx + env['SHCXX'] = _shcxx + env['CXXVERSION'] = version + env['SHOBJSUFFIX'] = '.pic.o' + +def exists(env): + path, _cxx, _shcxx, version = get_xlc(env) + if path and _cxx: + xlc = os.path.join(path, _cxx) + if os.path.exists(xlc): + return xlc + return None diff --git a/src/engine/SCons/Tool/aixcc.py b/src/engine/SCons/Tool/aixcc.py index ef5b280..f4ff5a2 100644 --- a/src/engine/SCons/Tool/aixcc.py +++ b/src/engine/SCons/Tool/aixcc.py @@ -1,6 +1,6 @@ """SCons.Tool.aixcc -Tool-specific initialization for IBM Visual Age C++ and C compilers. +Tool-specific initialization for IBM xlc / Visual Age C compiler. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() @@ -32,19 +32,37 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os.path + +import SCons.Platform.aix + import cc +packages = ['vac.C', 'ibmcxx.cmp'] + +def get_xlc(env): + xlc = env.get('CC', 'xlc') + xlc_r = env.get('SHCC', 'xlc_r') + return SCons.Platform.aix.get_xlc(env, xlc, xlc_r, packages) + def generate(env): - """ - Add Builders and construction variables for Visual Age C and C++ compilers - to an Environment. - """ + """Add Builders and construction variables for xlc / Visual Age + suite to an Environment.""" + path, _cc, _shcc, version = get_xlc(env) + if path: + _cc = os.path.join(path, cc) + _shcc = os.path.join(path, shcc) + cc.generate(env) - env['CC'] = 'xlc' - env['SHCC'] = 'xlc_r' - env['CXX'] = 'xlC' - env['SHCXX'] = 'xlC_r' + env['CC'] = _cc + env['SHCC'] = _shcc + env['CCVERSION'] = version def exists(env): - return env.Detect('xlC') + path, _cc, _shcc, version = get_xlc(env) + if path and _cc: + xlc = os.path.join(path, _cc) + if os.path.exists(xlc): + return xlc + return None diff --git a/src/engine/SCons/Tool/aixf77.py b/src/engine/SCons/Tool/aixf77.py index 7c8554e..81db28b 100644 --- a/src/engine/SCons/Tool/aixf77.py +++ b/src/engine/SCons/Tool/aixf77.py @@ -32,20 +32,43 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os.path + +import SCons.Platform.aix + import f77 -pcompilers = ['xlf77'] -rcompilers = ['xlf77_r'] +# It would be good to look for the AIX F77 package the same way we're now +# looking for the C and C++ packages. This should be as easy as supplying +# the correct package names in the following list and uncommenting the +# SCons.Platform.aix_get_xlc() call the in the function below. +packages = [] + +def get_xlf77(env): + xlf77 = env.get('F77', 'xlf77') + xlf77_r = env.get('SHF77', 'xlf77_r') + #return SCons.Platform.aix.get_xlc(env, xlf77, xlf77_r, packages) + return (None, xlf77, xlf77_r, None) def generate(env): """ Add Builders and construction variables for the Visual Age FORTRAN compiler to an Environment. """ + path, _f77, _shf77, version = get_xlf77(env) + if path: + _f77 = os.path.join(path, _f77) + _shf77 = os.path.join(path, _shf77) + f77.generate(env) - env['F77'] = env.Detect(pcompilers) or 'f77' - env['SHF77'] = env.Detect(rcompilers) or 'f77' + env['F77'] = _f77 + env['SHF77'] = _shf77 def exists(env): - return env.Detect(pcompilers) + path, _f77, _shf77, version = get_xlf77(env) + if path and _f77: + xlf77 = os.path.join(path, _f77) + if os.path.exists(xlf77): + return xlf77 + return None diff --git a/src/engine/SCons/Tool/aixlink.py b/src/engine/SCons/Tool/aixlink.py index 1209862..d987016 100644 --- a/src/engine/SCons/Tool/aixlink.py +++ b/src/engine/SCons/Tool/aixlink.py @@ -32,10 +32,20 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os +import os.path + +import aixcc import link -plinkers = ['xlC', 'xlc'] -rlinkers = ['xlC_r', 'xlc_r'] +cplusplus = __import__('c++', globals(), locals(), []) + +def smart_linkflags(source, target, env, for_signature): + if cplusplus.iscplusplus(source): + build_dir = env.subst('$BUILDDIR') + if build_dir: + return '-qtempinc=' + os.path.join(build_dir, 'tempinc') + return '' def generate(env): """ @@ -44,10 +54,15 @@ def generate(env): """ link.generate(env) - env['SHLINK'] = env.Detect(rlinkers) or 'cc' - env['SHLINKFLAGS'] = '$LINKFLAGS -qmkshrobj' - env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - env['LINK'] = env.Detect(plinkers) or 'cc' + env['SMARTLINKFLAGS'] = smart_linkflags + env['LINKFLAGS'] = '$SMARTLINKFLAGS' + env['SHLINKFLAGS'] = '$LINKFLAGS -qmkshrobj -qsuppress=1501-218' + env['SHLIBSUFFIX'] = '.a' def exists(env): - return env.Detect(linkers) + path, _cc, _shcc, version = aixcc.get_xlc(env) + if path and _cc: + xlc = os.path.join(path, _cc) + if os.path.exists(xlc): + return xlc + return None diff --git a/src/engine/SCons/Tool/ar.py b/src/engine/SCons/Tool/ar.py index 598b6b7..653836f 100644 --- a/src/engine/SCons/Tool/ar.py +++ b/src/engine/SCons/Tool/ar.py @@ -50,9 +50,6 @@ def generate(env): env['RANLIB'] = ranlib env['RANLIBFLAGS'] = '' env['ARCOM'] = arcom - env['SHLINK'] = '$LINK' - env['SHLINKFLAGS'] = '$LINKFLAGS -shared' - env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' def exists(env): return env.Detect('ar') diff --git a/src/engine/SCons/Tool/c++.py b/src/engine/SCons/Tool/c++.py new file mode 100644 index 0000000..8ede17e --- /dev/null +++ b/src/engine/SCons/Tool/c++.py @@ -0,0 +1,87 @@ +"""SCons.Tool.c++ + +Tool-specific initialization for generic Posix C++ compilers. + +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 (c) 2001, 2002, 2003 Steven Knight +# +# 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__ = "" + +import os.path + +import SCons.Tool +import SCons.Defaults +import SCons.Util + +compilers = ['CC', 'c++'] + +CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++'] +if os.path.normcase('.c') != os.path.normcase('.C'): + CXXSuffixes.append('.C') + +def iscplusplus(source): + if not source: + # Source might be None for unusual cases like SConf. + return 0 + for s in source: + if s.sources: + ext = os.path.splitext(str(s.sources[0]))[1] + if ext in CXXSuffixes: + return 1 + return 0 + +def generate(env): + """ + Add Builders and construction variables for Visual Age C++ compilers + to an Environment. + """ + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + + env['CXX'] = 'c++' + env['CXXFLAGS'] = '$CCFLAGS' + env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = '$CXXFLAGS' + env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + + env['CPPDEFPREFIX'] = '-D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + env['SHOBJSUFFIX'] = '.os' + env['OBJSUFFIX'] = '.o' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 + + env['CXXFILESUFFIX'] = '.cc' + +def exists(env): + return env.Detect(compilers) diff --git a/src/engine/SCons/Tool/cc.py b/src/engine/SCons/Tool/cc.py index 1d37e46..ab51589 100644 --- a/src/engine/SCons/Tool/cc.py +++ b/src/engine/SCons/Tool/cc.py @@ -1,6 +1,6 @@ """SCons.Tool.cc -Tool-specific initialization for generic Posix C++ and C compilers. +Tool-specific initialization for generic Posix C compilers. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() @@ -39,25 +39,18 @@ import SCons.Defaults import SCons.Util CSuffixes = ['.c'] -CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++'] if os.path.normcase('.c') == os.path.normcase('.C'): CSuffixes.append('.C') -else: - CXXSuffixes.append('.C') def generate(env): """ - Add Builders and construction variables for Visual Age C and C++ compilers - to an Environment. + Add Builders and construction variables for C compilers to an Environment. """ static_obj, shared_obj = SCons.Tool.createObjBuilders(env) for suffix in CSuffixes: static_obj.add_action(suffix, SCons.Defaults.CAction) shared_obj.add_action(suffix, SCons.Defaults.ShCAction) - for suffix in CXXSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CXXAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) env['CC'] = 'cc' env['CCFLAGS'] = '' @@ -66,13 +59,6 @@ def generate(env): env['SHCCFLAGS'] = '$CCFLAGS' env['SHCCCOM'] = '$SHCC $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - env['CXX'] = 'c++' - env['CXXFLAGS'] = '$CCFLAGS' - env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - env['SHCXX'] = '$CXX' - env['SHCXXFLAGS'] = '$CXXFLAGS' - env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - env['CPPDEFPREFIX'] = '-D' env['CPPDEFSUFFIX'] = '' env['INCPREFIX'] = '-I' @@ -83,4 +69,4 @@ def generate(env): env['CFILESUFFIX'] = '.c' def exists(env): - return env.Detect('CC') + return env.Detect('cc') diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py index 8c7f1b0..d641a6c 100644 --- a/src/engine/SCons/Tool/g++.py +++ b/src/engine/SCons/Tool/g++.py @@ -34,37 +34,55 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os.path +import string +import re -import cc import SCons.Defaults import SCons.Tool import SCons.Util -compilers = ['g++', 'c++'] +cplusplus = __import__('c++', globals(), locals(), []) + +compilers = ['g++'] def generate(env): """Add Builders and construction variables for g++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - for suffix in cc.CXXSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CXXAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + cplusplus.generate(env) + + env['CXX'] = env.Detect(compilers) - env['CXX'] = env.Detect(compilers) or 'g++' - env['CXXFLAGS'] = '$CCFLAGS' - env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - env['SHCXX'] = '$CXX' + # platform specific settings if env['PLATFORM'] == 'cygwin': env['SHCXXFLAGS'] = '$CXXFLAGS' + elif env['PLATFORM'] == 'aix': + # Original line from Christian Engel added -DPIC: + #env['SHCXXFLAGS'] = '$CXXFLAGS -DPIC -mminimal-toc' + env['SHCXXFLAGS'] = '$CXXFLAGS -mminimal-toc' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + env['SHOBJSUFFIX'] = '$OBJSUFFIX' + elif env['PLATFORM'] == 'hpux': + # Original line from Christian Engel added -DPIC: + #env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC -DPIC' + env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC' + env['SHOBJSUFFIX'] = '.pic.o' + elif env['PLATFORM'] == 'sunos': + # Original line from Christian Engel added -DPIC: + #env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC -DPIC' + env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC' + env['SHOBJSUFFIX'] = '.pic.o' else: + # Original line from Christian Engel added -DPIC: + #env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC -DPIC' env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC' - env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' - env['CPPDEFPREFIX'] = '-D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '-I' - env['INCSUFFIX'] = '' + # determine compiler version + if env['CXX']: + line = os.popen(env['CXX'] + ' --version').readline() + match = re.search(r'[0-9]+(\.[0-9]+)+', line) + if match: + env['CXXVERSION'] = match.group(0) - env['CXXFILESUFFIX'] = '.cc' def exists(env): return env.Detect(compilers) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 0f92b35..3c3bba1 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -33,41 +33,16 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import cc import link -import os.path -import SCons.Action -import SCons.Builder -import SCons.Errors -import SCons.Util -linkers = ['g++', 'gcc', 'c++', 'cc'] +linkers = ['g++', 'gcc'] -def cxxSource(sources): - for s in sources: - if SCons.Util.splitext(str(s))[1] in cc.CXXSuffixes: - return 1 - if cxxSource(s.sources): - return 1 - return 0 - -def smart_link(source, target, env, for_signature): - cppSource = 0 - if source is None: - # may occur, when env.subst('$LINK') is called - return '$CXX' - if not SCons.Util.is_List(source): - source = [source] - - if cxxSource(source): - return '$CXX' - else: - return '$CC' - def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" link.generate(env) - env['LINK'] = smart_link + + if env['PLATFORM'] == 'hpux': + env['SHLINKFLAGS'] = '$LINKFLAGS -shared -fPIC' def exists(env): return env.Detect(linkers) diff --git a/src/engine/SCons/Tool/hpc++.py b/src/engine/SCons/Tool/hpc++.py new file mode 100644 index 0000000..b654df8 --- /dev/null +++ b/src/engine/SCons/Tool/hpc++.py @@ -0,0 +1,44 @@ +"""SCons.Tool.hpc++ + +Tool-specific initialization for c++ on HP/UX. + +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. + +""" +__revision__ = "" + +import os.path +import string + +cplusplus = __import__('c++', globals(), locals(), []) + +acc = None + +# search for the acc compiler and linker front end +for dir in os.listdir('/opt'): + cc = '/opt/' + dir + '/bin/aCC' + if os.path.exists(cc): + acc = cc + break + + +def generate(env): + """Add Builders and construction variables for g++ to an Environment.""" + cplusplus.generate(env) + + if acc: + env['CXX'] = acc + # determine version of aCC + line = os.popen(acc + ' -V 2>&1').readline().rstrip() + if string.find(line, 'aCC: HP ANSI C++') == 0: + env['CXXVERSION'] = string.split(line)[-1] + + if env['PLATFORM'] == 'cygwin': + env['SHCXXFLAGS'] = '$CXXFLAGS' + else: + env['SHCXXFLAGS'] = '$CXXFLAGS +Z' + +def exists(env): + return acc diff --git a/src/engine/SCons/Tool/hplink.py b/src/engine/SCons/Tool/hplink.py index e3b3f92..3f3cd85 100644 --- a/src/engine/SCons/Tool/hplink.py +++ b/src/engine/SCons/Tool/hplink.py @@ -32,15 +32,30 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os +import os.path + import link -linkers = ['aCC', 'cc'] +ccLinker = None + +# search for the acc compiler and linker front end +for dir in os.listdir('/opt'): + linker = '/opt/' + dir + '/bin/aCC' + if os.path.exists(linker): + ccLinker = linker + break def generate(env): - "Add Builders and construction variables for HP linker to an Environment." + """ + Add Builders and construction variables for Visual Age linker to + an Environment. + """ link.generate(env) + env['LINKFLAGS'] = '-Wl,+s -Wl,+vnocompatwarnings' env['SHLINKFLAGS'] = '$LINKFLAGS -b' + env['SHLIBSUFFIX'] = '.sl' def exists(env): - return env.Detect(linkers) + return ccLinker diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index c54f65a..da672c1 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -37,7 +37,12 @@ import SCons.Defaults import SCons.Tool import SCons.Util -linkers = ['c++', 'cc'] +cplusplus = __import__('c++', globals(), locals(), []) + +def smart_link(source, target, env, for_signature): + if cplusplus.iscplusplus(source): + return '$CXX' + return '$CC' def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" @@ -48,7 +53,8 @@ def generate(env): env['SHLINKFLAGS'] = '$LINKFLAGS -shared' env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' env['SHLIBEMITTER']= None - env['LINK'] = env.Detect(linkers) or 'c++' + env['SMARTLINK'] = smart_link + env['LINK'] = "$SMARTLINK" env['LINKFLAGS'] = '' env['LINKCOM'] = '$LINK $LINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' env['LIBDIRPREFIX']='-L' @@ -57,5 +63,13 @@ def generate(env): env['LIBLINKPREFIX']='-l' env['LIBLINKSUFFIX']='' + if env['PLATFORM'] == 'hpux': + env['SHLIBSUFFIX'] = '.sl' + elif env['PLATFORM'] == 'aix': + env['SHLIBSUFFIX'] = '.a' + + def exists(env): - return env.Detect(linkers) + # This module isn't really a Tool on its own, it's common logic for + # other linkers. + return None diff --git a/src/engine/SCons/Tool/sunc++.py b/src/engine/SCons/Tool/sunc++.py new file mode 100644 index 0000000..230c92b --- /dev/null +++ b/src/engine/SCons/Tool/sunc++.py @@ -0,0 +1,58 @@ +"""SCons.Tool.sunc++ + +Tool-specific initialization for C++ on SunOS / Solaris. + +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. + +""" +__revision__ = "" + +import os.path +import string + +cplusplus = __import__('c++', globals(), locals(), []) + +# use the package installer tool lslpp to figure out where cppc and what +# version of it is installed +def get_cppc(env): + cppcPath = None + cppcVersion = None + + try: + cppc = env['CXX'] + except KeyError: + cppc = 'cppc' + for package in ['SPROcpl']: + cmd = "pkginfo -l " + package + " 2>/dev/null | grep '^ *VERSION:'" + line = os.popen(cmd).readline() + if line: + cppcVersion = line.split()[-1] + cmd = "pkgchk -l " + package + " | grep '^Pathname:.*/bin/CC$' | grep -v '/SC[0-9]*\.[0-9]*/'" + line = os.popen(cmd).readline() + cppcPath = os.path.dirname(line.split()[-1]) + break + return (cppcPath, 'CC', 'CC', cppcVersion) + +def generate(env): + """Add Builders and construction variables for SUN PRO C++ to an Environment.""" + path, cxx, shcxx, version = get_cppc(env) + if path: + cxx = os.path.join(path, cxx) + shcxx = os.path.join(path, shcxx) + + cplusplus.generate(env) + + env['CXX'] = cxx + env['SHCXX'] = shcxx + env['CXXVERSION'] = version + env['SHOBJSUFFIX'] = '.os' + +def exists(env): + path, cxx, shcxx, version = get_cppc(env) + if path and cxx: + cppc = os.path.join(path, cxx) + if os.path.exists(cppc): + return cppc + return None diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py index bc66dce..c73a309 100644 --- a/src/engine/SCons/Tool/sunlink.py +++ b/src/engine/SCons/Tool/sunlink.py @@ -32,16 +32,25 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os +import os.path + import link -linkers = ['CC', 'cc'] +ccLinker = None + +# search for the acc compiler and linker front end +for dir in os.listdir('/opt'): + linker = '/opt/' + dir + '/bin/CC' + if os.path.exists(linker): + ccLinker = linker + break def generate(env): """Add Builders and construction variables for Forte to an Environment.""" link.generate(env) env['SHLINKFLAGS'] = '$LINKFLAGS -G' - env['LINK'] = env.Detect(linkers) or 'cc' def exists(env): - return env.Detect(linkers) + return ccLinker diff --git a/test/ToolSurrogate.py b/test/ToolSurrogate.py index dc190dd..fa13b57 100644 --- a/test/ToolSurrogate.py +++ b/test/ToolSurrogate.py @@ -88,7 +88,7 @@ test.write('foo.c', "foo.c posix\n") test.run(arguments = '. platform=posix', stdout = test.wrap_stdout("""\ cc -c -o foo.obj foo.c -c++ -o foo.exe foo.obj +cc -o foo.exe foo.obj """)) test.write('foo.c', "foo.c win32\n") diff --git a/test/import.py b/test/import.py index be3858a..48c17be 100644 --- a/test/import.py +++ b/test/import.py @@ -44,25 +44,28 @@ x = SCons.Platform.%s.generate test.run() tools = [ - # Can't import '386asm' directly due to initial '3' syntax error... + # Can't import '386asm' everywhere due to Windows registry dependency. + 'aixc++', 'aixcc', 'aixf77', 'aixlink', 'ar', 'as', 'BitKeeper', + 'c++', 'cc', 'CVS', 'default', 'dvipdf', 'dvips', 'f77', - # Can't import 'g++' directly due to '+' syntax error... + 'g++', 'g77', 'gas', 'gcc', 'gnulink', 'gs', + 'hpc++', 'hpcc', 'hplink', 'icc', @@ -75,7 +78,7 @@ tools = [ 'latex', 'lex', 'link', - # Can't import 'linkloc' everywhere due to Windows registry dependency... + # Can't import 'linkloc' everywhere due to Windows registry dependency. 'm4', 'masm', 'midl', @@ -88,17 +91,18 @@ tools = [ 'pdflatex', 'pdftex', 'Perforce', - 'RCS', 'qt', + 'RCS', 'rmic', 'SCCS', 'sgiar', 'sgicc', 'sgilink', + 'Subversion', 'sunar', + 'sunc++', 'suncc', 'sunlink', - 'Subversion', 'swig', 'tar', 'tex', @@ -106,12 +110,27 @@ tools = [ 'zip', ] -for tool in tools: - test.write('SConstruct', """ +# An SConstruct for importing Tool names that have illegal characters +# for Python variable names. +indirect_import = """\ +env = Environment(tools = ['%s']) +SCons = __import__('SCons.Tool.%s', globals(), locals(), []) +m = getattr(SCons.Tool, '%s') +x = m.generate +""" + +# An SConstruct for importing Tool names "normally." +direct_import = """\ env = Environment(tools = ['%s']) import SCons.Tool.%s x = SCons.Tool.%s.generate -""" % (tool, tool, tool)) +""" + +for tool in tools: + if tool[0] in '0123456789' or '+' in tool: + test.write('SConstruct', indirect_import % (tool, tool, tool)) + else: + test.write('SConstruct', direct_import % (tool, tool, tool)) test.run() test.pass_test() -- cgit v0.12