diff options
-rw-r--r-- | giscanner/ccompiler.py | 96 | ||||
-rw-r--r-- | giscanner/dumper.py | 105 |
2 files changed, 86 insertions, 115 deletions
diff --git a/giscanner/ccompiler.py b/giscanner/ccompiler.py index 155b61d4..9951cc7a 100644 --- a/giscanner/ccompiler.py +++ b/giscanner/ccompiler.py @@ -113,22 +113,18 @@ class CCompiler(object): # An "internal" link is where the library to be introspected # is being built in the current directory. - if not libtool: - # non-libtool case: prepare distutils use - if self.check_is_msvc(): - for library in libraries + extra_libraries: - # MSVC Builds don't use libtool, so no .la libraries, - # so just add the library directly. - self.compiler.add_library(library) - for libpath in libpaths: - self.compiler.add_library_dir(libpath) - else: - # Search the current directory first - # (This flag is not supported nor needed for Visual C++) - self.compiler.add_library_dir('.') - if os.name != 'nt': - self.compiler.add_runtime_library_dir('.') + runtime_path_envvar = [] + runtime_paths = [] + + if self.check_is_msvc(): + runtime_path_envvar = ['LIB', 'PATH'] + else: + runtime_path_envvar = ['LD_LIBRARY_PATH'] + # Search the current directory first + # (This flag is not supported nor needed for Visual C++) + args.append('-L.') + if not libtool: # https://bugzilla.gnome.org/show_bug.cgi?id=625195 args.append('-Wl,-rpath,.') @@ -137,37 +133,51 @@ class CCompiler(object): if sys.platform != 'darwin': args.append('-Wl,--no-as-needed') - for library in libraries + extra_libraries: - self.compiler.add_library(library) - if not self.check_is_msvc(): - for library_path in libpaths: - args.append('-L' + library_path) - if os.path.isabs(library_path): - args.append('-Wl,-rpath,' + library_path) - - else: - # libtool case: assemble linker command arguments, like we did before - args.append('-L.') - for library in libraries: + for library in libraries + extra_libraries: + if self.check_is_msvc(): + # Note that Visual Studio builds do not use libtool! + if library != 'm': + args.append(library + '.lib') + else: if library.endswith(".la"): # explicitly specified libtool library args.append(library) else: args.append('-l' + library) - for library_path in libpaths: + for library_path in libpaths: + # The dumper program needs to look for dynamic libraries + # in the library paths first + if self.check_is_msvc(): + library_path = library_path.replace('/', '\\') + args.append('-libpath:' + library_path) + else: args.append('-L' + library_path) if os.path.isabs(library_path): - args.append('-rpath') - args.append(library_path) + if libtool: + args.append('-rpath') + args.append(library_path) + else: + args.append('-Wl,-rpath=' + library_path) + + runtime_paths.append(library_path) + + for envvar in runtime_path_envvar: + if envvar in os.environ: + os.environ[envvar] = \ + os.pathsep.join(runtime_paths + [os.environ[envvar]]) + else: + os.environ[envvar] = os.pathsep.join(runtime_paths) - def get_external_link_flags(self, args, libtool, libraries): + def get_external_link_flags(self, args, libraries): # An "external" link is where the library to be introspected # is installed on the system; this case is used for the scanning # of GLib in gobject-introspection itself. for library in libraries: - if not libtool: - self.compiler.add_library(library) + if self.check_is_msvc(): + # Visual Studio: don't attempt to link to m.lib + if library != 'm': + args.append(library + ".lib") else: if library.endswith(".la"): # explicitly specified libtool library args.append(library) @@ -240,22 +250,6 @@ class CCompiler(object): extra_postargs=extra_postargs, output_dir=os.path.abspath(os.sep)) - def link(self, output, objects, lib_args): - # Note: This is used for non-libtool builds only! - extra_preargs = [] - extra_postargs = [] - library_dirs = [] - libraries = [] - - for arg in lib_args: - extra_postargs.append(arg) - - self.compiler.link(target_desc=self.compiler.EXECUTABLE, - objects=objects, - output_filename=output, - extra_preargs=extra_preargs, - extra_postargs=extra_postargs) - def resolve_windows_libs(self, libraries, options): args = [] libsearch = [] @@ -278,6 +272,10 @@ class CCompiler(object): args.append('dumpbin.exe') args.append('-symbols') + # Work around the attempt to resolve m.lib on Python 2.x + if sys.version_info.major < 3: + libraries[:] = [lib for lib in libraries if lib != 'm'] + # When we are not using Visual C++ (i.e. we are using GCC)... else: libtool = utils.get_libtool_command(options) diff --git a/giscanner/dumper.py b/giscanner/dumper.py index 793177b0..7f77bd24 100644 --- a/giscanner/dumper.py +++ b/giscanner/dumper.py @@ -99,10 +99,10 @@ class DumpCompiler(object): self._uninst_srcdir = os.environ.get('UNINSTALLED_INTROSPECTION_SRCDIR') self._packages = ['gio-2.0 gmodule-2.0'] self._packages.extend(options.packages) - if hasattr(self._compiler.compiler, 'linker_exe'): - self._linker_cmd = self._compiler.compiler.linker_exe + if self._compiler.check_is_msvc(): + self._linker_cmd = ['link.exe'] else: - self._linker_cmd = [] + self._linker_cmd = shlex.split(os.environ.get('CC', 'cc')) # Public API @@ -212,21 +212,25 @@ class DumpCompiler(object): libtool = utils.get_libtool_command(self._options) if libtool: # Note: MSVC Builds do not use libtool! - # In the libtool case, put together the linker command, as we did before. - # We aren't using distutils to link in this case. args.extend(libtool) args.append('--mode=link') args.append('--tag=CC') if self._options.quiet: args.append('--silent') - args.extend(self._linker_cmd) + args.extend(self._linker_cmd) + # We can use -o for the Microsoft compiler/linker, + # but it is considered deprecated usage + if self._compiler.check_is_msvc(): + args.extend(['-out:' + output]) + else: args.extend(['-o', output]) - if os.name == 'nt': - args.append('-Wl,--export-all-symbols') - else: - args.append('-export-dynamic') + if libtool: + if os.name == 'nt': + args.append('-Wl,--export-all-symbols') + else: + args.append('-export-dynamic') if not self._compiler.check_is_msvc(): # These envvars are not used for MSVC Builds! @@ -246,8 +250,7 @@ class DumpCompiler(object): raise CompilerError( "Could not find object file: %s" % (source, )) - if libtool: - args.extend(sources) + args.extend(sources) pkg_config_libs = self._run_pkgconfig('--libs') @@ -261,66 +264,36 @@ class DumpCompiler(object): else: args.extend(pkg_config_libs) - self._compiler.get_external_link_flags(args, - libtool, - self._options.libraries) + self._compiler.get_external_link_flags(args, self._options.libraries) if not self._compiler.check_is_msvc(): for ldflag in shlex.split(os.environ.get('LDFLAGS', '')): args.append(ldflag) - if not libtool: - # non-libtool: prepare distutils for linking the introspection - # dumper program... - try: - self._compiler.link(output, - sources, - args) - - # Ignore failing to embed the manifest files, when the manifest - # file does not exist, especially for MSVC 2010 and later builds. - # If we are on Visual C++ 2005/2008, where - # this embedding is required, the build will fail anyway, as - # the dumper program will likely fail to run, and this means - # something went wrong with the build. - except LinkError as e: - if self._compiler.check_is_msvc(): - msg = str(e) - - if msg[msg.rfind('mt.exe'):] == 'mt.exe\' failed with exit status 31': - if sys.version_info < (3, 0): - sys.exc_clear() - pass - else: - raise LinkError(e) - else: - raise LinkError(e) - else: - # libtool: Run the assembled link command, we don't use distutils - # for linking here. - if not self._options.quiet: - print("g-ir-scanner: link: %s" % ( - subprocess.list2cmdline(args), )) - sys.stdout.flush() - msys = os.environ.get('MSYSTEM', None) + if not self._options.quiet: + print("g-ir-scanner: link: %s" % ( + subprocess.list2cmdline(args), )) + sys.stdout.flush() + + msys = os.environ.get('MSYSTEM', None) + if msys: + shell = os.environ.get('SHELL', 'sh.exe') + # Create a temporary script file that + # runs the command we want + tf, tf_name = tempfile.mkstemp() + with os.fdopen(tf, 'wb') as f: + shellcontents = ' '.join([x.replace('\\', '/') for x in args]) + fcontents = '#!/bin/sh\nunset PWD\n{}\n'.format(shellcontents) + f.write(fcontents) + shell = utils.which(shell) + args = [shell, tf_name.replace('\\', '/')] + try: + subprocess.check_call(args) + except subprocess.CalledProcessError as e: + raise LinkerError(e) + finally: if msys: - shell = os.environ.get('SHELL', 'sh.exe') - # Create a temporary script file that - # runs the command we want - tf, tf_name = tempfile.mkstemp() - with os.fdopen(tf, 'wb') as f: - shellcontents = ' '.join([x.replace('\\', '/') for x in args]) - fcontents = '#!/bin/sh\nunset PWD\n{}\n'.format(shellcontents) - f.write(fcontents) - shell = utils.which(shell) - args = [shell, tf_name.replace('\\', '/')] - try: - subprocess.check_call(args) - except subprocess.CalledProcessError as e: - raise LinkerError(e) - finally: - if msys: - os.remove(tf_name) + os.remove(tf_name) def compile_introspection_binary(options, get_type_functions, |