diff mbox series

[RFC] classes/cmake: don't put RPATHs to the build tree in binaries

Message ID 20250915145134.192581-1-ross.burton@arm.com
State New
Headers show
Series [RFC] classes/cmake: don't put RPATHs to the build tree in binaries | expand

Commit Message

Ross Burton Sept. 15, 2025, 2:51 p.m. UTC
By default, CMake will compile binaries with an RPATH pointing at the
build path, and then on install will "relink" the binaries with an
RPATH pointing to the install path.

However, when CMake says "relink" it actually means "edit if possible",
using an internal copy of chrpath. This introduces non-determinism in
several ways:
- The build path is used to generate the build-id. We've worked around
  this previously by ensuring that RPATHs are relative to the binary[1].
- Not all upstreams respect this option, so some recipes need extra
  tweaking to stop them injecting absolute build-time RPATHs[2]
- Whilst the final RPATH may be empty, using chrpath is _not_ relinking
  so different length build paths can result in binaries with different
  amounts of now-redundant padding. These binaries are non-reproducible.

Instead of using relative build-time RPATHs and then dealing with other
issues one by one, we can just tell CMake to not use built-time RPATHs
at all. We don't execute binaries directly from the build tree, so they
don't serve any purpose and are just a source of non-determinism.

[1] oe-core 44e77d3f97a ("classes/cmake: Use relative RPATHs")
[2] oe-core d96e0458b69 ("lldb: don't build rpaths into binaries")

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 meta/classes-recipe/cmake.bbclass | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Ross Burton Sept. 15, 2025, 3:37 p.m. UTC | #1
On 15 Sep 2025, at 15:51, Ross Burton via lists.openembedded.org <ross.burton=arm.com@lists.openembedded.org> wrote:
> By default, CMake will compile binaries with an RPATH pointing at the
> build path, and then on install will "relink" the binaries with an
> RPATH pointing to the install path.

Context here is that the clang recipes love putting absolute build paths into the RPATHs, destroying reproducibility. This is a sledgehammer to stop it happening globally, if people think it’s a bit too heavy for this late in the cycle I can do it in the clang recipes.

Ross
diff mbox series

Patch

diff --git a/meta/classes-recipe/cmake.bbclass b/meta/classes-recipe/cmake.bbclass
index 1488d744d40..18c26c196fa 100644
--- a/meta/classes-recipe/cmake.bbclass
+++ b/meta/classes-recipe/cmake.bbclass
@@ -163,10 +163,12 @@  set( ENV{QT_CONF_PATH} ${WORKDIR}/qt.conf )
 
 # We need to set the rpath to the correct directory as cmake does not provide any
 # directory as rpath by default
+
 set( CMAKE_INSTALL_RPATH ${OECMAKE_RPATH} )
 
-# Use RPATHs relative to build directory for reproducibility
-set( CMAKE_BUILD_RPATH_USE_ORIGIN ON )
+# Don't build build RPATHS into the binaries, they're a source of non-determinism
+# even when stripped out of the installed files
+set (CMAKE_SKIP_BUILD_RPATH ON)
 
 # Use our cmake modules
 list(APPEND CMAKE_MODULE_PATH "${STAGING_DATADIR}/cmake/Modules/")