Linux - find the path of g++ lib - c++

I installed these two libraries: glut and curl.
sudo apt-get install libcurl4-gnutls-dev
sudo apt-get install freeglut3-dev
when I have to compile a program I use:
g++ -o executable file11.cpp file2.cpp -lglut -lcurl
and it works!
How can I know where the linker search for "-lglut" or "-lcurl"?
"-lsomething" correspond to a path, How can I find out?

It checks /lib, /usr/lib, and any paths passed to -L.

The linker will look in directories specified by the -L option and in standard system directories, which are usually /lib and /usr/lib. Although you're not using any -L options GCC will usually pass some to the linker so it can find GCC's own libraries (e.g. the C++ standard library) unless you use -nostdlib. GCC will also add -L options for the contents of the LIBRARY_PATH environment variable.
To see the options GCC passes to the linker you can compile with -v (for verbose) and to see which libraries the linker uses you can pass -Wl,--trace to GCC, which causes it to pass --trace to the linker, which makes it output something like:
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o
/tmp/ccJHrbSx.o
-lglut (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libglut.so)
-lcurl (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libcurl.so)
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/libgcc_s.so)
/lib64/libc.so.6
(/usr/lib64/libc_nonshared.a)elf-init.oS
/lib64/ld-linux-x86-64.so.2
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/libgcc_s.so)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
This shows the libraries that were found for the -lglut and lcurl libs on my system. The libs are found in that path because on my system GCC passed -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 to the linker (shown by compiling with -v)
You can canonicalize those paths using readlink
$ readlink -f /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/
/usr/lib64/

http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
It just turns the string into a filename, and checks normal locations for it, it seems.

Try
ldd /path/to/your/executable

Related

Program compiles, but cannot run because of missing library that exists

I have an OpenGL program. I have all the include directories, and everything.
Directory Structure:
Main.cpp
Lib/
GL/
GLEW/
glm/
I compile the program by running:
g++ main.cpp -lGL -lm -lX11 -lpthread -lXi -lXrandr -ldl -I. -lglfw -Llib/ -o main -lGLEW
The error is on -lGLEW. The program compiles with no errors, but when I run ./main, it gives me this:
Error while loading shared libraries: libGLEW.so.2.2: No such file or directory.
This is confusing, as in my lib/ directory, libGLEW.so.2.2 is present, so is libGLEW.so and libGLEW.a.
Can someone please help me?
When running a dynamic linked executable, the linker must be able to find all the libraries it needs. It always searches
a list of fixed default paths like /lib and /usr/lib
additional paths defined by the environment variable LD_LIBRARY_PATH
any non-standard paths hard-coded in the binary by the -Wl,-rpath g++ option.
These are your options for making this non-standard library known to the runtime linker.
So either use export LD_LIBRARY_PATH=<somepath>/lib when running or use -Wl,-rpath=<somepath>/lib (with comma and without spaces) when building.

Cross-compilation and libraries

During a cross-compilation I got this linker error:
/home/tech/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lfontconfig
This is the g++ command line:
/home/tech/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++ -Wl,-rpath-link,/mnt/rasp-pi-rootfs/opt/vc/lib -Wl,-rpath-link,/mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf -Wl,-rpath-link,/mnt/rasp-pi-rootfs/lib/arm-linux-gnueabihf -mfloat-abi=hard --sysroot=/mnt/rasp-pi-rootfs -Wl,-O1 -o fontconfig fontconfig.o --sysroot=/mnt/rasp-pi-rootfs -lpthread -L/mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf/ -lfreetype -lfontconfig
And
ls /mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf/libfontconfig*
/mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf/libfontconfig.so.1
/mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf/libfontconfig.so.1.8.0
I don't understand "why" the linker cannot find that library.
What do you suggest to do in such a case to investigate further?
Linker requires import library with .a extension of the library for linker operations because it contains the signatures of classes and functions needed by the linker for linking while .so libraries are shared objects used at runtime.
You need to find the directory where you have libfontconfig.a (e.g.: through the command locate libfontconfig.a or 'find / -name libfontconfig.a') and then add it to the command line with -L/path/of/directory.

#executable_path not working

