Compiling binary using dynamic libraries - linux

I have 20 shared objects files, and I want to use one function from the let`s say "a.so"
but my problem is that a.so is linked to other libraries.
When i compile my main i get the following error:
/usr/bin/ld: warning: b.so, needed by /home/test/lib/a.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: c.so, needed by /home/test/lib/a.so, not found (try using -rpath or -rpath-link)
How can i compile my main that i would be able to use the function in a.so ?
I have tried to use this method: gcc -L. -WL, -rpath,. main.c -l{libraryName} -o main
but i get the following error:
gcc: error: unrecognized command line option ‘-WL,’; did you mean ‘-Wa,’?
gcc: error: unrecognized command line option ‘-rpath,.’

When i compile my main i get the following error:
There are two mistakes in above statement:
you get a warning, not an error, and
you get it when you link your program, not when you compile it.
How can i compile my main that i would be able to use the function in a.so ?
Like so:
gcc -L. -Wl,-rpath=. main.c -l{libraryName} -o main
P.S. In general, it's a bad practice to have -rpath as a relative path, because the program will not work if you invoke it from a different directory. A better solution is to use absolute -rpath instead:
gcc -L/home/test/lib -Wl,-rpath=/home/test/lib main.c -l{libraryName} -o main

Related

Linking mosquitto library to hello.c program on Linux

I am trying to compile the mosquitto library with my custom c program. So WHat I have done is wrote a hello.c file, git cloned the latest mosquitto library from the below repository:
https://github.com/eclipse/mosquitto.git
and compiled it with the make command as below:
make
I had to remove the doc target as it was asking for some dependancy library. I don't have admin rights on this machine, hence don't want to be blocked by any dependancy lib. After the compilation what I have is the below:
src/mosquitto
./lib/libmosquitto.so.1
The I copied the libmosquitto.so.1 shared lib into a local folder called ~/hello/:
~/hello$ cp ~/mosquitto/lib/libmosquitto.so.1 .
then wrote a hello.c inside ~/hello/ which is as below:
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
I can compile the hello.c and run it as below:
gcc -o hello hello.c
./hello
Hello World
But if I try to link the binary with the mosquitto library I get an error like the below:
gcc -o hello hello.c -lmosquitto
/usr/bin/ld: cannot find -lmosquitto
collect2: error: ld returned 1 exit status
The libmosquitto.so.1 lives in the same folder as the hello.c. I don't want to install the mosquitto library, rather would like to keep in a local folder and be able to link it. I have also tried the below with the hope that the -L. would point the linker to the present directory for the shared lib file but still get the same error:
gcc -o hello hello.c -L. -lmosquitto
/usr/bin/ld: cannot find -lmosquitto
collect2: error: ld returned 1 exit status
My ultimate objective is to cross compile the library for an arm target. So really need to understand how the linking of the shared library is failing so that I can use the same experience while cross compiling and link for the target. At the moment I am doing this on a x86 platform.
Can anyone please help?
/usr/bin/ld: cannot find -lmosquitto
The linker doesn't look for libmosquitto.so.1 -- it only looks for libmosquitto.a or libmosquitto.so.
Solution: ln -s libmosquitto.so.1 libmosquitto.so
./pub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
The problem here is that the runtime loader doesn't look in the current directory for libmosquitto.so.1 -- it only looks in system-configured directories.
You could fix this by adding export LD_LIBRARY_PATH=$HOME/mosquitto/lib, but this is suboptimal -- your binary will work or not depending on the environment.
A better solution is to change your link command like so:
gcc -o hello hello.c -L. -lmosquitto -Wl,-rpath=$HOME/mosquitto/lib

Question about compiling sources code with HDF5 and mpi

When I am trying to compile the source code by 'make', the first steps that creating the '.o' files are running fine, and all '.o' files could be compiled normally. However, when compiling the executable file:
mpifort -fopenmp -O3 -o MyEXE sth.o main.o -L/usr/local/share/fftw-3.3.8/lib -lfftw3_mpi -lfftw3 -lm -L/usr/local/share/mpich-3.2/lib -lmpi -lz -L/usr/local/share/hdf5-1.8.18/lib -lhdf5_fortran -lhdf5hl_fortran -lhdf5_hl -lhdf5 -fPIC
it gots the following error:
/usr/bin/ld: /usr/local/share/hdf5-1.8.18/lib/libhdf5.a(H5PL.o): undefined reference to symbol 'dlclose##GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
How could I solve this problem? Some pages suggest that it is due to the '-ldl- flag when calling c++ compiler, but I couldn't find a way to make it suitable for my cases.
The pages were right. Your HDF5 library libhdf5.a uses the function dlclose, which is defined in the library libdl. To use it, you need to simply add -ldl at the end of your mpifort command line.

Linker is unable to locate curl_global_init

I am compiling a C++ application on Ubuntu 18.04.
The linker is unable to pickup the required functions from the library or it is not locating the right library
I have libcurl.so located at /usr/local/lib
nm -D lists all the functions I need with T prefix. Yet when I compile as follows
g++ -std=c++17 -lcurl tz.o main.o
I get
/usr/bin/ld: tz.o: in function 'date::curl_global()':
tz.cpp:(.text+0x9aef): undefined reference to 'curl_global_init'
I tried installing openssl-dev. No joy. So I uninstalled it.
try
g++ -std=c++17 tz.o main.o -lcurl
instead... g++ is shit in some ways, like argument ordering. (all i did was to make -lcurl the last argument instead of argument #3)

g++ link an .a file and its dependencies into a static .so

I have a libSomelib.a that can be linked to an executable by the following command:
g++ -L. -lsomeLib -lpcrecpp -lpcre -lpthread main.cpp -o main
But how could I link a shared object from it, that contains all depentencies?
I want to achieve the following with my new someLib.so:
g++ -L. -lsomeLib main.cpp -o main
I have tried the following:
g++ -shared -L. -lsomeLib -lpcrecpp -lpcre -lpthread -o libSomelib_static.so
This gives me an .so file with no symbols.
PS: I'm completely beginer of compilers.
There are a few issues at play here:
Linkers only use object files from an archive that resolve unresolved symbols. This is why the order of archives in the command line is important. Correct order is object files, followed by static libraries, followed by shared libraries. E.g. g++ -o main -pthread main.cpp -L. -lsomeLib -lpcrecpp -lpcre.
When you build the shared library that archive does not resolve any symbols, hence the linker ignores it completely. See 1.
Object files for a shared library must be compiled as position independent code (-fPIC compiler flag). Archives are normally built without this flag.
Use -pthread flag both when compiling and linking multi-threaded applications, not -lpthread.

gcc:linker input file unused because linking not done

When I run a make file in Linux to compile C codes, I get the following error:
gcc -Wall -fPIC -DSOLARIS -DXP_UNIX -DMCC_HTTPD -D_REENTRANT -I/opt/profile/OraAlert_test/code/include -I/usr/netscape/server4/plugins/include -I../../pwutils -I../../database/src -I../../access/src -I/data/share/capscan/include -o getEnv.o -c ../src/
gcc: ../src/: linker input file unused because linking not done
I have tried searching for related questions in stackoverflow and tried the the solutions suggested. Still this could not be resolved.
Any suggestions?
You have a compilation command without a source file.
What is it supposed to compile?
The error is indeed misleading. It assumes you want to link with ../src/, but -c says no linkage is to be done.

Resources