Skip to content

Use DT_RUNPATH instead of DT_RPATH for -C rpath #30378

@geofft

Description

@geofft

On at least GNU/Linux, and possibly on other ELF-based systems, there are two types of rpath, one using the DT_RPATH entry in the dynamic headers and one using the DT_RUNPATH one. The distinction is that DT_RPATH takes precedence over the LD_LIBRARY_PATH environment variable, whereas DT_RUNPATH does not. The latter is more convenient and means that rpaths are less likely to get in your way, since you can override them. DT_RPATH is also claimed to be deprecated by the ld.so manpage. So I think that rustc -C rpath should generate DT_RUNPATH where available.

glibc has supported this since at least 1999. musl 1.1.6 (January 2015) seems to honor DT_RUNPATH but not treat it differently. You can emit both, and the GNU dynamic linker ignores DT_RPATH.

You can tell GNU ld to emit DT_RUNPATH instead of DT_RPATH by adding --enable-new-dtags, probably something like

diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs
index 6674d31..e96f33d 100644
--- a/src/librustc_back/rpath.rs
+++ b/src/librustc_back/rpath.rs
@@ -41,6 +41,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {

 fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
     let mut ret = Vec::new();
+    ret.push("-Wl,--enable-new-dtags".to_string());
     for rpath in rpaths {
         ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
     }

However, neither Apple's linker nor lld supports this, and I'm not really sure how to make this platform-conditional. Hence a bug instead of a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions