How can I get GCC to use that static library instead of the dynamic one? Normally you add the .a file to the linker parameters. But libssp linking is triggered by the -fstack-protector option. And compiler prefers linking to the shared library if it finds one instead of static library.
If I try to run the resulting program on systems that don't have the libssp.so the program won't run.
(After system upgrade on some build machines, the older boxes on the test system screwed up)
Does
gcc -static static.c -o static -fstack-protector-all
or
gcc -static -lssp static.c -o static -fstack-protector-all
work? Can you run ldd on the resulting binaries?
What version of gcc are you using?
Related
I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.
I am trying to build an executable from different libraries using the below statement
g++ -fPIC -O -DUSING_PCH -D_REENTRANT -I"/app1/home1/quickfast/boost_1_61_0/include/boost-1_61" -I"/app1/home1/quickfast/boost_1_61_0/." -I"../../src" -I"../src/Examples" -I"/app1/home1/quickfast/boost_1_61_0/include" -L"." -L"/app1/home1/quickfast/boost_1_61_0/stage/lib" -L/app1/home1/quickfast/quickfast-master/lib -l"QuickFAST" -l"boost_thread-gcc44-mt-1_61" -l"boost_system-gcc44-mt-1_61" -l"boost_filesystem-gcc44-mt-1_61" -l"boost_unit_test_framework-gcc44-mt-1_61" -static -ldl -lpthread -o "../../bin/testSequences"
The above compilation statement includes lot of libraries, which are availabe as dynamic libaries(.so file) as well as static libraries (.a file). For example library boost_system-gcc44-mt-1_61 is present in the system as libboost_system-gcc44-mt-1_61.so as well as libboost_system-gcc44-mt-1_61.a . What I want is that while compilation only dynamic libraries (.so files) are picked up and static libraries are ignored. Can someone please guide.
You are telling it to pick up static libraries by using the -static link option. If you remove it, it'll probably work as you expect.
I am developing and testing some code on 2 different machines: my own *buntu laptop and a remote linux machine configured by someone else.
My code uses a library, let's say libfoo, that in turn depends on, say, libbase.
I would like to keep a single makefile across both the machines, but I found out things works differently when I build my project (with GCC):
On my laptop, I need to specify -lfoo -lbase for the code to link
correctly.
On the remote machine, I only need the -lfoo flag, and the linker
somehow picks up the base library automagically.
Anyone knows what is going on? Is there any flag that might have been passed when building libfoo from source that made this automatical "depencency detection" possible?
PS: I know I could just specify every library in the make file, but keeping the list of flags to the minimum looks interesting, and I would like to know what's going on under the hood.
Yes. Both -lfoo and -lbase refer to some shared libraries libfoo.so and libbase.so (perhaps with some version number).
On the remote machine, libfoo.so was built and linked to libbase.so, perhaps from some foo1.c and foo2.c like
gcc -Wall -O -fPIC foo1.c -o foo1.pic.o
gcc -Wall -O -fPIC foo2.c -o foo2.pic.o
gcc -shared -O foo1.pic.o foo2.pic.o -lbase -o libfoo.so
(of course, probably some Makefile did run above commands thru make)
On your own laptop, you (or your distribution maker) did not link -lbase inside libfoo.so
Read Drepper's how to write shared library (long) paper (and the program library howto)
It is possible to link a shared (low-level) library inside another (higher-level) shared library (and that is not possible with static libraries libfoo.a).
You could use ldd on (the absolute path of) your libraries libfoo.so and libbase.so to find out how they have been linked.
I have a project where I have one static library libhelper.a and another with my actual shared object library, libtestlib.so. My goal is to link libhelper.a into libtestlib.so. Is that possible on Linux/BSD? When I tried and created a test program I got the following errors:
./prog1:/usr/local/lib/libtestlib.so.1.0: undefined symbol ''
My guess is that this is occurring because libhelper.a was not compiled with -fPIC while libtestlib.so was. What is the proper way to build programs that use shared libraries that also have dependancies on static libraries?
Thanks!
My goal is to link libhelper.a into libtestlib.so. Is that possible on Linux?
Sure. This should do:
gcc -shared -fPIC -o libtestlib.so $(OBJS) \
-Wl,--whole-archive -lhelper -Wl,--no-whole-archive
libhelper.a was not compiled with -fPIC
It's best to rebuild libhelper.a with -fPIC. If that's not possible, above command will still work on Linux/ix86, but not on e.g. Linux/x86_64.
What is the proper way to build programs that use shared libraries that also have dependancies on static libraries?
If you include libhelper.a into libtestlib.so as above, then simple:
gcc main.c -ltestlib
is all you need. If you insist on linking with libhelper.a, then you must tell the end-user that he must link with e.g.
gcc main.c -ltestlib -lhelper
There is no way to specify that libtestlib.so depends on libhelper.a.
I am working in Linux, Eclipse CDT, g++, with Boost library. Having existing program which uses Boost thread, I try to link it statically instead of dynamically. /usr/local/lib directory contains the following files:
libbost_thread.a
libbost_thread.so
libbost_thread.1.41.0
Dynamic linking works:
g++ -o"MyProgram" ./main.o -lboost_thread
Static linking:
g++ -static -o"MyProgram" ./main.o -lboost_thread
produces huge number of messages like:
undefined reference to `pthread_mutex_init'
How can I link statically to the Boost library?
For pthread_mutex_init, you want to compile/link with -pthread option:
g++ -static -pthread -o"MyProgram" ./main.o -lboost_thread
The problem is that functions like pthread_mutex_init are in a separate library. Dynamic libraries can include the metadata for the fact that it needs the separate library (so libboost_thread.so includes the fact that it needs libpthread).
But static libraries don't have that information. So you need to provide the reference to any necessary libraries when you link statically.
As for using -pthread instead of -lpthread, it's slightly preferable because it not only links the necessary library, but provides any other options that should be used (such a -D_REENTRANT to the compiler).
Try adding -lpthread to your invocation.
On Linux a dynamic library may automatically depend on other dynamic libraries so that when you link it, you get the other libraries for free. When linking statically, there is no such system and you have to specify the other libraries manually.