by accidentally, I linked with --shared flag with a hello world c++ program and got an exe file. but output is segfault when I run it. Can someone tell me the reason behind it?
way to reproduce:
standard c++ hello world problem in eclipse c++.
check the shared flag box in setting--> shared library setting.
build output:
make all
Building file: ../app.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -fPIC -MMD -MP -MF"app.d" -MT"app.d" -o "app.o" "../app.cpp"
Finished building: ../app.cpp
Building target: app
Invoking: GCC C++ Linker
g++ -shared -o "app" ./app.o
Finished building target: app
execution output:
segmentation fault
Thanks
From g++ manual:
--shared
Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options that were used to generate code (-fpic, -fPIC, or model suboptions) when you specify this option.[1]
When you put the --shared option, it means that you don't want an executable, but a shared object.
In your case, you create a shared library and not an executable. This is why you segfault when your launch it.
Related
I am creating a gcc shared library having a static library dependency.
I compile the parts for static library as following:
gcc -c -m64 -O2 -fPIC -std=c99 -Wall ms*.c //there are 10 C files, no warnings
Next I create a static library with:
ar rc static_lib.a ms*.o
Next I compile the parts for my program as following:
g++ -c -m64 -O2 -fPIC -std=c++14 -Wall ab*.cpp //there are 5 C++ files, just -Wunused-variable warnings
Then I create a shared library as following:
g++ -shared -g -Wall ab*.o static_lib.a -o shared_lib.so
in the normal case, this shared_lib.so will be called by a Ruby program using a foreign function interface. There is no problem if I do it on ubuntu or mac(.dylib), but if I try this on debian stretch I get an error related to the static library as if the configurations are not set properly. If I run the application without foreign function interface, such as creating a tester and running with the cpp file main function as following:
> g++ -o library_test ab*.o static_lib.a
> ./library_test
There is no problem!
My question is what kind of configuration for creating a shared library may be missing here to not get that undesirable behaviour. Especially on debian stretch 9.5!
Or is there a way that I can understand if there is a problem in the shared library.
From the comments, you indicate the problem is with a #define. Those are preprocessor directives. Libraries are for the linker.
You might be confused because g++ does include the preprocessor phase, and might call the linker depending on the requested output. Still, g++ follows the C++ language rules.
I'm trying to build a self contained executable, which I can run on any/most linux host.
I know I can do that with containers, but for now I'm trying to just statically link my exe.
I compile with:
g++ -std=c++1y -fopenmp -Ofast -g -march=x86-64 -mtune=generic -m64 -c <source>.cpp -MMD -MP -o <object>.o
And link with:
g++ -std=c++1y -fopenmp -Ofast -g -march=x86-64 -mtune=generic -m64 <list of object files> <list of absolute path to static libs .a> -lpthread -static-libgcc -static-libstdc++ -o exe
It used to work just fine, but I just discovered it now breaks on some hosts with
error while loading shared libraries: libmvec.so.1: cannot open shared object file: No such file or directory
I don't know if it's something in the code or system libraries update. I have tried (to no avail):
removing -fopenmp
adding -lmvec -lm to the linker
My exe is indeed statically linked: ldd exe says not a dynamic executable. But it insists on loading libmvec.so at runtime: strace exe says:
execv
a bunch of mmap
open(ld-linux-x86-64.so), read it and close it
open(ld.so.cache), stat, mmap, and close it
open(libpthread.so), read, stat, mmap and close it
open(libmvec.so) => fail on hosts where it doesn't exist
[...]
As I understand libmvec is an extension of libm, dealing with x86 vectorization, used by OpenMP.
So basically, I'm asking if there is a way to make it work statically - I see at least 3 solutions:
disable its use - but that would probably mean performance loss, plus it is used even when I disable OpenMP
statically link it, and somehow explain to the runtime that it then doesn't have to dynamically link to it since it's already linked.
make it optional, i.e. dynamically select a slower code path if it's not available. This sounds complex but could in theory be possible.
So I have a problem that I cannot solve by myself (currently still thinking it through). So I've downloaded g++ and it++ libraries for my project and I've chosen Eclipse as my IDE. Everything worked fine, but then I had to overwrite some files in itpp directory (usr/include/itpp). After doing that I had around 100+ errors all saying "undefined reference to ..." and all of them seems to be coming from the files that were added to the library and I really need them. I've tried removing and downloading everything again, but it doesn't seem to work. It seems to be a linker problem and I'm pretty new to linking and stuff(didn't need it in the past) and I'm not to sure how to do it. As far as I can see, in the main .h file of itpp everything seems to be fine, every new .h file has been included and all of the added files are in the right folder. I hope I've made my point clear, but as my English is imperfect you might have some troubles with understanding my problems - if so please state it and I will make myself more clear.
Thanks in advance for any help!
#Edit:
After adding the command "g++ magisterka.cpp $(pkg-config --libs itpp)" under Project -> Properties -> C/C++ Build -> Settings -> GCC C++ Compiler, I'm left with only one error and that is make*** [src/name.o] Error 1, but I guess that's a problem to discuss in another thread.
#Edit2:
After all my solution was bad. Maybe all errors disappeared, but it was due to the fact that the command line I've mentioned above was wrong and the new error has occured due to the fact that it could not localize magisterka.cpp which is my main file. Therefore I have now 100 errors again. Will try to post a solution as soon as I get one.
#Edit3: Console
make all
Building file: ../src/CodeInstance.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CodeInstance.d" -MT"src/CodeInstance.d" -o "src/CodeInstance.o" "../src/CodeInstance.cpp"
Finished building: ../src/CodeInstance.cpp
Building file: ../src/magisterka.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/magisterka.d" -MT"src/magisterka.d" -o "src/magisterka.o" "../src/magisterka.cpp"
Finished building: ../src/magisterka.cpp
Building target: magisterka
Invoking: GCC C++ Linker
g++ -L/usr/include/itpp -o "magisterka" ./src/CodeInstance.o ./src/magisterka.o -litpp
./src/magisterka.o: In function `main':
I am making a simple hello world program to learn about linking shared libraries in linux. I have managed to compile the main program into an executable with the shared library using the following:
g++ -fPIC -c lab2_hello_main.cpp <--create position independent objects
g++ -fPIC -c lab2_hello_sub.cpp
g++ -fPIC -shared -Wl,-soname=libfuncs.so.1.0 *.o -o libfuncs.so.1.0 -lc <--make the shared library
ln -s libfuncs.so.1.0 libfuncs.so <-- soft links for compiling and running
ln -s libfuncs.so.1.0 libfuncs.so.1
g++ -o hello_dyn lab2_hello_main.cpp -L/mypath -lfuncs <-- Linking the library to main
When I do an ldd on hello_dyn I get an output stating that the library can't be found:
"libfuncs.so.1.0 => not found"
The other libraries it looks for automatically are fine.
Anyone know why this might be?
Your shared library's location is not in the linker's search path. You can confirm this by adding the directory in which your library is located to the LD_LIBRARY_PATH environment variable and then run ldd again. See the ld.so(8) man page for details.
when I build my cpp project in cpp...this is the oupput.
**** Build of configuration Debug for project rtbCookieServer ****
make all
Building file: ../src/rtbCookieServer.cpp
Invoking: GCC C++ Compiler
g++ -I/home/cpp/mongo-cxx-driver-v2.0/mongo -I/home/cpp/mongo-cxx-driver-v2.0 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/rtbCookieServer.d" -MT"src/rtbCookieServer.d" -o"src/rtbCookieServer.o" "../src/rtbCookieServer.cpp"
Finished building: ../src/rtbCookieServer.cpp
Building target: rtbCookieServer
Invoking: GCC C++ Linker
g++ -L/home/cpp/mongo-cxx-driver-v2.0 -lfcgi++ -lboost_system -lcgicc -lmongoclient -o"rtbCookieServer" ./src/rtbCookieServer.o
Finished building target: rtbCookieServer
W=hen I run the code..the is the error message I get.
/home/workspace/rtbCookieServer/Debug/rtbCookieServer: error while loading shared libraries: libmongoclient.so: cannot open shared object file: No such file or directory
The file is in home/cpp/mongo-cxx-driver-v2.0 so why cant if find it????
Thanks
Better than using LD_LIBRARY_PATH is to specify the runtime library search
-Wl,-rpath /home/cpp/mongo-cxx-driver-v2.0
For more information about why not using LD_LIBRARY_PATH look e.g. here.
Try the command
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/cpp/mongo-cxx-driver-v2.0
first, and try again.
The loader doesn't know the path to the library, so it has to be told where to look.