summary refs log tree commit diff
diff options
context:
space:
mode:
authorJan Tojnar <jtojnar@gmail.com>2018-02-23 01:42:35 +0100
committerJan Tojnar <jtojnar@gmail.com>2018-03-22 07:30:58 +0100
commitde910a040b64a2e0c808a89e62717bb80c9f0043 (patch)
treefee80798626752055475594bdc2aa25bb79928e8
parent33e6ef179028ab9881d6feb465848c7ecc5c61a8 (diff)
downloadnixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.tar
nixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.tar.gz
nixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.tar.bz2
nixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.tar.lz
nixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.tar.xz
nixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.tar.zst
nixlib-de910a040b64a2e0c808a89e62717bb80c9f0043.zip
meson: fix rpath fixup
In common distributions, RPATH is only needed for internal libraries so
meson removes everything else. With Nix, the locations of libraries
are not as predictable, therefore we need to keep them in the RPATH. [1]

Previously we have just kept the RPATH produced by the linker, patching
meson not to remove it. This deprived us of potentially replacing it
with install_rpath provided by project so we had to re-add it manually,
and also introduced a vulnerability of keeping build paths in RPATH.

This commit restores the clean-up but modifies it so the items starting
with /nix/store are retained.

This should be relatively safe since the store is immutable, however,
there might be some unwanted retainment of build_rpath [2] if it contains
paths from Nix store.

[1]: https://github.com/NixOS/nixpkgs/issues/31222#issuecomment-365811634
[2]: http://mesonbuild.com/Release-notes-for-0-42-0.html#added-build_rpath-keyword-argument
-rw-r--r--pkgs/development/tools/build-managers/meson/default.nix16
-rw-r--r--pkgs/development/tools/build-managers/meson/fix-rpath.patch32
2 files changed, 43 insertions, 5 deletions
diff --git a/pkgs/development/tools/build-managers/meson/default.nix b/pkgs/development/tools/build-managers/meson/default.nix
index 27aa38cfa7e1..23b6f7226a16 100644
--- a/pkgs/development/tools/build-managers/meson/default.nix
+++ b/pkgs/development/tools/build-managers/meson/default.nix
@@ -1,4 +1,4 @@
-{ lib, python3Packages, stdenv, targetPlatform, writeTextDir, m4 }: let
+{ lib, python3Packages, stdenv, targetPlatform, writeTextDir, substituteAll }: let
   targetPrefix = lib.optionalString stdenv.isCross
                    (targetPlatform.config + "-");
 in python3Packages.buildPythonApplication rec {
@@ -27,11 +27,17 @@ in python3Packages.buildPythonApplication rec {
     # We patch Meson to add a --fallback-library-path argument with
     # library install_dir to g-ir-scanner.
     ./gir-fallback-path.patch
-  ];
 
-  postPatch = ''
-    sed -i -e 's|e.fix_rpath(install_rpath)||' mesonbuild/scripts/meson_install.py
-  '';
+    # In common distributions, RPATH is only needed for internal libraries so
+    # meson removes everything else. With Nix, the locations of libraries
+    # are not as predictable, therefore we need to keep them in the RPATH.
+    # At the moment we are keeping the paths starting with /nix/store.
+    # https://github.com/NixOS/nixpkgs/issues/31222#issuecomment-365811634
+    (substituteAll {
+      src = ./fix-rpath.patch;
+      inherit (builtins) storeDir;
+    })
+  ];
 
   setupHook = ./setup-hook.sh;
 
diff --git a/pkgs/development/tools/build-managers/meson/fix-rpath.patch b/pkgs/development/tools/build-managers/meson/fix-rpath.patch
new file mode 100644
index 000000000000..e52428a7db26
--- /dev/null
+++ b/pkgs/development/tools/build-managers/meson/fix-rpath.patch
@@ -0,0 +1,32 @@
+--- a/mesonbuild/compilers/compilers.py
++++ b/mesonbuild/compilers/compilers.py
+@@ -846,8 +848,10 @@
+             if paths != '':
+                 paths += ':'
+             paths += build_rpath
+-        if len(paths) < len(install_rpath):
+-            padding = 'X' * (len(install_rpath) - len(paths))
++        store_paths = ':'.join(filter(lambda path: path.startswith('@storeDir@'), paths.split(':')))
++        extra_space_needed = len(install_rpath + (':' if install_rpath and store_paths else '') + store_paths) - len(paths)
++        if extra_space_needed > 0:
++            padding = 'X' * extra_space_needed
+             if not paths:
+                 paths = padding
+             else:
+--- a/mesonbuild/scripts/depfixer.py
++++ b/mesonbuild/scripts/depfixer.py
+@@ -300,6 +300,14 @@
+             return
+         self.bf.seek(rp_off)
+         old_rpath = self.read_str()
++
++        if new_rpath:
++            new_rpath += b':'
++        else:
++            new_rpath = b''
++
++        new_rpath += b':'.join(filter(lambda path: path.startswith(b'@storeDir@'), old_rpath.split(b':')))
++
+         if len(old_rpath) < len(new_rpath):
+             sys.exit("New rpath must not be longer than the old one.")
+         # The linker does read-only string deduplication. If there is a