diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2017-11-02 19:41:48 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2017-11-11 23:06:48 +0530 |
commit | d2a250412c208a38a4c82a8b2615aad90dc15df9 (patch) | |
tree | 5bed892a787aabebccd6e61d552bb276a57b0e18 | |
parent | 4405a1297b2d76849b40843f8456d8c086c46516 (diff) | |
download | meson-d2a250412c208a38a4c82a8b2615aad90dc15df9.zip meson-d2a250412c208a38a4c82a8b2615aad90dc15df9.tar.gz meson-d2a250412c208a38a4c82a8b2615aad90dc15df9.tar.bz2 |
compilers: Improve manual library searching
We can now specify the library type we want to search for, and whether
we want to prefer static libraries over shared ones or the other way
around. This functionality is not exposed to build files yet.
-rw-r--r-- | mesonbuild/build.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/c.py | 59 | ||||
-rw-r--r-- | mesonbuild/dependencies/ui.py | 5 | ||||
-rw-r--r-- | mesonbuild/environment.py | 44 | ||||
-rw-r--r-- | mesonbuild/mesonlib.py | 36 |
5 files changed, 91 insertions, 55 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 12f4bdb..5f552c2 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -22,7 +22,7 @@ from . import mlog from .mesonlib import File, MesonException, listify, extract_as_list from .mesonlib import typeslistify, stringlistify, classify_unity_sources from .mesonlib import get_filenames_templates_dict, substitute_values -from .environment import for_windows, for_darwin, for_cygwin +from .mesonlib import for_windows, for_darwin, for_cygwin from .compilers import is_object, clike_langs, sort_clike, lang_suffixes known_basic_kwargs = {'install': True, diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 3f9ba5c..9e85712 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -17,6 +17,7 @@ import subprocess, os.path, tempfile from .. import mlog from .. import coredata from ..mesonlib import EnvironmentException, version_compare, Popen_safe, listify +from ..mesonlib import for_windows, for_darwin, for_cygwin from .compilers import ( GCC_MINGW, @@ -710,7 +711,45 @@ class CCompiler(Compiler): return False raise RuntimeError('BUG: {!r} check failed unexpectedly'.format(n)) - def find_library(self, libname, env, extra_dirs): + def get_library_naming(self, env, libtype): + ''' + Get library prefixes and suffixes for the target platform ordered by + priority + ''' + stlibext = ['a'] + # We've always allowed libname to be both `foo` and `libfoo`, + # and now people depend on it + prefixes = ['lib', ''] + # Library suffixes and prefixes + if for_darwin(env.is_cross_build(), env): + shlibext = ['dylib'] + elif for_windows(env.is_cross_build(), env): + if self.id == 'msvc': + shlibext = ['lib'] + else: + shlibext = ['dll', 'dll.a', 'lib'] + # Yep, static libraries can also be foo.lib + stlibext += ['lib'] + elif for_cygwin(env.is_cross_build(), env): + shlibext = ['dll', 'dll.a'] + prefixes = ['cyg'] + prefixes + else: + # Linux/BSDs + shlibext = ['so'] + # Search priority + if libtype in ('default', 'shared-static'): + suffixes = shlibext + stlibext + elif libtype == 'static-shared': + suffixes = stlibext + shlibext + elif libtype == 'shared': + suffixes = shlibext + elif libtype == 'static': + suffixes = stlibext + else: + raise AssertionError('BUG: unknown libtype {!r}'.format(libtype)) + return prefixes, suffixes + + def find_library(self, libname, env, extra_dirs, libtype='default'): # These libraries are either built-in or invalid if libname in self.ignore_libs: return [] @@ -720,21 +759,21 @@ class CCompiler(Compiler): extra_dirs = [extra_dirs] # Gcc + co seem to prefer builtin lib dirs to -L dirs. # Only try to find std libs if no extra dirs specified. - if not extra_dirs: + if not extra_dirs and libtype == 'default': args = ['-l' + libname] if self.links(code, env, extra_args=args): return args - # Not found? Try to find the library file itself. + # Not found or we want to use a specific libtype? Try to find the + # library file itself. extra_dirs += self.get_library_dirs() - suffixes = ['so', 'dylib', 'lib', 'dll', 'a'] + prefixes, suffixes = self.get_library_naming(env, libtype) + # Triply-nested loop! for d in extra_dirs: for suffix in suffixes: - trial = os.path.join(d, 'lib' + libname + '.' + suffix) - if os.path.isfile(trial): - return [trial] - trial2 = os.path.join(d, libname + '.' + suffix) - if os.path.isfile(trial2): - return [trial2] + for prefix in prefixes: + trial = os.path.join(d, prefix + libname + '.' + suffix) + if os.path.isfile(trial): + return [trial] return None def thread_flags(self): diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py index 8f183e5..3412dc6 100644 --- a/mesonbuild/dependencies/ui.py +++ b/mesonbuild/dependencies/ui.py @@ -23,8 +23,9 @@ from collections import OrderedDict from .. import mlog from .. import mesonlib -from ..mesonlib import MesonException, Popen_safe, version_compare, extract_as_list -from ..environment import for_windows, detect_cpu +from ..mesonlib import MesonException, Popen_safe, version_compare +from ..mesonlib import extract_as_list, for_windows +from ..environment import detect_cpu from .base import DependencyException, DependencyMethods from .base import ExternalDependency, ExternalProgram diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 7f07c8d..d9146eb 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -219,46 +219,6 @@ def detect_system(): return 'cygwin' return system - -def for_windows(is_cross, env): - """ - Host machine is windows? - - Note: 'host' is the machine on which compiled binaries will run - """ - if not is_cross: - return mesonlib.is_windows() - elif env.cross_info.has_host(): - return env.cross_info.config['host_machine']['system'] == 'windows' - return False - - -def for_cygwin(is_cross, env): - """ - Host machine is cygwin? - - Note: 'host' is the machine on which compiled binaries will run - """ - if not is_cross: - return mesonlib.is_cygwin() - elif env.cross_info.has_host(): - return env.cross_info.config['host_machine']['system'] == 'cygwin' - return False - - -def for_darwin(is_cross, env): - """ - Host machine is Darwin (iOS/OS X)? - - Note: 'host' is the machine on which compiled binaries will run - """ - if not is_cross: - return mesonlib.is_osx() - elif env.cross_info.has_host(): - return env.cross_info.config['host_machine']['system'] == 'darwin' - return False - - def search_version(text): # Usually of the type 4.1.4 but compiler output may contain # stuff like this: @@ -550,9 +510,9 @@ class Environment: cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler return cls(ccache + compiler, version, gtype, is_cross, exe_wrap, defines) if 'clang' in out: - if 'Apple' in out or for_darwin(want_cross, self): + if 'Apple' in out or mesonlib.for_darwin(want_cross, self): cltype = CLANG_OSX - elif 'windows' in out or for_windows(want_cross, self): + elif 'windows' in out or mesonlib.for_windows(want_cross, self): cltype = CLANG_WIN else: cltype = CLANG_STANDARD diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 5c4c374..f74c6c1 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -219,6 +219,42 @@ def is_cygwin(): def is_debianlike(): return os.path.isfile('/etc/debian_version') +def for_windows(is_cross, env): + """ + Host machine is windows? + + Note: 'host' is the machine on which compiled binaries will run + """ + if not is_cross: + return is_windows() + elif env.cross_info.has_host(): + return env.cross_info.config['host_machine']['system'] == 'windows' + return False + +def for_cygwin(is_cross, env): + """ + Host machine is cygwin? + + Note: 'host' is the machine on which compiled binaries will run + """ + if not is_cross: + return is_cygwin() + elif env.cross_info.has_host(): + return env.cross_info.config['host_machine']['system'] == 'cygwin' + return False + +def for_darwin(is_cross, env): + """ + Host machine is Darwin (iOS/OS X)? + + Note: 'host' is the machine on which compiled binaries will run + """ + if not is_cross: + return is_osx() + elif env.cross_info.has_host(): + return env.cross_info.config['host_machine']['system'] == 'darwin' + return False + def exe_exists(arglist): try: p = subprocess.Popen(arglist, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |