summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
authorDavid Rothenberger <daveroth@acm.org>2013-08-17 19:12:56 (GMT)
committerDavid Rothenberger <daveroth@acm.org>2013-08-17 19:12:56 (GMT)
commitf837e2e6511cc8049e5a765c9af25afc9fd730fe (patch)
tree1e31f698424a467ed6ac3d722037912c0224f194 /src/engine/SCons
parenta0ca59da5a6b076f34c1fb5ebe713a1d1ce7d085 (diff)
downloadSCons-f837e2e6511cc8049e5a765c9af25afc9fd730fe.zip
SCons-f837e2e6511cc8049e5a765c9af25afc9fd730fe.tar.gz
SCons-f837e2e6511cc8049e5a765c9af25afc9fd730fe.tar.bz2
Add a cyglink tool
Add cyglink, a specialization of gnulink with the following properties: 1. Set SHLIBPREFIX to "cyg" and SHLIBSUFFIX = ".dll". 2. Remove any "lib" after "cyg", to accommodate build scripts that name libraries "libFoo". 3. Create DLL import libraries.
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/Tool/__init__.py8
-rw-r--r--src/engine/SCons/Tool/__init__.xml13
-rw-r--r--src/engine/SCons/Tool/cyglink.py96
-rw-r--r--src/engine/SCons/Tool/link.py12
4 files changed, 128 insertions, 1 deletions
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 89aabb5..af1282c 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -733,6 +733,14 @@ def tool_list(platform, env):
assemblers = ['as']
fortran_compilers = ['gfortran', 'f95', 'f90', 'g77']
ars = ['ar']
+ elif str(platform) == 'cygwin':
+ "prefer GNU tools on Cygwin, except for a platform-specific linker"
+ linkers = ['cyglink', 'mslink', 'ilink']
+ c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
+ cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
+ assemblers = ['gas', 'nasm', 'masm']
+ fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
+ ars = ['ar', 'mslib']
else:
"prefer GNU tools on all other platforms"
linkers = ['gnulink', 'mslink', 'ilink']
diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml
index 18bfd3e..9c3dc85 100644
--- a/src/engine/SCons/Tool/__init__.xml
+++ b/src/engine/SCons/Tool/__init__.xml
@@ -168,6 +168,17 @@ listed in the targets.
</para>
<para>
+On Cygwin systems, the
+&b-SharedLibrary;
+builder method will always build an import
+(<filename>.dll.a</filename>) library
+in addition to the shared (<filename>.dll</filename>) library,
+adding a <filename>.dll.a</filename> library with the same basename
+if there is not already a <filename>.dll.a</filename> file explicitly
+listed in the targets.
+</para>
+
+<para>
Any object files listed in the
<literal>source</literal>
must have been built for a shared library
@@ -485,4 +496,4 @@ letters to designate alpha, beta, or release candidate patch levels.
</summary>
</cvar>
-</sconsdoc> \ No newline at end of file
+</sconsdoc>
diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py
new file mode 100644
index 0000000..23c1adf
--- /dev/null
+++ b/src/engine/SCons/Tool/cyglink.py
@@ -0,0 +1,96 @@
+"""SCons.Tool.cyglink
+
+Customization of gnulink for Cygwin (http://www.cygwin.com/)
+
+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.
+
+"""
+
+import SCons.Action
+import SCons.Util
+
+import gnulink
+
+def shlib_generator(target, source, env, for_signature):
+ cmd = SCons.Util.CLVar(['$SHLINK'])
+
+ dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+ if dll: cmd.extend(['-o', dll])
+
+ cmd.extend(['$SHLINKFLAGS', '$__RPATH'])
+
+ implib = env.FindIxes(target, 'IMPLIBPREFIX', 'IMPLIBSUFFIX')
+ if implib:
+ cmd.extend([
+ '-Wl,--out-implib='+implib.get_string(for_signature),
+ '-Wl,--export-all-symbols',
+ '-Wl,--enable-auto-import',
+ '-Wl,--whole-archive', '$SOURCES',
+ '-Wl,--no-whole-archive', '$_LIBDIRFLAGS', '$_LIBFLAGS'
+ ])
+ else:
+ cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS'])
+
+ return [cmd]
+
+def shlib_emitter(target, source, env):
+ dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+ no_import_lib = env.get('no_import_lib', 0)
+
+ if not dll or len(target) > 1:
+ raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX"))
+
+ # Remove any "lib" after the prefix
+ pre = env.subst('$SHLIBPREFIX')
+ dll_name = str(dll)
+ if dll_name[len(pre):len(pre)+3] == 'lib':
+ dll_name = pre + dll_name[len(pre)+3:]
+ dll = env.fs.File(dll_name)
+
+ orig_target = target
+ target = [env.fs.File(dll)]
+ target[0].attributes.shared = 1
+
+ # Append an import lib target
+ if not no_import_lib:
+ # Create list of target libraries as strings
+ target_strings = env.ReplaceIxes(orig_target[0],
+ 'SHLIBPREFIX', 'SHLIBSUFFIX',
+ 'IMPLIBPREFIX', 'IMPLIBSUFFIX')
+
+ implib_target = env.fs.File(target_strings)
+ implib_target.attributes.shared = 1
+ target.append(implib_target)
+
+ return (target, source)
+
+
+shlib_action = SCons.Action.Action(shlib_generator, generator=1)
+
+def generate(env):
+ """Add Builders and construction variables for cyglink to an Environment."""
+ gnulink.generate(env)
+
+ env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,-no-undefined')
+
+ env['SHLINKCOM'] = shlib_action
+ env['LDMODULECOM'] = shlib_action
+ env.Append(SHLIBEMITTER = [shlib_emitter])
+
+ env['SHLIBPREFIX'] = 'cyg'
+ env['SHLIBSUFFIX'] = '.dll'
+
+ env['IMPLIBPREFIX'] = 'lib'
+ env['IMPLIBSUFFIX'] = '.dll.a'
+
+def exists(env):
+ return gnulink.exists(env)
+
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py
index 2ba419e..3f20fe0 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -127,6 +127,18 @@ def shlib_emitter_names(target, source, env):
print "shlib_emitter_names: side effect: ", name
# add version_name to list of names to be a Side effect
version_names.append(version_name)
+ elif platform == 'cygwin':
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ name = target[0].name
+ # generate library name with the version number
+ suffix_re = re.escape(shlib_suffix)
+ version_name = re.sub(suffix_re, '-' + re.sub('\.', '-', version) + shlib_suffix, name)
+ if Verbose:
+ print "shlib_emitter_names: target is ", version_name
+ print "shlib_emitter_names: side effect: ", name
+ # add version_name to list of names to be a Side effect
+ version_names.append(version_name)
+
except KeyError:
version = None
return version_names