I have installed SDL2. I can link my program with
clang++ -lSDL2 -lv8 main.o test.o -o nano8
However, for distributing reasons, I'd like to give SDL2 away with the binary, and hence i've copied libSDL2-2.0.0.dylib under /myapp/lib/libSDL2-2.0.0.dylib
As for the documentation, #executable_path should allow me to link to that dylib instead of the one in /usr/local/lib, but if I run
clang++ #executable_path/lib/libSDL2-2.0.0.dylib -lv8 main.o test.o -o nano8
I get the error
clang: error: no such file or directory: '#executable_path/lib/libSDL2-2.0.0.dylib'
How to set the search path for a dylib?
This is a pain to get right.
I assume that /myapp can be anywhere in the filesystem, and want to load the library from #executable_path/../lib/libSDL2.dylib?
If so you have to use the Run Path and copy and modify the library during linking (this needs to be done every build):
cp /usr/local/lib/libSDL2.dylib build_dir/lib.
Change the install name of the .dylib using install_name_tool:
install_name_tool -change /usr/local/lib/libSDL2.dylib #rpath/libSDL2.dylib build_dir/lib/libSDL2.dylib
Link against build_dir/lib/libSDL2.dylib and set the rpath during linking:
cd build_dir/bin
clang++ obj_dir/main.o obj_dir/test.o -o nano8 -L ../lib -lv8 -lSDL2 -Xlinker -rpath -Xlinker "#executable_path/../lib"
I have not tested this and there is likely to be errors. Use otool -L to examine the library references in both the binary and the libraries in order to home-in on this issue.
A cleaner way:
Install your binaries into /usr/local/bin and provide any .dylibs to be installed into /usr/local/lib. This is better as /usr/local is the place for user-binaries and you don't need the faff above.

Usage of -l for arm-none-eabi-gcc

I am trying to use a arm-none-eabi-gcc to compile some mbed code offline and ran into trouble when I tried to move the mbed folder outside the directory. The command that comes out of the make file is
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -T../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/MKL25Z4.ld -L./mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM -o Example.elf main.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/retarget.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/board.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/cmsis_nvic.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/mbed_overrides.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/system_MKL25Z4.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/startup_MKL25Z4.o -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
The folder named mbed contains all the headers and .o files required for basic mbed programming. However, when I try to move the mbed folder to a different folder and address it relatively, I get an error saying:
cannot find -l../libraries/mbed
Is it wrong to give relative paths to the -l option? If yes, how do I work around this problem?
Use the -L option to gcc to indicate where libraries are to be looked for. See the manual:
The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
The directories searched include several standard system directories plus any that you specify with -L.
I was able to get this working. The problem was that -L was not taking in relative paths. The new command looks something like this:
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -T/<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/MKL25Z4.ld -o Example.elf main.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/retarget.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/board.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/cmsis_nvic.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/mbed_overrides.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/system_MKL25Z4.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/startup_MKL25Z4.o -L/<path-to-folder>/workspace/mbed/libraries/mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM -L/<path-to-folder>/workspace/mbed/libraries/mbed -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
I'm not exactly sure why the relative path didn't work. One of my friends suggested that it may be because '..' is a symbolic link in some sense.

How to create a dynamic library for c++ on linux?

I would like to create a dynamic library for c++ program on linux.
In c++ program/system I`m using libconfig++ library, libpqxx library, some boost and c++11.
My steps:
1)
g++ -Wall -I/usr/local/include/ -std=c++0x -lconfig++ -Wall -lpqxx -lpq -fPIC -c ../SourceFiles/DBHandler.cpp ../SourceFiles/ParamServer.cpp ../SourceFiles/Functions.cpp
2)
g++ -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
3)
ln -sf libctest.so.1.0 libctest.so.1
4)
ln -sf libctest.so.1.0 libctest.so
5) compile
g++ -Wall -I/path/to/include-files -L/path/to/libraries program.cpp -I/usr/local/include/ -std=c++0x -lconfig++ -lpqxx -lpq -lctest -o prog
After execute above command :
/usr/bin/ld: cannot find -lctest
collect2: ld returned 1 exit status
What am I doing wrong?
Here is the reference:
enter link description here
In step 5, you forgot -L. to look for libraries in the current directory.
By default, only a [long] list of system directories is used when searching for libraries.
You will also need to add . to the LD_LIBRARY_PATH environment variable before executing your program, so that the current directory is searched at runtime, too. Running ldconfig will avoid this, but if you are only testing your library and do not want to persistently affect your system, I would stick to the LD_LIBRARY_PATH approach.
An alternative is to "install" your library into one of those directories, such as /usr/local/lib (or your equivalent). You should use ldconfig after doing this, so that the dynamic library cache and all your symlinks are set up for you. This is the canonical approach but may not be suitable during iterative development of said library.
You need to ldconfig update the dynamic library cache -- it will also create the symbolic links for you.
See eg Section 3.5 of this Linux Documentation Project HOWTO