gcc: confused about -static -shared -fPIE -fPIC -Wl,-pie - gcc

I'm trying to build clang, with all library static linked in. So that I can run it on CentOS 6 with ancient GCC 4.4 version.
At first, I think adding the option -static by turning on LLVM_BUILD_STATIC is enough. But in the link stage, it errors out.
dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
So, I add -fPIE -Wl,-pie to CMAKE_CXX_FLAGS, and it says
-- Performing Test HAVE_CXX_ATOMICS_WITH_LIB
-- Performing Test HAVE_CXX_ATOMICS_WITH_LIB - Failed
CMake Error at cmake/modules/CheckAtomic.cmake:49 (message):
Host compiler must support std::atomic!
Call Stack (most recent call first):
cmake/config-ix.cmake:307 (include)
CMakeLists.txt:590 (include)
I checked the cmake/modules/CheckAtomic.cmake file, It compiles the following code
#include <atomic>
std::atomic<float> x(0.0f);
int main() { return (float)x; }
with command
/home/hailin/gcc-4.8.3-boost-1.55/rtf/bin/g++ -fPIE -Wl,-pie -DHAVE_CXX_ATOMICS_WITHOUT_LIB -std=c++11 -static -lm
/home/hailin/gcc-4.8.3-boost-1.55/rtf/bin/g++ -fPIE -Wl,-pie -DHAVE_CXX_ATOMICS_WITH_LIB -std=c++11 -static -lm -latomic
The command with option -Wl,-pie reproduce the same error.
It seems like a dead end. Is there any conflict between -shared and -fPIE -Wl,-pie ?

Old question, but in case someone else hits it: apparently you need to pass -pie to the compiler driver (gcc/g++), not just the linker (-Wl,-pie). Some startup object files differ for PIE (e.g. Scrt1.o instead of crt1.o) and these are passed by the driver to the linker, so the driver needs to know that you're making a PIE.

Related

What default libraries does -nolibc remove?

I am working on a project which eventually requires me to link my code against my customized version of libc, libstdc++ and libgcc. Now I am learning what libraries are linked by default.
I tried to compile my project code with -nolibc and manually provide the needed libraries in the argument list.
g++ -fuse-ld=gold -O2 -o main -static -nolibc main.cpp -lgcc -lm -lc
I got the following error, showing that I missed some libraries.
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc_eh.a(unwind-dw2-fde-dip.o):function _Unwind_Find_FDE: error: undefined reference to 'dl_iterate_phdr'
Which library is missing here?

build static linked clang with gcc 4.8.3 on centos

I'm trying to build a static linked executable clang on centos 6. I'm using gcc4.8.3 compiled from source.
If I compile with cmake option -DLLVM_BUILD_STATIC=ON, the error is:
CMake Error at cmake/modules/CheckAtomic.cmake:52 (message):
Host compiler appears to require libatomic, but cannot find it.
Call Stack (most recent call first):
cmake/config-ix.cmake:307 (include)
CMakeLists.txt:590 (include)
If I add -static flag to CMAKE_EXE_LINKER_FLAGS directly, the error is:
ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in
`/usr/lib/../lib64/libc.a(strcmp.o)' can not be used when making
an executable; recompile with -fPIE and relink with -pie
If I add -fPIE to CMAKE_CXX_FLAGS, and -Wl,-pie to CMAKE_EXE_LINKER_FLAGS directly, the error is:
CMake Error at cmake/modules/CheckAtomic.cmake:52 (message):
Host compiler appears to require libatomic, but cannot find it.
Call Stack (most recent call first):
cmake/config-ix.cmake:307 (include)
CMakeLists.txt:590 (include)
Checking the error message in llvm_build/CMakeFiles/CMakeError.log, I found cmake use the following code the check atomic.
#include <atomic>
std::atomic<float> x(0.0f);
int main() { return (float)x; }
The command to compile this code is:
/home/hailin/gcc-4.8.3-boost-1.55/rtf/bin/g++ -std=c++11 -fPIC -fPIE -Wl,-pie -DHAVE_CXX_ATOMICS_WITH_LIB -std=c++11 main.cpp
/home/hailin/gcc-4.8.3-boost-1.55/rtf/lib/gcc/x86_64-unknown-linux-gnu/4.8.3/../../../../x86_64-unknown-linux-gnu/bin/ld: /usr/lib/../lib64/crt1.o: relocation R_X86_64_32S against `__libc_csu_fini' can not be used when making a shared object; recompile with -fPIC
/usr/lib/../lib64/crt1.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
If I remove the flag -Wl,-pie, the error will gone.

linker --as-needed flag not pruning libraries

