Why does `-Crelocation-model=dynamic-no-pic` help although it shouldn't?

Yesterday I was debugging linker problems of the sort:

relocation R_X86_64_32 against '...' can not be used when making a PIE object; recompile with -fPIE

and to make a long story short, here are the facts and a solution; what I would like to know is why this is working, and especially why this seemingly contradicts what rustc's manual says (see below):

  1. I'm building a binary on Linux and link all its dependencies (C++ libraries) statically, by printing the usual strings, for instance cargo:rustc-link-lib=static=LHAPDF for libLHAPDF.a.

  2. This works fine on both my desktop computer (Debian GNU/Linux 11 (bullseye)) and my laptop (Gentoo), but it doesn't work in the anylinux2014 container that I'm using on Github. The error messages are all the ones given above.

  3. The difference between the systems where it works and not, I believe, is that the C compiler/linker was configured with --enable-default-pie. When I run echo "int main() {}" > test.c && cc -v test.c on my desktop and my laptop they both show --enable-default-pie but the container doesn't.

  4. When I compile my binary with

    RUSTFLAGS='-Crelocation-model=dynamic-no-pic' cargo install --features=static --path pineappl_cli --locked
    

it perfectly compiles in the container. Now, the reason I added this RUSTFLAG was that I searched on the internet and I found people had similar problems and this flag fixed their problems for them. However, when I lookup this parameter in the manual, it says:

dynamic-no-pic - relocatable external references, non-relocatable code. Only makes sense on Darwin and is rarely used. If StackOverflow tells you to use this as an opt-out of PIC or PIE, don't believe it, use -C relocation-model=static instead.

I tried relocation-model=static, but that doesn't work because serde-derive and some other crates try to build dyanamically linked code (?).

To summarize, I'm on Linux, but the docs say it only makes sense on Darwin. I also can seemingly use it to opt out of PIE, which the docs claim it doesn't do. Can someone explain?

I can't speak to how the rustc relocation models work, but the "proper" fix here would be to build your C libraries with -fPIC in CFLAGS.

1 Like

Thank you @sfackler! Why wasn't this the first thing I tried :man_facepalming:? For anyone else running into the same problem, if you have autotools-built dependencies you can add the flag to static libraries by running:

./configure ... --with-pic=yes

The original question still stands, but it is less relevant now.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.