New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ubuntu bionic x86_64: static libc++.a version 9 cannot be used in shared libraries since build without -fPIC #42949
Comments
assigned to @ldionne |
libc++ from llvm-8 have no such problem |
Unsure who all to CC here, but this issue makes the apt.llvm.org Debian packages really broken. The issue persists to this day with LLVM 12. Basic example of how this works well with libstdc++ but not with libc++:
Note that I've verified that this happens at least with 10, 11, and 12. Any chance we could fix this? I'm pretty sure this just a CMake setting getting flipped, and so it'd be particularly nice to actually push fresh debian archives with this fix as w/o it the debian packages are completely broken for this use case. |
I forgot to add that this mostly breaks use of a statically linked libc++ with PIE executables:
All of this testing is done on a vanilla Ubuntu 20.04 (LTS) install with the https://apt.llvm.org/llvm.sh script used to install the relevant packages. |
I'm digging through this issue now. I believe the following commit is relevant for context:
Basically, I removed At the time, it seemed excessive to force whoever's building libc++ (e.g. vendors) to use -fPIC if they don't want to. The idea was to use So, I acknowledge 100% that the problem you're seeing exists and needs to be fixed. I'm just not certain whether: (1) we should start enforcing I'd be leaning towards (2) since that would bring back the ability to use libc++.a as released by LLVM in shared libraries and PIE executables without forcing all vendors to go down the same route. On the other hand, I'm not super well versed in the whole PIE/PIC story, so I read this to try and get a better idea of the tradeoffs: https://lists.debian.org/debian-devel/2016/05/msg00309.html. This seems to suggest that nowadays, avoiding |
I might go with (2) if possible for patching the LLVM-12 release, and I would really love to see a patch release with this fixed. It seems a strict improvement at low cost (only the .a files change).
I largely agree with this assessment. I think that building .o files and .a files with PIC always (on Linux ABIs at least) and then letting the linker do its thing for .so and executables is the best choice. At the least, it'd be nice of users that build their own libc++ got the right defaults out of the box here, and the right default seems almost certainly for PIC .a files -- otherwise PIE isn't ever really an option. |
The -fPIE/-fPIC distinction is ELF specific. The only differences are:
The main CMake file uses -fno-semantic-interposition by default now (https://reviews.llvm.org/D102453) so the second benefit is moot. I know very little about CMake and just learned CMAKE_POSITION_INDEPENDENT_CODE. llvm/CMakeLists.txt I think defaulting CMAKE_POSITION_INDEPENDENT_CODE to on makes a lot of sense... |
Try to rebuild -12 packages (apt.llvm.org) with but I am getting the same issue: echo '#include clang++-12 -o test test.cpp -pie -stdlib=libc++ -static-libstdc++ /usr/bin/ld: /tmp/test-75d1cf.o: relocation R_X86_64_32 against undefined symbol |
Some of those errors are from your test, try:
The The others do look like the same bug here. But the path to Is the stage2 build where you're adding the CMake flag the one that is building the runtimes, or just the stage2 compiler? Maybe need to pass the CMake flags specifically to the runtimes part of the build (which can happen even in stage1) |
Can this be fixed by just setting the necessary CMake variable when building the debian packages? |
Somewhere, yes. Not sure where the CMake variables are set when building the debian packages. If you point me at the script I can try to suggest how to fix things. |
Here is the patch that I applied: diff --git a/debian/rules b/debian/rules
sources are: you can find the tarballs: for example: (takes a while) |
You'll also want to add it to the bootstrap passthrough flag list I would guess? I would love to send you patches to this file, but there is no license and so I'm unsure how to do so... While patching this, maybe add the fix suggested here so that the resulting archive also works out of the box? llvm/llvm-bugzilla-archive#46321 #c5 |
I just started a new build to see if it fixes the issue.
Sure, I will have a look. |
Chandler, failed again -even with CLANG_BOOTSTRAP_PASSTHROUGH diff --git a/debian/rules b/debian/rules
@@ -417,7 +418,7 @@ override_dh_auto_configure: preconfigure
$ clang++-12 -o test -fPIC test.cpp -pie -stdlib=libc++ -static-libstdc++ |
Okay, so I created two patches to try and solve this problem, which embody the two ways I see of fixing this:
Once we've settled on the approach, I'll merge this to |
I don't feel particularly strongly about this, but figured I'd share my perspective...
IMO, there is a relevant layering distinction here, but I'd put it in a slightly different place. The difference I would draw is between the build of libraries directly part of LLVM and Clang, and the runtime libraries that are used automatically by For runtime libraries, I think always using PIC is reasonable. But for non-runtime LLVM and Clang libraries, I don't think it's nearly as reasonable. Unfortunately, neither patch is exactly this runtimes vs. non-runtimes split... So to an extent, I prefer #1 because it at least covers all the runtimes... But if folks want, I think there is a viable separation here if anyone really wants to pursue it.
|
We need some consensus on how to fix this soon (1 or 2 days) or this fix won't make the release. We can work-around this problem by passing -DMAKE_POSITION_INDEPENDENT_CODE=ON to the release script when building LLVM, so another option would be to ask the release testers to use this option when building the packages. |
This should be fixed by:
That should have been committed in time for the LLVM 13 release. I had no strong preference between the two approaches I proposed above, but I ended up going with D104328 because I am more familiar with the runtimes' build scripts than the release scripts. If this patch causes an issue for someone, please contact me and we'll figure something out. Sylvestre (or someone else), can you please confirm whether you're still seeing the issue after 21c24ae? |
mentioned in issue #48661 |
Extended Description
/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(algorithm.cpp.o): relocation R_X86_64_32S against
.rodata._ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(chrono.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(condition_variable.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(exception.cpp.o): relocation R_X86_64_32S against symbol
_ZTVSt16nested_exception' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(future.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(hash.cpp.o): relocation R_X86_64_32 against
.rodata' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(ios.cpp.o): relocation R_X86_64_32S against symbol
_ZTVNSt3__18ios_baseE' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(iostream.cpp.o): relocation R_X86_64_32 against
.bss' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(locale.cpp.o): relocation R_X86_64_32 against
.bss' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(memory.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(mutex.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(new.cpp.o): relocation R_X86_64_32 against symbol
_ZTISt9bad_alloc' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(regex.cpp.o): relocation R_X86_64_32 against symbol
__gxx_personality_v0' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(stdexcept.cpp.o): relocation R_X86_64_32S against symbol
_ZTVSt11logic_error' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(string.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(system_error.cpp.o): relocation R_X86_64_32S against symbol
_ZTVNSt3__114error_categoryE' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(thread.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(vector.cpp.o): relocation R_X86_64_32 against
.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC/usr/bin/ld: /usr/lib/llvm-9/lib/libc++.a(charconv.cpp.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
The text was updated successfully, but these errors were encountered: