What steps does gcc(or g++) take in searching for the location of libaries? - c++

When using the -l flag in a c++ makefile, I couldn't find information on what steps gcc takes in searching for that library.
For clarity of what I'm asking, I'll make up an example answer (this is completely made up):
First searches the -L flag directory
Next searches the /lib directory
Something something etc
Some extra info:
The reason I'm stuck in this is because I currently have a program that uses libconfig in the makefile like so:
g++ $(CFLAGS) -o libvldsk_config.so $(SRCDIR)/config.cpp -Wall -shared -fPIC -I$(SRCDIR) -I$(COMMON_SRCDIR) -lconfig
but this was made assuming that libconfig is installed via a package manager. I installed via source because the linux version was too old to have it in a package manager. And so I'm trying to modify my program that uses libconfig to search for the libconfig .so file in the system's /lib directory, and if it doesn't exist search for it in the current project directory.

Related

Quick Rundown on C++ libraries?

I am trying to troubleshoot a problem I have in using the library matplot++. I need someone to teach me how to fish here instead of giving me a fish, because I'm struggling to google search the right terms to solve my problem.
My folder structure is as follows
-music_vis
|-libs
|-3rd party
|-matplot
|-matplot.h
|-other_folders_for_matplot
|-wavs
|build.sh
|main.cpp
|thread_pool.hpp
build.sh is as follows right now:
g++ -Wall -lmatplot -I /$(pwd)/libs -g -o music_vis_cpp ./music_vis_main.cpp -lstdc++fs -std=c++17 -pthread
Everything 100% works in this shell script except for something within this section:
-lmatplot -I /$(pwd)/libs
For which I get the following error:
/usr/bin/ld: cannot find -lmatplot
collect2: error: ld returned 1 exit status
Is g++ spuriously looking in my /usr/bin/ for files? Shouldn't it be looking in $(pwd)/libs?
From what I have researched, I am also supposed to have .so files, but everything under the matplot folder is .cpp or .h files. Does this mean I installed the library incorrectly into my /lib/ folder? I cloned from github and simply copied into my /lib/ folder. Without the -lmatplot flag I get the following error:
Any thoughts, resources, guidance or guidelines on how to troubleshoot these problems in the future? Thanks friends.
I followed the instructions on the repo, but piggybacking off of Compiler not finding jpeg and png libraries , I added the following flag to the cmake. This created object files for me.
-DBUILD_SHARED_LIBS=ON
I was able to build a .so file by following the build instructions included in the matplot++ .md file, but supplying an extra flag -DBUILD_SHARED_LIBS=ON
From there, under the build folder, I found a .so file somewhere in the folder tree, moved that to my /lib/ directory, and ran the following shell script:
#!/bin/bash
g++ -I /$(pwd)/libs -L /$(pwd)/libs -Wall -g -o music_vis_cpp ./music_vis_main.cpp -lstdc++fs -std=c++17 -pthread -lmatplot
And this finally built my program. However it doesn't run because shared object file doesn't exist or something.
Edit: More steps to make the program run;
Create a folder on your filesystem you want to put your .so files into and then...
export LD_LIBRARY_PATH=/home/harrison/Documents/computer/cpp_packages/shared_object_lib/
I need to run this export line every time I restart my computer, so I just add it to my build script.
So the .so file is in two places, one necessary at build time and the other necessary at run time. My binaries can be run anywhere on my computer with this method.

Link libraries to linux biinary file in c++

I'm compiling a c++ program using g++ and i am using two libraries called libsdl2-dev and libsdl2-image-dev
I installed both these libraries in my ubuntu machine with the commands
apt install libsdl2-dev libsdl2-image-dev and when I compile the program everything works fine. Then I copied these libraries from /usr/lib/x86_64-linux-gnu/ to my working dir with the binary file to be able to give this folder to someone else.
The problem comes when the user that hasn't installed these libraries tries to open my program by writing ./main (the binary file). Since he hasn't installed these libraries he would get an error like "can't open shared object: no such file or directory".
This happens because the binary file looks for these libraries in /usr/lib etc...
What i need
I need that my binary file looks for these libraries in the same folder,and not in /usr/lib/x86 etc.., from what I read I have to do something like rpath
The IDE used is Sublime Text and the syntax used to compile all my files is this:
g++ -c src/*.cpp -std=c++14 -m64 -g -Wall -I include && g++ *.o -o bin/debug/main -lSDL2main -lSDL2 -lSDL2_image && ./bin/debug/main`
Structure of folders
I got the project dir with and inside that i got 4 more directories, each one called: bin (with the debug subdirectory, where we got the final compile), include (with hpp files), res (with all textures), and src with all cpp files to compile, the other files are project files and .o files
I'm using Ubuntu 20.04-2 LTS and the same is for the other user's PC
Thanks in advance for any help!
That's because the dynamic linker loading runtime dependencies looks for them in some specified locations, which are "by default" your system library directories (where those libraries got installed by apt).
The other user should ideally install those libraries too (which could be done "automatically" if you build a .deb package with proper dependencies)
Otherwise you would have to change the runpath of your program by adding -Wl,-rpath='$ORIGIN', which makes the dynamic linker look for dependencies just where the binary is located.
$ORIGIN here is a special variable meaning "this executable" which is what you wanted to achieve.
see rpath
and A description of RPATH $ORIGIN
I found a way to resolve!
I used the program patchelf to add an rpath to my directory (linked to the binary file) now everything works
use ldd ./bin/debug/main to check the library
export LD_LIBRARY_PATH =$LD_LIBRARY_PATH:"your library path"
run the program,if this is not work. use patchelf to change the rpath to you r library

Executing cross-compiled C++ program using Boost on Raspberry Pi

I have built a GCC cross toolchain for the RPi and can cross-compile C++ source and successfully run it after copying the executable to the RPi.
Next I built the Boost libraries targeting ARM, using the cross toolchain. I can successfully build and link C++ source to those Boost libraries using the cross toolchain on my PC.
I then copied the program, dynamically linked to Boost, to the RPi and copied all built libraries into /usr/local/lib on the Pi. However, executing fails:
$ ./my_program
./my_program: error while loading shared libraries: libboost_system.so.1.60.0: cannot open shared object file: No such file or directory
Again, this library, libboost_system.so.1.60.0, exists in /usr/local/lib.
I also tried
export LD_LIBRARY_PATH='/usr/local/lib'
but that doesn't change anything. What am I doing wrong?
EDIT:
I build all source files like this (rpi-g++ is a symlink to my cross-compiler):
rpi-g++ -c -std=c++1y -Wall -Wextra -pedantic -O2 -I /path/to/cross/boost/include *.cpp
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -lboost_system -pthread
EDIT 2:
When linked with
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -rdynamic -lboost_system -pthread
the problem remains the same. I have checked and verified everything suggested by Technaton as well. Strangely, ldd insists that the created executable is "not a dynamic executable" (checked that on my PC and on the RPi), which doesn't make sense to me.
There are several things you can check. I've posted a complete check list here, but judging from your linker command line, number 5 is probably the culprit.
Check that your library and your program are correctly build for the target architecture. You can verify that by using file ./myprog and file libboost_system.so.1.60.0.
Make sure that you have copied the actual shared object, and not a link to it.
Ensure that the shared object file's permissions are sane (0755).
Run ldconfig -v and check that your shared object file is picked up. Normally, /usr/local/lib is in the standard library search path, and LD_LIBRARY_PATH is not required.
Make sure that your program is actually dynamically linked by running ldd ./myprog. Judging from your linker command line, that is the problem: You're missing -rdynamic.
Check the paths returned from ldd: If you have linked with rpath, the library search path might be screwed up. Try again without -rpath.

libxml/parser.h: in c++ ubuntu

Even though I have installed libxml++2.6-2 libxml++2.6-doc etc in my ubuntu 12.04 version again I am getting the below error
fatal error: libxml/parser.h: No such file or directory
I am using make for building the project
Kindly suggest any other libxml libraries which I need to install
libxml/parser.h is a part o libxml library, not libxml++
For any given library, you need development packages (the ones with names ending in -dev) in order to build applications using that library.
You need to pass additional flags to your compiler: xml2-config --cflags and to linker xml2-config --libs.
I don't have access to an Ubuntu system now, but: Maybe you need to install the libxml developer package? Maybe you only have the library but not the include file(s)?
Check in /usr/include, /usr/local/include, ... for the directory libxml and the file parser.h.
If you find the file, you may need to adapt your makefile so that the parent-directory is in the list of include paths, e.g.:
INC = -I/usr/local/include
g++ $(INC) ...
If you did not find the file: Check the available libxml packages for a developer package and install that.
Before Posting the answer THANKS to the people who have answered, but those answers were not worked for me
I have just copied libxml folder from the directory usr/lib/libxml2 and pasted in usr/lib directory and compiled my code it is not giving any error. It is working fine now.
Please read #el.pescado answer before reading this. I wanted to comment on that answer but felt the need to format my code better.
gcc -c <files to compile> `xml2-config --cflags` -o <object files>
gcc <object files> -L<libxml2 lib location> `xml2-config --libs` -o <binary file>
Assuming we have a file names xmltest.c that have code that included libxml2 header like #include <libxml/parser.h>, standard location of libxml2 shared library i.e. /usr/lib64/libxml2, the above code will evaluate like this:
gcc -c xmltest.c -I/usr/include/libxml2 -o xmltest.o
gcc xmltest.o -L/usr/lib64/libxml2 -lxml2 -lz -lm -o xmltest
A better idea is to put together a Makefile that does this automatically.

ldconfig is not seeing custom library

We created a custom shared library from some C++ code using
g++ -c -fPIC customTest.cpp
g++ -shared -o libcustomTest.so customTest.o
And we put it in the project directory and in our makefile we have the default target being
main: main.o
nvcc $^ -o main -lcustomTest -L.
And this works just fine.
The problem is, we'd like to move our library to /usr/lib/ or any arbitrary folder and still have the program locate it and use it but this hasn't been happening as we want it to.
We have a folder in our root that we created called libTest and in that folder we put our library customTest.so.0.1. Then we edited ld.so.conf in /etc/ to had /libTest in it.
Then we went to the directory of our program files and ran
ldconfig -v
which looked like this but larger
libpanel.so.5 -> libpanel.so.5.9
libt1.so.5 -> libt1.so.5.1.2
libbluetooth.so.3 -> libbluetooth.so.3.11.4
libgck-1.so.0 -> libgck-1.so.0.0.0
libdca.so.0 -> libdca.so.0.0.0
a lot of links are created and what not, but libcustomTest.so is not one of them. Not surprisingly, when we run make the custom library can't be located.
Can anyone point us in the right direction with what we are doing wrong? By the way we are on Ubuntu 11.10
g++ -shared -o libcustomTest.so customTest.o
This will create a shared library with SONAME not set.
We have a folder in our root that we created called libTest and in that folder we put our library customTest.so.0.1
Don't do that. Just copy libcustomTest.so into /libTest, and be done with it.
a lot of links are created and what not, but libcustomTest.so is not one of them.
That's expected result. ldconfig creates symlinks from SONAME to actual implementation binary. Since you didn't set SONAME, no symlink for you.
Unless you understand what SONAME is for, don't bother setting it (via -Wl,--soname=... flag) either. On Linux, SONAME and external library versioning is usually the wrong answer, as symbol versioning provides much better approach anyway.