We created a shared object file and linked to our executable:
add_executable(a ${A_SRC})
add_library(testso SHARED src/mainlib.cc test1.cc test2.cc)
target_link_libraries(a, testso)
we notice that the code is compiling without -fPIC, but the link uses -fPIC:
g++ -std=c++11 -g -c -i../../src ./test1.cc
g++ -std=c++11 -shared -fPIC ../mainlib.cc test1.o -o testso.so
Is the -fPIC flag required on each file? Will we crash at some point or is this ok?
Related
I have a source file, mything.cpp, and a library that was provided to me as notmine.h and notmine.a.
I need to produce a shared object that has all my stuff from mything.cpp and all the stuff from somelib.a. Here is what I did on the command line:
g++ -fpic -c -o mything.o mything.cpp
g++ -shared -o mything.so mything.o notmine.a
However, when I look at the final mything.so using ldd I see that it has a dependency on libnotmine.so, and when I check nm, I see that all the symbols that should have been supplied by notmine.a are undefined.
What am I doing wrong?
More details: notmine.a is actually liblua.a that I built locally. I think g++ might be getting confused because there is a liblua.so in the system directories
Finally figured it out. There are two options. The simpler is to use:
g++ -fpic -c -o mything.o mything.cpp
g++ -shared -o mything.so mything.o -L. -l:notmine.a
Alternatively, you can tell the linker you want to treat the .a as a bunch of object files with
g++ -fpic -c -o mything.o mything.cpp
g++ -shared -o mything.so mything.o -Wl,--whole_archive notmine.a -Wl,--no-whole-archive
The --Wl,-no-whole-archive is to prevent that flag from messing up the other steps the linker does with the system libraries
I'm trying to statically link glibc in order to run my application on an older OS, but when I use the -static flag I get "undefined reference" errors for other libraries I'm using that I don't get without using -static. How do I fix this issue?
My Makefile produces the following commands:
g++ -static -Wall -O3 -w -std=c++11 -I/storage/home/PA/libs -I/storage/home/PA/libs/xerces -fopenmp -c Utilities.cpp
gcc -static -Wall -O3 -w -std=c++11 -I/storage/home/PA/libs -I/storage/home/PA/libs/xerces -fopenmp -c ccvt.c
gcc -static -Wall -O3 -w -std=c++11 -I/storage/home/PA/libs -I/storage/home/PA/libs/xerces -fopenmp -c client.c
g++ -static -Wall -O3 -w -std=c++11 -I/storage/home/PA/libs -I/storage/home/PA/libs/xerces -fopenmp -c XML_Params.cpp
g++ -static -Wall -O3 -w -std=c++11 -I/storage/home/PA/libs -I/storage/home/PA/libs/xerces -fopenmp -c main.cpp
g++ -static -Wall -O3 -std=c++11 -L/storage/home/PA/libs/gsl -fopenmp -lgsl -lgslcblas -lm -L/storage/home/PA/libs/xerces -lxerces-c -o App main.o Utilities.o XML_Params.o ccvt.o client.o
After the last line I get a huge wall of errors complaining about undefined references to Xerces and gsl functions. However, if I remove the -static from the makefile, everything builds fine. What is the proper way to link these libraries when I'm using -static?
according to gcc manual:
-llibrary
It makes a difference where in the command you write this option; the
linker searches and processes libraries and object files in the order
they are specified. Thus, foo.o -lz bar.o searches library z after
file foo.o but before bar.o. If bar.o refers to functions in z,
those functions may not be loaded.
Move -lxerces after *.o might solve your problem.
I think you don't need to add -static except for the last line, correct me if i'm wrong.
I am trying to compile an example from dlib.net using g++. I find that directly compiling the example into an executable works fine using:
g++ -std=c++11 -O3 -I/usr/lib /usr/lib/dlib/all/source.cpp -lpthread -lX11 optimization_ex.cpp -o optimiation_ex
But when I compile the source into object files first (1) and link later (2),
g++ -std=c++11 -O3 -I/usr/lib -c /usr/lib/dlib/all/source.cpp -lpthread -lX11 -o /usr/lib/dlib/all/source.o
g++ -std=c++11 -O3 -I/usr/lib -c optimization_ex.cpp -lpthread -lX11 -o optimization_ex.o
g++ /usr/lib/dlib/all/source.o optimization_ex.o -o optimization_ex
Then the executable cannot be compiled and g++ complains about undefined references.
What is going on behind this behavior? And how can I link the executable from the object files?
Problem
Say I've got a Linux executable MAIN that uses an old version of some shared library LIB.so (which it locates using LD_LIBRARY_PATH).
I'd like MAIN to also use my library MYLIB.so, except this uses a newer version of LIB.so.
MAIN and MYLIB.so both use functions that appear in both versions of LIB.so with the same name (but different implementations).
How do I get the application to also load the new version of LIB.so when it loads MYLIB.so?
What doesn't seem to work
I've tried compiling MYLIB.so with an RPATH option pointing to the new version of the library. However, while this correctly identifies the newer library when I run ldd MYLIB.so, when the application runs it only uses the old library implementation.
My compilation (using single file toy implementations for clarity) is as follows:
# compile old library implementation
g++ -c -Wall -Werror -fpic library_old.cpp
g++ -shared -o liblib.so library_old.o
# compile new library implementation
g++ -c -Wall -Werror -fpic library_new.cpp
g++ -shared -o new/liblib.so library_new.o
# compile my library against new liblib
g++ -c -Wall -Werror -fpic my_library.cpp
g++ -L`pwd`/new -shared -Wl,-rpath,`pwd`/new -o libmine.so my_library.o -llib
# compile application against old liblib
g++ -L`pwd` -Wall -Werror -o main main.cpp -llib -lmine
export LD_LIBRARY_PATH=`pwd`
Is it possible to compile Paho CPP as a static executable? If so - how?
Here is an example of the compilation statement for one of the examples:
g++ -DOPENSSL -I.. -I/usr/local/include -D_NDEBUG -Wall -std=c++11 -O2 -o data_publish data_publish.cpp -L../../lib -L/usr/local/lib -lpaho-mqttpp3 -lpaho-mqtt3a
How do I compile this as a static executable?
Build Paho with static libraries.
And then link it with -static command line switch. E.g. g++ ... -static -lpaho-mqttpp3 -lpaho-mqtt3a.