I'm running into an issue after upgrading gcc from 4.1.1 to 4.7.2. The problem is that the ld --as-needed flag is not pruning libraries that are not required if enough libraries with inter dependencies are listed.
For example, if I build a simple program that doesn't need any special libraries, but includes them on the build line, as such
gcc -m32 test.c -Wl,--as-needed -L/usr/local/lib -lrt -lprojcommon -lproj -lrte -o test
then it builds fine and the --as-needed flag does it's job pruning out all of the listed libs that are not needed.
ldd test
linux-gate.so.1 => (0x00bfc000)
libc.so.6 => /lib/libc.so.6 (0x001ac000)
/lib/ld-linux.so.2 (0x0018a000
However, if I add one more library (in this case crypto), then the build fails with undefined reference errors.
gcc -m32 test.c -Wl,--as-needed -L/usr/local/lib -lcrypto -lrt -lprojcommon -lproj -lrte -o test
/usr/local/lib/librte.so: error: undefined reference to 'tla_decap_data'
/usr/local/lib/librte.so: error: undefined reference to 'do_db'
collect2: error: ld returned 1 exit status
This exact same build worked with 4.1.1, but started failing with 4.7.2.
This is part of a general build infra and libraries included on the build line are generic and expected to be pruned via --as-needed. I could fix this with --allow-shlib-undefined, but I'd prefer to find real unresolved symbols at build time. If I do set --allow-shlib-undefined, then I end up with the same set of required libs as the build that worked.
Any insight would be appreciated.

Android NDK Cannot load library: reloc_library[1306]

Im developing an android app thats loading two shared libraries. One is external, its called libpcan.so . Usually its build to libpcan.so.0.6, this somehow cant be used by my android, i so changed the gcc flags compiling it from:
arm-linux-androideabi-gcc src/libpcan.c -fPIC -shared -O2 -Wall -Wl,-soname,-libpcan.so.0 -lc -I. -I../driver -DNO_RT -o -libpcan.so.0.6
ln -sf libpcan.so.0.6 libpcan.so
to
arm-linux-androideabi-gcc src/libpcan.c -fPIC -shared -O2 -Wall -lc -I. -I../driver -DNO_RT -o -libpcan.so
This .so has the same size as the so.0.6 so i assume it worked fine.
My own c-code is getting compiled with
arm-linux-androideabi -shared src/receivetest.c src/common.c -I. -I../lib -I../driver -L../lib -L/lib -L/usr/lib -L/usr/local/lib -o libreceivetest.so
I load both of these files, so the libpcan.so and the libreceivetest.so to my app
static {
System.loadLibrary("pcan");
System.loadLibrary("receivetest");
}
When I'm trying to launch that app i get the error message:
07-14 11:12:43.812: E/AndroidRuntime(753): java.lang.ExceptionInInitializerError
07-14 11:12:43.812: E/AndroidRuntime(753): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1306]: 36 cannot locate 'CAN_Open'...
My receivetest is using that function, but since it declared in the libpcan.so and im also loading that library, i don't know where that error could come from.
I'd just guess its an error in my clags, since I'm new to building .so files via using gcc in the shell i don't really understand all the flags im using.
It's quite long since i solved this. But I haven't ever marked this question as solved.
Thanks to jww for reminding me.
As I've said in the comment to my question, the link to the function CAN_Open was missing due to a missing parameter at compiling the .so-file. The function CAN_Open is a part of the libpcan.so and by skipping the link to that file the CAN_Open function just never made it into the receivetest.so .

How to get -flto to work?

I'm using GCC 4.7.2 and LD 2.23 but when I add -flto to my compile options my compile time increases by over 20%! The manual seems to indicate that -fuse-linker-plugin is needed for the optimization to work. It also says that it's enabled by default with -flto but when I add it explicitly I see the following error in the link command:
g++: error: -fuse-linker-plugin is not supported in this configuration
According to manual, it should be supported by LD 2.21 or greater. Any idea why I'm getting this error? For reference here are examples of my full compile commands:
g++ -Wall -pipe -O3 -flto -fno-strict-aliasing -mtune=generic --no-exceptions -fPIC -c some.cc
g++ -o exec -Xlinker some1.o some2.o -static some1.a some2.a -Wl,--wrap,open -flto -fuse-linker-plugin
Running 'ld --help | grep plugin' shows "-plugin" option so I don't understand why GCC is complaining:
-plugin PLUGIN Load named plugin
-plugin-opt ARG Send arg to last-loaded plugin
Link time optimizations aren't supposed to reduce compilation time, but optimize runtime of your program.
#options, just add "-flto -fuse-linker-plugin" to your CFLAGS(or CXXFLAGS for c++) and LDFLAGS and it should work just fine.
#gold: ld --version is probably gonna return gnu LD, to switch to gold, make ld symlink which ld point to which ld.gold
e.g. ln -s /usr/bin/ld.gold /usr/bin/ld

Resources