From e38f040661b56781bed8290e7ab357ccfbdf49ec Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Jul 2014 20:53:50 +0300 Subject: [PATCH] Can set install time rpath. --- build.py | 4 ++++ environment.py | 51 +++++++++++++++--------------------------------- meson_install.py | 5 ++--- ninjabackend.py | 8 +++++--- 4 files changed, 27 insertions(+), 41 deletions(-) diff --git a/build.py b/build.py index 498e3a7ad..040388478 100644 --- a/build.py +++ b/build.py @@ -299,6 +299,9 @@ class BuildTarget(): if not(os.path.isfile(trial)): raise InvalidArguments('Tried to add non-existing extra file %s.' % i) self.extra_files = extra_files + self.install_rpath = kwargs.get('install_rpath', '') + if not isinstance(self.install_rpath, str): + raise InvalidArguments('Install_rpath is not a string.') def get_subdir(self): return self.subdir @@ -585,6 +588,7 @@ class CustomTarget: self.dependencies = [] self.process_kwargs(kwargs) self.extra_files = [] + self.install_rpath = '' def process_kwargs(self, kwargs): self.sources = kwargs.get('input', []) diff --git a/environment.py b/environment.py index 9d9a225de..1e7a64173 100644 --- a/environment.py +++ b/environment.py @@ -95,8 +95,19 @@ class CCompiler(): def split_shlib_to_parts(self, fname): return (None, fname) - def build_rpath_args(self, build_dir, rpath_paths): - return [] + # The default behaviour is this, override in + # OSX and MSVC. + def build_rpath_args(self, build_dir, rpath_paths, install_rpath): + if len(rpath_paths) == 0 and len(install_rpath) == 0: + return [] + paths = ':'.join([os.path.join(build_dir, p) for p in rpath_paths]) + if len(paths) < len(install_rpath): + padding = 'X'*(len(install_rpath) - len(paths)) + if len(paths) == 0: + paths = padding + else: + paths = paths + ':' + padding + return ['-Wl,-rpath,' + paths] def get_id(self): return self.id @@ -457,7 +468,7 @@ class JavaCompiler(): def split_shlib_to_parts(self, fname): return (None, fname) - def build_rpath_args(self, build_dir, rpath_paths): + def build_rpath_args(self, build_dir, rpath_paths, install_rpath): return [] def get_id(self): @@ -805,11 +816,6 @@ class GnuCCompiler(CCompiler): def split_shlib_to_parts(self, fname): return (os.path.split(fname)[0], fname) - def build_rpath_args(self, build_dir, rpath_paths): - if len(rpath_paths) == 0: - return [] - return ['-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])] - def get_soname_args(self, shlib_name, path): return get_gcc_soname_args(self.gcc_type, shlib_name, path) @@ -832,11 +838,6 @@ class GnuObjCCompiler(ObjCCompiler): def get_pch_suffix(self): return 'gch' - def build_rpath_args(self, build_dir, rpath_paths): - if len(rpath_paths) == 0: - return [] - return ['-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])] - def get_soname_args(self, shlib_name, path): return get_gcc_soname_args(self.gcc_type, shlib_name, path) @@ -860,11 +861,6 @@ class GnuObjCPPCompiler(ObjCPPCompiler): def get_pch_suffix(self): return 'gch' - def build_rpath_args(self, build_dir, rpath_paths): - if len(rpath_paths) == 0: - return [] - return ['-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])] - def get_soname_args(self, shlib_name, path): return get_gcc_soname_args(self.gcc_type, shlib_name, path) @@ -897,11 +893,6 @@ class ClangCCompiler(CCompiler): def get_pch_suffix(self): return 'pch' - def build_rpath_args(self, build_dir, rpath_paths): - if len(rpath_paths) == 0: - return [] - return ['-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])] - class GnuCPPCompiler(CPPCompiler): std_warn_args = ['-Wall', '-Winvalid-pch'] # may need to separate the latter to extra_debug_args or something @@ -930,11 +921,6 @@ class GnuCPPCompiler(CPPCompiler): def get_pch_suffix(self): return 'gch' - def build_rpath_args(self, build_dir, rpath_paths): - if len(rpath_paths) == 0: - return [] - return ['-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])] - def get_soname_args(self, shlib_name, path): return get_gcc_soname_args(self.gcc_type, shlib_name, path) @@ -957,11 +943,6 @@ class ClangCPPCompiler(CPPCompiler): def get_pch_suffix(self): return 'pch' - def build_rpath_args(self, build_dir, rpath_paths): - if len(rpath_paths) == 0: - return [] - return ['-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])] - class VisualStudioLinker(): always_args = ['/NOLOGO'] def __init__(self, exelist): @@ -988,7 +969,7 @@ class VisualStudioLinker(): def get_linker_always_args(self): return VisualStudioLinker.always_args - def build_rpath_args(self, build_dir, rpath_paths): + def build_rpath_args(self, build_dir, rpath_paths, install_rpath): return [] class ArLinker(): @@ -997,7 +978,7 @@ class ArLinker(): def __init__(self, exelist): self.exelist = exelist - def build_rpath_args(self, build_dir, rpath_paths): + def build_rpath_args(self, build_dir, rpath_paths, install_rpath): return [] def get_exelist(self): diff --git a/meson_install.py b/meson_install.py index 947295477..763bdd8be 100755 --- a/meson_install.py +++ b/meson_install.py @@ -18,13 +18,12 @@ import sys, pickle, os, shutil, subprocess, gzip, platform from glob import glob class InstallData(): - def __init__(self, source_dir, build_dir, prefix, depfixer, dep_prefix): + def __init__(self, source_dir, build_dir, prefix, depfixer): self.source_dir = source_dir self.build_dir= build_dir self.prefix = prefix self.targets = [] self.depfixer = depfixer - self.dep_prefix = dep_prefix self.headers = [] self.man = [] self.data = [] @@ -149,6 +148,7 @@ def install_targets(d): aliases = t[2] outname = os.path.join(outdir, os.path.split(fname)[-1]) should_strip = t[3] + install_rpath = t[4] print('Installing %s to %s' % (fname, outname)) os.makedirs(outdir, exist_ok=True) shutil.copyfile(fname, outname) @@ -170,7 +170,6 @@ def install_targets(d): if not printed_symlink_error: print("Symlink creation does not work on this platform.") printed_symlink_error = True - install_rpath = '' if is_elf_platform(): p = subprocess.Popen([d.depfixer, outname, install_rpath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/ninjabackend.py b/ninjabackend.py index b9131ae68..af4f14806 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -220,7 +220,7 @@ class NinjaBackend(backends.Backend): depfixer = os.path.join(script_root, 'depfixer.py') d = InstallData(self.environment.get_source_dir(), self.environment.get_build_dir(), - self.environment.get_prefix(), depfixer, './') # Fixme + self.environment.get_prefix(), depfixer) elem = NinjaBuildElement('install', 'CUSTOM_COMMAND', '') elem.add_dep('all') elem.add_item('DESC', 'Installing files.') @@ -261,7 +261,8 @@ class NinjaBackend(backends.Backend): outdir = bindir else: outdir = libdir - i = [self.get_target_filename(t), outdir, t.get_aliaslist(), should_strip] + i = [self.get_target_filename(t), outdir, t.get_aliaslist(),\ + should_strip, t.install_rpath] d.targets.append(i) def generate_pkgconfig_install(self, d): @@ -912,7 +913,8 @@ class NinjaBackend(backends.Backend): if not(isinstance(target, build.StaticLibrary)): for dep in target.get_external_deps(): commands += dep.get_link_args() - commands += linker.build_rpath_args(self.environment.get_build_dir(), target.get_rpaths()) + commands += linker.build_rpath_args(self.environment.get_build_dir(),\ + target.get_rpaths(), target.install_rpath) if self.environment.coredata.coverage: commands += linker.get_coverage_link_args() dep_targets = [self.get_dependency_filename(t) for t in dependencies]