1- From 6d3899390bf75985eb79a106f6a487b335509114 Mon Sep 17 00:00:00 2001
1+ From 432a43ac75e3b124fde2476458a199ceba12582f Mon Sep 17 00:00:00 2001
22From: Christian Marangi <ansuelsmth@gmail.com>
33Date: Sun, 12 Oct 2025 13:57:15 +0200
44Subject: [PATCH] linkers: don't include absolue RPATH on cross-compiling
@@ -17,24 +17,26 @@ packed in the final system (for example a squashfs image)
1717
1818On top of this on cross-compilation on 99% of the scenario, it's not
1919really possible to run the just built tool for build usage as it
20- probably target a different arch.
20+ probably target a different arch (unless the project provide an
21+ exe_wrapper).
2122
2223To permit building REAL reproducible binary, add extra logic to skip the
2324inclusion of such library path in RPATH if we detect a cross-compilation
2425scenario and limit the inclusion of library path in RPATH only to
2526relative path (expected to be the ones specific to the building
26- binary/internal shared library)
27+ binary/internal shared library) if we detect the binaries can't be run
28+ on the host system (by the use of can_run_host_binaries() API).
2729
2830Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2931---
30- mesonbuild/linkers/linkers.py | 57 ++++++++++++++++++++++++- ----------
31- 1 file changed, 40 insertions(+), 17 deletions(-)
32+ mesonbuild/linkers/linkers.py | 62 +++++++++++++++++++++++++ ----------
33+ 1 file changed, 45 insertions(+), 17 deletions(-)
3234
3335--- a/mesonbuild/linkers/linkers.py
3436+++ b/mesonbuild/linkers/linkers.py
35- @@ -523 ,11 +523 ,11 @@ class MetrowerksStaticLinkerARM(Metrower
36- class MetrowerksStaticLinkerEmbeddedPowerPC(MetrowerksStaticLinker) :
37- id = 'mwldeppc'
37+ @@ -558 ,11 +558 ,11 @@ class TaskingStaticLinker(StaticLinker):
38+ def get_linker_always_args(self) -> T.List[str] :
39+ return ['-r']
3840
3941- def prepare_rpaths(raw_rpaths: T.Tuple[str, ...], build_dir: str, from_dir: str) -> T.List[str]:
4042+ def prepare_rpaths(env: Environment, raw_rpaths: T.Tuple[str, ...], build_dir: str, from_dir: str) -> T.List[str]:
@@ -46,7 +48,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
4648 ordered_rpaths = order_rpaths(internal_format_rpaths)
4749 return ordered_rpaths
4850
49- @@ -544 ,11 +544 ,16 @@ def order_rpaths(rpath_list: T.List[str]
51+ @@ -579 ,11 +579 ,16 @@ def order_rpaths(rpath_list: T.List[str]
5052 return sorted(rpath_list, key=os.path.isabs)
5153
5254
@@ -65,7 +67,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
6567 else:
6668 return os.path.relpath(os.path.join(build_dir, p), os.path.join(build_dir, from_dir))
6769
68- @@ -673 ,7 +678 ,7 @@ class GnuLikeDynamicLinkerMixin(DynamicL
70+ @@ -711 ,7 +716 ,7 @@ class GnuLikeDynamicLinkerMixin(DynamicL
6971 return ([], set())
7072 args: T.List[str] = []
7173 origin_placeholder = '$ORIGIN'
@@ -74,94 +76,94 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
7476 # Need to deduplicate rpaths, as macOS's install_name_tool
7577 # is *very* allergic to duplicate -delete_rpath arguments
7678 # when calling depfixer on installation.
77- @@ -683 ,9 +688 ,13 @@ class GnuLikeDynamicLinkerMixin(DynamicL
79+ @@ -721 ,9 +726 ,13 @@ class GnuLikeDynamicLinkerMixin(DynamicL
7880 rpath_dirs_to_remove.add(p.encode('utf8'))
7981 # Build_rpath is used as-is (it is usually absolute).
80- if build_rpath != '':
81- - all_paths.add(build_rpath)
82- - for p in build_rpath.split(':'):
82+ if target. build_rpath != '':
83+ - all_paths.add(target. build_rpath)
84+ - for p in target. build_rpath.split(':'):
8385- rpath_dirs_to_remove.add(p.encode('utf8'))
84- + paths = build_rpath.split(':')
86+ + paths = target. build_rpath.split(':')
8587+ for p in paths:
8688+ # Only include relative paths if we can't run binaries on host system.
8789+ # (cross-compilation and no exe_wrapper)
8890+ if env.can_run_host_binaries() or not os.path.isabs(p):
8991+ all_paths.add(p)
9092+ rpath_dirs_to_remove.add(p.encode('utf8'))
93+ if extra_paths:
94+ all_paths.update(extra_paths)
9195
92- # TODO: should this actually be "for (dragonfly|open)bsd"?
93- if mesonlib.is_dragonflybsd() or mesonlib.is_openbsd():
94- @@ -828,10 +837,15 @@ class AppleDynamicLinker(PosixDynamicLin
96+ @@ -883,10 +892,15 @@ class AppleDynamicLinker(PosixDynamicLin
9597 # @loader_path is the equivalent of $ORIGIN on macOS
9698 # https://stackoverflow.com/q/26280738
9799 origin_placeholder = '@loader_path'
98100- processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
99101+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir)
100102 all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths])
101- if build_rpath != '':
102- - all_paths.update(build_rpath.split(':'))
103- + paths = build_rpath.split(':')
103+ if target. build_rpath != '':
104+ - all_paths.update(target. build_rpath.split(':'))
105+ + paths = target. build_rpath.split(':')
104106+ for p in paths:
105107+ # Only include relative paths if we can't run binaries on host system.
106108+ # (cross-compilation and no exe_wrapper)
107109+ if env.can_run_host_binaries() or not os.path.isabs(p):
108110+ all_paths.add(p)
111+ if extra_paths:
112+ all_paths.update(extra_paths)
109113 for rp in all_paths:
110- rpath_dirs_to_remove.add(rp.encode('utf8'))
111- args.extend(self._apply_prefix('-rpath,' + rp))
112- @@ -1200,10 +1214,15 @@ class NAGDynamicLinker(PosixDynamicLinke
114+ @@ -1261,10 +1275,15 @@ class NAGDynamicLinker(PosixDynamicLinke
113115 return ([], set())
114116 args: T.List[str] = []
115117 origin_placeholder = '$ORIGIN'
116118- processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
117119+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir)
118120 all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths])
119- if build_rpath != '':
120- - all_paths.add(build_rpath)
121- + paths = build_rpath.split(':')
121+ if target. build_rpath != '':
122+ - all_paths.add(target. build_rpath)
123+ + paths = target. build_rpath.split(':')
122124+ for p in paths:
123125+ # Only include relative paths if we can't run binaries on host system.
124126+ # (cross-compilation and no exe_wrapper)
125127+ if env.can_run_host_binaries() or not os.path.isabs(p):
126128+ all_paths.add(p)
129+ if extra_paths:
130+ all_paths.update(extra_paths)
127131 for rp in all_paths:
128- args.extend(self._apply_prefix('-Wl,-Wl,,-rpath,,' + rp))
129-
130- @@ -1454,15 +1473,19 @@ class SolarisDynamicLinker(PosixDynamicL
131- install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
132- if not rpath_paths and not install_rpath and not build_rpath:
132+ @@ -1517,15 +1536,19 @@ class SolarisDynamicLinker(PosixDynamicL
133+ rpath_paths = target.determine_rpath_dirs()
134+ if not rpath_paths and not target.install_rpath and not target.build_rpath and not extra_paths:
133135 return ([], set())
134136- processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
135137+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir)
136138 all_paths = mesonlib.OrderedSet([os.path.join('$ORIGIN', p) for p in processed_rpaths])
137139 rpath_dirs_to_remove: T.Set[bytes] = set()
138140 for p in all_paths:
139141 rpath_dirs_to_remove.add(p.encode('utf8'))
140- if build_rpath != '':
141- - all_paths.add(build_rpath)
142- - for p in build_rpath.split(':'):
142+ if target. build_rpath != '':
143+ - all_paths.add(target. build_rpath)
144+ - for p in target. build_rpath.split(':'):
143145- rpath_dirs_to_remove.add(p.encode('utf8'))
144- + paths = build_rpath.split(':')
146+ + paths = target. build_rpath.split(':')
145147+ for p in paths:
146148+ # Only include relative paths if we can't run binaries on host system.
147149+ # (cross-compilation and no exe_wrapper)
148150+ if env.can_run_host_binaries() or not os.path.isabs(p):
149151+ all_paths.add(p)
150152+ rpath_dirs_to_remove.add(p.encode('utf8'))
153+ if extra_paths:
154+ all_paths.update(extra_paths)
151155
152- # In order to avoid relinking for RPATH removal, the binary needs to contain just
153- # enough space in the ELF header to hold the final installation RPATH.
154- @@ -1525,7 +1548,12 @@ class AIXDynamicLinker(PosixDynamicLinke
155- if install_rpath != '':
156- all_paths.add(install_rpath)
157- if build_rpath != '':
158- - all_paths.add(build_rpath)
159- + paths = build_rpath.split(':')
156+ @@ -1591,7 +1614,12 @@ class AIXDynamicLinker(PosixDynamicLinke
157+ if target.install_rpath != '':
158+ all_paths.add(target.install_rpath)
159+ if target.build_rpath != '':
160+ - all_paths.add(target.build_rpath)
161+ + paths = target.build_rpath.split(':')
160162+ for p in paths:
161163+ # Only include relative paths if we can't run binaries on host system.
162164+ # (cross-compilation and no exe_wrapper)
163165+ if env.can_run_host_binaries() or not os.path.isabs(p):
164166+ all_paths.add(p)
165- for p in rpath_paths :
167+ for p in target.determine_rpath_dirs() :
166168 all_paths.add(os.path.join(build_dir, p))
167169 # We should consider allowing the $LIBPATH environment variable
0 commit comments