aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2016-12-22 02:11:36 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2016-12-22 02:27:01 +0530
commit0ac965cc10094e81db87c2b921c1001e97ee6410 (patch)
tree75ea0705fff61044067e93f7c085498af7678ea7
parent18f581f2c47d3ba81ce753334830ac8ecd5e5a5c (diff)
downloadmeson-0ac965cc10094e81db87c2b921c1001e97ee6410.zip
meson-0ac965cc10094e81db87c2b921c1001e97ee6410.tar.gz
meson-0ac965cc10094e81db87c2b921c1001e97ee6410.tar.bz2
Fix shared library symlink aliasing on install
Set the rules for the symlinking on the target itself, and then reuse that information while generating aliases during the build, and then pass it to the install script too.
-rw-r--r--mesonbuild/backend/ninjabackend.py23
-rw-r--r--mesonbuild/build.py27
-rw-r--r--mesonbuild/modules/rpm.py2
-rw-r--r--mesonbuild/scripts/meson_install.py4
4 files changed, 27 insertions, 29 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 40776a9..b43977e 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -626,7 +626,7 @@ int dummy;
self.environment.get_import_lib_dir(),
# It has no aliases, should not be stripped, and
# doesn't have an install_rpath
- [], False, '']
+ {}, False, '']
d.targets.append(i)
outdir = self.environment.get_shared_lib_dir()
elif isinstance(t, build.StaticLibrary):
@@ -641,16 +641,16 @@ int dummy;
# Install the debug symbols file in the same place as
# the target itself. It has no aliases, should not be
# stripped, and doesn't have an install_rpath
- i = [self.get_target_debug_filename(t), outdir, [], False, '']
+ i = [self.get_target_debug_filename(t), outdir, {}, False, '']
d.targets.append(i)
if isinstance(t, build.BuildTarget):
- i = [self.get_target_filename(t), outdir, t.get_aliaslist(),\
- should_strip, t.install_rpath]
+ i = [self.get_target_filename(t), outdir, t.get_aliases(),
+ should_strip, t.install_rpath]
d.targets.append(i)
elif isinstance(t, build.CustomTarget):
for output in t.get_outputs():
f = os.path.join(self.get_target_dir(t), output)
- d.targets.append([f, outdir, [], False, None])
+ d.targets.append([f, outdir, {}, False, None])
def generate_custom_install_script(self, d):
d.install_scripts = self.build.install_scripts
@@ -2087,22 +2087,15 @@ rule FORTRAN_DEP_HACK
def generate_shlib_aliases(self, target, outdir):
basename = target.get_filename()
- aliases = target.get_aliaslist()
- for i, alias in enumerate(aliases):
+ aliases = target.get_aliases()
+ for alias, to in aliases.items():
aliasfile = os.path.join(self.environment.get_build_dir(), outdir, alias)
try:
os.remove(aliasfile)
except Exception:
pass
- # If both soversion and version are set and to different values,
- # the .so symlink must point to the soversion symlink rather than the
- # original file.
- if i == 0 and len(aliases) > 1:
- pointed_to_filename = aliases[1]
- else:
- pointed_to_filename = basename
try:
- os.symlink(pointed_to_filename, aliasfile)
+ os.symlink(to, aliasfile)
except NotImplementedError:
mlog.debug("Library versioning disabled because symlinks are not supported.")
except OSError:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index afd8b0a..3750f77 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -798,8 +798,8 @@ class BuildTarget():
else:
self.extra_args[language] = args
- def get_aliaslist(self):
- return []
+ def get_aliases(self):
+ return {}
def get_clike_dynamic_linker(self):
'''
@@ -1029,7 +1029,7 @@ class SharedLibrary(BuildTarget):
First we determine the filename template (self.filename_tpl), then we
set the output filename (self.filename).
- The template is needed while creating aliases (self.get_aliaslist),
+ The template is needed while creating aliases (self.get_aliases),
which are needed while generating .so shared libraries for Linux.
Besides this, there's also the import library name, which is only used
@@ -1175,25 +1175,30 @@ class SharedLibrary(BuildTarget):
def get_all_link_deps(self):
return [self] + self.get_transitive_link_deps()
- def get_aliaslist(self):
+ def get_aliases(self):
"""
If the versioned library name is libfoo.so.0.100.0, aliases are:
- * libfoo.so.0 (soversion)
- * libfoo.so (unversioned; for linking)
+ * libfoo.so.0 (soversion) -> libfoo.so.0.100.0
+ * libfoo.so (unversioned; for linking) -> libfoo.so.0
"""
+ aliases = {}
# Aliases are only useful with .so libraries. Also if the .so library
# ends with .so (no versioning), we don't need aliases.
if self.suffix != 'so' or self.filename.endswith('.so'):
- return []
- # Unversioned alias: libfoo.so
- aliases = [self.basic_filename_tpl.format(self)]
- # If ltversion != soversion we create an soversion alias: libfoo.so.X
+ return {}
+ # If ltversion != soversion we create an soversion alias:
+ # libfoo.so.0 -> libfoo.so.0.100.0
if self.ltversion and self.ltversion != self.soversion:
if not self.soversion:
# This is done in self.process_kwargs()
raise AssertionError('BUG: If library version is defined, soversion must have been defined')
alias_tpl = self.filename_tpl.replace('ltversion', 'soversion')
- aliases.append(alias_tpl.format(self))
+ ltversion_filename = alias_tpl.format(self)
+ aliases[ltversion_filename] = self.filename
+ else:
+ ltversion_filename = self.filename
+ # Unversioned alias: libfoo.so -> libfoo.so.0
+ aliases[self.basic_filename_tpl.format(self)] = ltversion_filename
return aliases
def type_suffix(self):
diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py
index e3c45c0..ece1610 100644
--- a/mesonbuild/modules/rpm.py
+++ b/mesonbuild/modules/rpm.py
@@ -55,7 +55,7 @@ class RPMModule:
files.add('%%{_bindir}/%s' % target.get_filename())
elif isinstance(target, build.SharedLibrary) and target.need_install:
files.add('%%{_libdir}/%s' % target.get_filename())
- for alias in target.get_aliaslist():
+ for alias in target.get_aliases():
if alias.endswith('.so'):
files_devel.add('%%{_libdir}/%s' % alias)
else:
diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index 11dd320..c749b4f 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -222,14 +222,14 @@ def install_targets(d):
else:
raise RuntimeError('Unknown file type for {!r}'.format(fname))
printed_symlink_error = False
- for alias in aliases:
+ for alias, to in aliases.items():
try:
symlinkfilename = os.path.join(outdir, alias)
try:
os.unlink(symlinkfilename)
except FileNotFoundError:
pass
- os.symlink(os.path.split(fname)[-1], symlinkfilename)
+ os.symlink(to, symlinkfilename)
append_to_log(symlinkfilename)
except (NotImplementedError, OSError):
if not printed_symlink_error: