CodeBlocks cannot find shared libraries even when search paths are setup - c++

I have a very basic C++ project in code blocks that makes use of glfw.so and two other libraries that are compiled to .so files from another project, libHorde3D.so and libHorde3DUtils.so. The latter are placed in the project root folder, while glfw is somewhere in my /usr/lib (I think).
I have added the project folder to the linker and compiler search paths in code blocks. I have added the libHorde3D.so and libHorde3DUtils.so as well as glfw.so to the Link Libraries in the Linker Settings tab. I thought that this would be enough based on the previous similar questions here on stackoverflow.
However when I press build:
ld cannot find -lHorde3D.so
ld cannot find -lHorde3DUtils.so
ld cannot find -lglfw.so
My system is Arch Linux 64 and I am using GCC.
I also tried bopying libHorde3D.so and libHorde3DUtils.so in /usr/lib and /usr/lib64 with no success.
P.S. All search paths are copied across the Debug and Release target.

Say, if the library name is libmylibrary.so, then linker option to link against that library would look like -lmylibrary. Note that lib prefix and .so suffix are not there — they are added automatically by the linker. In your case it seems like you specified the wrong name. Try removing .so from it, that should solve the problem.
Here is a simple demonstration of how to trigger the failure by making a similar mistake:
$ echo 'int main() { return 0; }' > test.c
$ gcc -o test ./test.c -lc
$ gcc -o test ./test.c -lc.so
/usr/bin/ld: cannot find -lc.so
collect2: ld returned 1 exit status
$
The first command succeeds and the second one (with incorrect library name) fails.

You must not pass ".so". The linker options are
-lHorde3D -lHorde3DUtils -lglfw
This way the linker will search for "libHorde3D.so" etc. in the library path(s).

Related

Eclipse can't find linked libraries

I am working with the windows.h functions and everything works fine so far.
But when I try to use functions which require me to link external libraries something goes wrong.
In this case I am trying to use CreateFont(). I already know that I must link libwinmm.a and libgdi32.a and I've done that:
See this screenshot
But when I try to build the project i get following error messages:
g++ "-LD:\\Programme\\Eclipse\\lib" -o GameTest.exe "src\\choosemealmain.o" "src\\mealchooser.o" "-lD:\\Programme\\Eclipse\\lib\\libwinmm.a" "-lD:\\Programme\\Eclipse\\lib\\libgdi32.a"
d:/programme/eclipse/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lD:\Programme\Eclipse\lib\libwinmm.a
d:/programme/eclipse/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lD:\Programme\Eclipse\lib\libgdi32.a
collect2.exe: error: ld returned 1 exit status
I made sure to doublecheck whether the mentioned libraries are actually to be found in the mentioned path and they are.
I would be glad for any kind of help!
You are wrongly using quotes with -l flag. The -l flag also automatically adds the lib prefix and the .a extension. Your command line should be:
g++ -LD:\Programme\Eclipse\lib -o GameTest.exe "src\choosemealmain.o" "src\mealchooser.o" -lwinmm -lgdi32

How gnu linker choose which dynamic library to link

