diff options
-rw-r--r-- | .travis.yml | 5 | ||||
-rw-r--r-- | mesonbuild/dependencies/dev.py | 81 |
2 files changed, 72 insertions, 14 deletions
diff --git a/.travis.yml b/.travis.yml index dd5cebb..bd8d48c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ matrix: before_install: - python ./skip_ci.py --base-branch-env=TRAVIS_BRANCH --is-pull-env=TRAVIS_PULL_REQUEST - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt llvm; fi # # Run one macOS build without pkg-config available, and the other (unity=on) with pkg-config - if [[ "$TRAVIS_OS_NAME" == "osx" && "$MESON_ARGS" =~ .*unity=on.* ]]; then brew install pkg-config; fi # Use a Ninja with QuLogic's patch: https://github.com/ninja-build/ninja/issues/1219 @@ -62,4 +62,5 @@ script: withgit \ /bin/sh -c "cd /root && mkdir -p tools; wget -c http://nirbheek.in/files/binaries/ninja/linux-amd64/ninja -O /root/tools/ninja; chmod +x /root/tools/ninja; CC=$CC CXX=$CXX OBJC=$CC OBJCXX=$CXX PATH=/root/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS && chmod -R a+rwX .coverage" fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:/usr/local/opt/qt/bin:$PATH MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi + # Ensure that llvm is added after $PATH, otherwise the clang from that llvm install will be used instead of the native apple clang. + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:/usr/local/opt/qt/bin:$PATH:$(brew --prefix llvm)/bin MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py index d8289c5..1e7c3e8 100644 --- a/mesonbuild/dependencies/dev.py +++ b/mesonbuild/dependencies/dev.py @@ -16,6 +16,7 @@ # development purposes, such as testing, debugging, etc.. import functools +import glob import os import re @@ -27,6 +28,17 @@ from .base import ( ) +def get_shared_library_suffix(environment, native): + """This is only gauranteed to work for languages that compile to machine + code, not for languages like C# that use a bytecode and always end in .dll + """ + if mesonlib.for_windows(native, environment): + return '.dll' + elif mesonlib.for_darwin(native, environment): + return '.dylib' + return '.so' + + class GTestDependency(ExternalDependency): def __init__(self, environment, kwargs): super().__init__('gtest', environment, 'cpp', kwargs) @@ -235,7 +247,7 @@ class LLVMDependency(ConfigToolDependency): self.compile_args = list(cargs.difference(self.__cpp_blacklist)) if version_compare(self.version, '>= 3.9'): - self._set_new_link_args() + self._set_new_link_args(environment) else: self._set_old_link_args() self.link_args = strip_system_libdirs(environment, self.link_args) @@ -258,18 +270,63 @@ class LLVMDependency(ConfigToolDependency): new_args.append(arg) return new_args - def _set_new_link_args(self): + def __check_libfiles(self, shared): + """Use llvm-config's --libfiles to check if libraries exist.""" + mode = '--link-shared' if shared else '--link-static' + + # Set self.required to true to force an exception in get_config_value + # if the returncode != 0 + restore = self.required + self.required = True + + try: + # It doesn't matter what the stage is, the caller needs to catch + # the exception anyway. + self.link_args = self.get_config_value(['--libfiles', mode], '') + finally: + self.required = restore + + def _set_new_link_args(self, environment): """How to set linker args for LLVM versions >= 3.9""" - if ((mesonlib.is_dragonflybsd() or mesonlib.is_freebsd()) and not - self.static and version_compare(self.version, '>= 4.0')): - # llvm-config on DragonFly BSD and FreeBSD for versions 4.0, 5.0, - # and 6.0 have an error when generating arguments for shared mode - # linking, even though libLLVM.so is installed, because for some - # reason the tool expects to find a .so for each static library. - # This works around that. - self.link_args = self.get_config_value(['--ldflags'], 'link_args') - self.link_args.append('-lLLVM') - return + mode = self.get_config_value(['--shared-mode'], 'link_args')[0] + if not self.static and mode == 'static': + # If llvm is configured with LLVM_BUILD_LLVM_DYLIB but not with + # LLVM_LINK_LLVM_DYLIB and not LLVM_BUILD_SHARED_LIBS (which + # upstreams doesn't recomend using), then llvm-config will lie to + # you about how to do shared-linking. It wants to link to a a bunch + # of individual shared libs (which don't exist because llvm wasn't + # built with LLVM_BUILD_SHARED_LIBS. + # + # Therefore, we'll try to get the libfiles, if the return code is 0 + # or we get an empty list, then we'll try to build a working + # configuration by hand. + try: + self.__check_libfiles(True) + except DependencyException: + lib_ext = get_shared_library_suffix(environment, self.native) + libdir = self.get_config_value(['--libdir'], 'link_args')[0] + # Sort for reproducability + matches = sorted(glob.iglob(os.path.join(libdir, 'libLLVM*{}'.format(lib_ext)))) + if not matches: + if self.required: + raise + return + + self.link_args = self.get_config_value(['--ldflags'], 'link_args') + libname = os.path.basename(matches[0]).rstrip(lib_ext).lstrip('lib') + self.link_args.append('-l{}'.format(libname)) + return + elif self.static and mode == 'shared': + # If, however LLVM_BUILD_SHARED_LIBS is true # (*cough* gentoo *cough*) + # then this is correct. Building with LLVM_BUILD_SHARED_LIBS has a side + # effect, it stops the generation of static archives. Therefore we need + # to check for that and error out on static if this is the case + try: + self.__check_libfiles(False) + except DependencyException: + if self.required: + raise + link_args = ['--link-static', '--system-libs'] if self.static else ['--link-shared'] self.link_args = self.get_config_value( ['--libs', '--ldflags'] + link_args + list(self.required_modules), |