ld does not find secondary shared objects using ld.so.conf.d at compile time in Manjaro-Linux - linker

I stumbled over a weird behavior of ld (compile time linking) in Manjaro-Linux.
Assuming I want to compile test.c which is dependent on libprimary.so and libprimary.so is dependent on libsecondary.so, which are installed in non standard paths.
I could compile like this (both are working):
gcc test.c -L/path/to/primaryLibDir -lprimary -L/path/to/secondaryLibDir -lsecondary -o test
or like this:
gcc test.c -L/path/to/primaryLibDir -lprimary -Wl,-rpath-link=/path/to/secondaryLibDir -o test
A look into ld manual under the -rpath-link option is telling that if -rpath-link is not used and the not directly dependent library is not given with -lsecondary, the file is (among other methods with higher prioriry tried before), also searched using the paths in /etc/ld.so.conf (priority 7).
I tried this in my Manjaro-Linux dsitribution and in the Ubuntu WSL.
And it works in all of them when writing the path directly into /etc/ld.so.conf.
If I write the path into a /etc/ld.so.conf.d/test.conf file (which is included via include /etc/ld.so.conf.d/*.conf in /etc/ld.so.conf) it works only in the Ubuntu WSL. In Manjaro Linux, it does not find the library anymore then.
Can anyone imagine, why this is not working? I think it must have something to do with the Manjaro setup.

Related

Compiling cmocka on windows

I'm trying to compile a simple unit test on my windows machine.
When I'm trying to compile my test I'm using the shared library flag.
gcc -c -L./bin/ -lcmocka .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o -o main
But the second line throws this error:
undefined reference to `_cmocka_run_group_tests'
However, if I'm compiling using directly the cmocka.c file which I downloaded from their git it works fine:
gcc -c .\lib\cmocka.c .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o .\cmocka.o
What am I doing wrong in the first compilation?
In addition, I would happy to understand the difference between the two compilations. Which one is the better practice?
Thank you
In order to compile your code, the compiler does not need to know where to look for the library. It's enough if the compiler "finds" the declarations of the functions which are usually in the header files provided by the library.
This step is done in the first line of your compilation procedure (maybe you need to specify the folder to the header files by adding -Ipath/to/headers/):
gcc -c .\Test.c .\src\some_module.c
The library itself is "combined" with your code during the linking step, which is done during your second compilation step. Here you need to specify the library (and its path via -Lpath/to/library, if the linker does not find the library on its own):
gcc .\Test.o .\some_module.o -o main -L./bin/ -lcmocka
You should definitely not use your second approach and compile the library by yourself.

How to use the hidapi library from Signal11?

I installed the hidapi library from Signall11 on my windows10 pc (using minGW). But now I'm having some trouble actually getting it to work with gcc. I have some main.c file in which I include the hidapi.h file. My gcc command looks like
gcc main.c
I'm not sure where I'm going wrong because whenever I try to run this command I get an undefined reference error to some function that is defined in the hidapi.h file.
A full compile command for a project using hidapi is like this:
gcc -o your_app your_app.c -lhidapi-hidraw
It's not enough to include #include "hidapi.h" in the C-code, which does let gcc compile. You also need -lhidapi-hidraw to link with the library. I.e. compiling is in fact a 2 step process.

ld: warning: directory not found for option: -LC_ID_DYLIB=/usr/lib

I'm using OSX command line gcc and attempting to build a dynamic library. when I do the build I get the following warning. How is it it is not finding this library given /usr/lib is well known? And /usr/lib does indeed exist on my machine
this is what I am using:
gcc -arch i386 cata/*.c -dynamiclib -o build/cata.dylib -LC_ID_DYLIB=/usr/lib
Thanks
the way i solved it was to make it so the string that got stuck in the library (on where to find the library at runtime) was relative to nowhere -- if that makes sense. so it would be forced to use the LD_LOAD_PATH.
I was using the other flags because someone suggested I use them.
so the gcc i ended up using is this:
# my tree is like this
# cata/*.c
# build/*.dylib
#
cd build
gcc -arch i386 ../cata/*.c -dynamiclib -o cata.dylib
Doing this compiles/makes a library in the same directory where it thinks it is 'used' (basically having no path). I am now free to put it somewhere else. When it is later linked at compile time by a different program and then examined using
otool -L
it appears with no path in front of the library name. This is apparently preferable as now when the system goes to try to find it it resorts to looking at the standard libraries and eventually finds it (because I install it to one of the standard locations).
In the original way, otool -L was showing it having a required path of
'build/cata.dylib'
This made it un-findable and which is why i was trying to use the apple documentation to get around the problem.
This doesn't really solve why LC_ID_DYLIB doesn't work. I looked into the Loader.h file (line 643) and it has room for an identifier(0xd), a path, and a structure, so I don't really understand why my path wasn't getting picked up. but its two different topics. Loader.h is runtime and the other is gcc AFAIK. I'm still learning apple.

cc linker gives no error, but the resulting library is not linked to libgstvideo-1.0

I'm using cmake to generate a gstreamer library. In the end cmake uses the following command for linking:
/usr/bin/cc -fPIC -shared -Wl,-soname,libmacq-gstmelpi.so -o libmacq-gstmelpi.so <OBJECT_FILES> -lmacq-melpi -lmacq-icar-tools -lmacq-gstmecimeta -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0 -lgstvideo-1.0
Note the -lgstvideo-1.0 flag at the end. The command runs fine, no error is produced, and the resulting library is created just fine. However when I use the library, I get undefined symbol error. So I use ldd to check; and amongst all the output of ldd; libgstvideo-1.0.so is not to be found.
This problem occurs on Ubuntu 14.04 on a armhf architecture. The problem does not occur on opensuse 13.1 (i586) nor on opensuse 13.1 (armv7hl), since in that case ldd libmacq-gstmelpi.so | grep gstvideo gives:
libgstvideo-1.0.so.0 => /usr/lib/libgstvideo-1.0.so.0 (0xb715f000)
EDIT :
I have another library, very similar where a very similar command works just fine; the resulting library is correctly linked to libgstvideo-1.0.so
/usr/bin/cc -fPIC -shared -Wl,-soname,libmacq-gstplugins.so -o libmacq-gstplugins.so <OBJECT_FILES> -lmacq-icar-tools -lmacq-gstmecimeta -lgstapp-1.0 -lgstbase-1.0 -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0 -lgstvideo-1.0
Some remarks on what I have checked and tried:
/usr/lib/arm-linux-gnueabihf/libgstvideo-1.0.so exists. (the other libraries in /usr/lib/arm-linux-gnueabihf/ are found without problem, libmacq-gstmelpi.so is linked to /usr/lib/arm-linux-gnueabihf/libgstreamer-1.0.so.0 without problem)
I tried changing the order, and putting the -lgstvideo-1.0 flag before all other -l flags; no succes.
replacing cc with c++ or gcc; the commands work, but output is the same
removing -lgstvideo-1.0 on a system where the build worked. The resulting library builds (links) without error; yet upon execution I have the same undefined symbol error as on Ubuntu. This proves that the missing symbol is in libgstvideo-1.0.so, and that I need it.
Are you actually using symbols from that particular library or do you just want to link to it to avoid linking it in the application that uses the library later on?
It could be a default compiler behavior that it skips linking of libraries when no symbol from these are actually used.
Try -Wl,--no-as-needed to your flags. In this case the library should get linked - not checking whether its symbols are actually used or not.
EDIT:
After chatting it turned out that the actual desired symbols are in gstbase-1.0 and not gstvideo-1.0. Since gstvideo-1.0 pulls in gstbase-1.0 as a dependency this worked but would cause problem as the linker may remove this dependency since no symbols from this particular library are being used. Linking directly to gstbase-1.0 seemed to solve all issues.

Gcc on OS X: Undefined symbols for architecture x86_64

I am writing an application that has multiple subdirectories. I have created a Makefile structure such that the subdirectories compile the file and do "ar rvs" and "ranlib libxxx.a" to create archives into the parent directory for linking.
However the "ld" command is running into the following problem.
ld: warning: ignoring file ./libxxx.a, file was built for archive which is not
the architecture being linked (x86_64):
./libxxx.a Undefined symbols for architecture x86_64:
I am using gcc on Mac OS X 10.10.1
I read many posts on this. I tried "gcc -arch i386", then I encounter the same error for i386
Undefined symbols for architecture i386:
I installed gcc-4.9.2 and tried using it instead of the default gcc, with no luck. I tried using x86_64-apple-darwin14.0.0-g++-4.9.2 and that did not help either.
The errors you are seeing mean that you have a mixture of i386 and x86_64 code in the build, and you need to be consistent. Unless there's a compelling reason to do otherwise (I'd be curious to know what it is), you should be compiling everything for 64-bit only. Using gcc on Mac, that is normally the default, but you can force it by adding a -m64 flag to the compilations. One way of doing that is to set CC="gcc -m64" on the make command line; there are other better ways too, but the details depend on your makefile contents.
To resolve: first, remove all the libraries and object code you've built in your project area (maybe make clean will do it — if you wrote a clean target). Then, fettle the value of CC or its flags (CFLAGS ultimately, but how CFLAGS is built depends on the makefile) so that 64-bit compilation is enforced. Then make sure you're using that in all compilations. If you don't see the -m64, you've got a problem.
If you must use 32-bit, substitute -m32 for -m64.
The discussion above assumes you are using gcc to run the ld command. If you are not, then you're on your own until you use gcc to run the ld command. In my view, you've got better things to do with your life than work out how to run the ld command correctly; I certainly have.

Resources