I was using gpgpu-sim, a GPU simulator, to conduct researches. There are several .so files in my own folder:
And there are some alternatives .so in Nvidia's cudart lib folder:
And there are some .o files and need to be linked with libcudart.so, when I type in the command:
g++ -L "Path/to/MyFolder" -l cudart *.o
I hope the generated a.out would link to libcudart.so, but it just linked to a strange so file:
libcudart_gpgpu-sim_git-commit-6443f21d433f1b642003867e56fe1f54efae55e3_modified_0.so => not found
And when I typed this code:
g++ -L "Path/to/NvidiaFolder" -l cudart *.o
The program can sussessfully find libcudart.so.9 in my LD_LIBRARY_PATH folder,but it shows that the version can't match!:
./a.out: /path/to/myFolder/libcudart.so.9.0: version `libcudart.so.9.0'not found (required by ./a.out)
Can anybody tell me how ld works and how to solve those problems?
I finally find out the reason.
if you use this code to link objects to generate a shared library:
g++ -shared -Wl,-soname,libNAME_A.so -o libNAME_B.so
then, if some on is trying to link NAME_B.so using:
g++ <INPUT> -lNAME_B -o <OUTPUT>
the output will finally look for libNAME_A.so.
refer to g++ man page:
-Wl,option
Pass option as an option to the linker. If option contains commas,
it is split into multiple options at the commas. You can use this
syntax to pass an argument to the option. For example,
-Wl,-Map,output.map passes -Map output.map to the linker. When
using the GNU linker, you can also get the same effect with
-Wl,-Map=output.map.
and for ld man page:
-soname=name
When creating an ELF shared object, set the internal DT_SONAME
field to the specified name. When an executable is linked with a
shared object which has a DT_SONAME field, then when the executable
is run the dynamic linker will attempt to load the shared object
specified by the DT_SONAME field rather than the using the file
name given to the linker.
There is nothing to do with CUDA here, it's just a linking and runtime environment setup problem.
The ld linker searches for objects and library archives following the order specified by -L option parameters, and only after into default system directories. The linker will link the object code that first match this search.
At runtime, if you linked against dynamic libraries (.so files) you will need to properly define the LD_LIBRARY_PATH environment variable with a list of paths to look for dynamic libraries, separated by colon (:).
So if you link to your objects using libraries from your local path (assuming you are looking for libcudart.so):
g++ -o myprogram *.o -L "/Path/to/myFolder" -lcudart
you need to set LD_LIBRARY_PATH as follows before running your program:
export LD_LIBRARY_PATH="/Path/to/myFolder:$LD_LIBRARY_PATH"
./myprogram
I hope this help and clarify your understanding. Frankly I don't understand the origin of your libcudart_gpgpu-sim_git-commit match

Id cannot find the .so library

I am attempting link an app with my compiler, however, ld is warning it cannot find specified libraries. This is the last one that I cannot handle.
I am calling the linker with:
/usr/bin/c++ -O3 -DNDEBUG XXX -o ijkmcube -lNrrdIO,-rpath,XXX:
Id warned that:
/usr/bin/ld: cannot find -lNrrdIO
Since this library seems like not that popular, I cannot find direct apt install method to handle it.
Furthermore, I could only find out .a library instead of .so library for this particular case.
locate libNrrdIO.a
/home/XXX/Desktop/NrrdIO-1.11.0-src/libNrrdIO.a
/home/XXX/Desktop/src/ijkmcube/lib/libNrrdIO.a
How do I diagnose this problem further, and what could be wrong? Thanks in advance!

wsdlpull: linking error with g++

I'm new to programming c++ with g++ and have big problems to get wsdlpull-library to work. The version is 1.24.
I followed the installation steps from http://wsdlpull.sourceforge.net/.:
./configure --prefix=/home/jesse/Dropbox/Programmering/C++/test --disable-opt --enable-examples
make
make install
I then copied print.cpp file from the example to the "prefix"-directory. The next step would be "add the $(prefix)/include in your include path and add $(prefix)/libs and -lwsdl -lschema -lxmlpull to your LDFLAGS". The first problem is that there's no folder "libs" but "lib" and the include-folder has another folder inside named wsdlpull. Therefore I instead entered the following command:
g++ -I include/wsdlpull -L lib -lwsdl -lschema -lxmlpull -o print print.cpp
This resulted in the following error:
/usr/bin/ld: cannot find -lwsdl
/usr/bin/ld: cannot find -lschema
/usr/bin/ld: cannot find -lxmlpull
collect2: error: ld returned 1 exit status
I have no idea what this means, why does it look in /usr/bin/ld when I point to "lib"?
When you use -L lib, it means that, lib dir is available in pwd where you are doing make. Check whether you have said lib is really available or not.
To make things simple, you can give the absolute path of the lib folder.
i.e -L<path to lib>/lib. This would help the make to see the lib without any confusions.
Next, you might want to explicitly specify whether libwsdl is a static or shared library. Although this is optional.
Or, the best solution is to place the libraries in system libs location i.e /lib or /usr/lib or /use/local/lib and run ldconfig such that the linker/loader knows where the newly added libraries exists. In such case, you can simple issue -lwsdl without specifying the -L flag.
For more info, please refer ldconfig.

How to modify options being passed to ld , without recompiling gcc

I'm trying to compile shared library on solaris 2.7 using gcc 3.4.6 and
which is linking to a statically linked c .a and .o files.
Please note that it is using Sun ld from path "/usr/ccs/bin/ld"
At linking time i got a long list of symbols and following error
ld: fatal: relocations remain against allocatable but non-writable sections
collect2: ld returned 1 exit status
Then i tried to build it passing -z textoff option to ld. but i'm getting follwing error
ld: fatal: option -ztextoff and -ztext are incompatible
ld: fatal: Flags processing errors
Is there any other way where i don't need to recompile gcc and still modify the options getting passed to ld.
The errors are the result of linking position-dependent code into a shared library. Such code will result in the library not being shareable, and thus wasting RAM.
If you can rebuild all the objects you are trying to link into the shared library, the simplest (and most correct) solution is to rebuild all of them with -fPIC flag.
However, sometimes you really must link non-PIC object code which you can't rebuild into a shared library, and therefore you need to get rid of the -ztext option. To do that, add -mimpure-text option to your link line.
Run the ld executable from the command line (not via gcc) - you can then pass it whatever parameters you want. I don't think that will solve your underlying problems though - you might want to post a question about them.
Are you using make or some other build system to invoke the compiler?
If you change the options in the build system to specifically use the linker during the link phase rather than using the compiler.
Step 1: Find flags passed by gcc
Add the -v flag. It makes gcc verbose.
CXXFLAGS += -v
Step 2: Modify the link stage to explicitly use the tool that gcc was invoking.