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):
-
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
forlibLHAPDF.a
. -
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.
-
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 runecho "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. -
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?