Linking mosquitto library to hello.c program on Linux - 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

Related

Compile from .o Files to .dll File in Linux

Im trying to compile/link .o file(s) into a .dll file under Ubuntu...
i get it nearly to work but i have a problem with static linking these .o file(s) ...
Here is what ive done:
First i installed all dependencies ... then i build the following application:
https://github.com/Zeranoe/mingw-w64-build
On my Ubuntu.
After that i create the .o files from the application with normal "sudo make" command...
Now i had all .o file(s) ready ... then i modified the .o files with "dlltool" so now i have the opportunity to link them to a .dll file with "mingw" ... it works only in "shared mode" ... not in "static mode" ...
this is the working command:
sudo /home/robert/Downloads/mingw-32/x86_64/i686/bin/i686-w64-mingw32-g++ -shared -lmsvcrt -Wl,-subsystem,windows *.o -o phpcppdll.dll
and this is not working:
sudo /home/robert/Downloads/mingw-32/x86_64/i686/bin/i686-w64-mingw32-g++ -static -lmsvcrt -Wl,-subsystem,windows *.o -o phpcppdll.dll
and then i get the following error - with this command:
/home/robert/Downloads/mingw-32/x86_64/i686/bin/../lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/bin/ld: /home/robert/Downloads/mingw-32/x86_64/i686/bin/../lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o):crt0_c.c:(.text+0x3c): undefined reference to `WinMain#16'
collect2: error: ld returned 1 exit status
but i dont get further maybe you have an idea ...
Okay - i got it to work with the -nostartfiles flag ... but it dont make sense because all .dlls are not static ... but shared ...

Error while linking a custom dynamic library Rust

In a directory I have a C file and its header
/home/test/c_pro
f.c
f.h
libf.so
I have compiled the f.c into a dll called libf.so using the following command
gcc -c -fPIC f.c -o f.o
gcc f.o -shared -o f.so
I want to use this in my Rust project.
So in Rust project I have a build.rs
println!("cargo:rustc-link-search=/home/test/c_pro");
println!("cargo:rustc-link-lib=dylib=f")
When I run a cargo build the build fails with the following errors
/home/test/c_pro/f.so: undefined reference to `EC_KEY_new_by_curve_name'
collect2: error: ld returned 1 exit status
In my f.c I do some imports from openssl
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
and use symbols from these libraries.
Any ideas as to why the build fails? I am following the official doc and am relying on 2 build parameters
cargo:rustc-link-search so that cargo can know that he has to do a look up in this directory as well.
cargo:rustc-link-lib=dylib to tell what dynamic library to link to.
What am I missing here folks?
Thanks in advance.
EDIT+UPDATE:
I did as pointed out by #Uli Schlachter and it compiles but I get a runtime error stating that libf.so is not found.
ldd ./target/debug/test_f
libf.so => not found.
Any ideas?
Compile your shared object with
gcc -c -fPIC f.c -o f.o
gcc f.o -shared -o f.so -lssl

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.

Build a program with GLFW3 on Linux

I know this question has been asked many times before but I have been trying to get this working for days and none of the current answers solve my problem. I'd appreciate not being linked to this post: How to build & install GLFW 3 and use it in a Linux project Most of the answers I have seen redirect there but I have gone through it thoroughly and am still having problems.
I am running Linux Mint 17.1.
I have downloaded and built GLFW 3.1.1:
*Downloaded source; extracted; terminal to extract directory*
cmake .
make install
I have also downloaded the example program at http://www.glfw.org/docs/3.0/quick.html#quick_example
I am using the following build commands:
g++ -std=c++11 -c HelloGLFW.cpp
g++ HelloGLFW.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi
The program compiles fine but when I try to link it I get these errors:
//usr/local/lib/libglfw3.a(x11_init.c.o): In function `initExtensions':
x11_init.c:(.text+0x1aeb): undefined reference to `XineramaQueryExtension'
x11_init.c:(.text+0x1b05): undefined reference to `XineramaIsActive'
//usr/local/lib/libglfw3.a(x11_init.c.o): In function `_glfwCreateCursor':
x11_init.c:(.text+0x21f9): undefined reference to `XcursorImageCreate'
x11_init.c:(.text+0x22d0): undefined reference to `XcursorImageLoadCursor'
x11_init.c:(.text+0x22e0): undefined reference to `XcursorImageDestroy'
//usr/local/lib/libglfw3.a(x11_monitor.c.o): In function `_glfwPlatformGetMonitors':
x11_monitor.c:(.text+0x6e9): undefined reference to `XineramaQueryScreens'
collect2: error: ld returned 1 exit status
I have also gone through the instructions on the GLFW website but they seem to be quite lacking for Linux. I have gotten it working on Linux before but that was a year ago and I can't replicate it.
Can someone please let me know all the steps required to build a program with GLFW3 on Linux (including all dependencies required)?
When glfw3 was installed using cmake a file glfw3.pc was created along with it. This is a pkg-config file and lists what libraries are required for linking.
For me this file was located in /usr/local/lib/pkgconfig
The command I used to successfully build the program with was:
g++ HelloGLFW.cpp -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread
The GLFW site does list details at http://www.glfw.org/docs/latest/build.html#build_link_pkgconfig but it's a bit unclear what to look for if you aren't that familiar with Linux systems.
Specificity the instructions list this command for compiling with the static glfw3 library:
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3`
and with the dynamic glfw3 library:
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`

undefined reference when cross-compiling for ARM with static OpenCV libraries

I'm trying to compile a simple test program using static OpenCV libraries that have been compiled using an ARM compiler. But when I try to compile it with the command
$arm-linux-gnueabihf-g++ `pkg-config --static opencv` -I/usr/local/include -L<path to static libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2
This gives
/tmp/ccxNeUbK.o: In function main':
ARMtest2.cpp:(.text+0x8a): undefined reference tocv::Mat::ones(int, int, int)'
/tmp/ccxNeUbK.o: In function cv::Mat::~Mat()':
ARMtest2.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x20): undefined reference tocv::fastFree(void*)'
/tmp/ccxNeUbK.o: In function cv::Mat::release()':
ARMtest2.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x30): undefined reference tocv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
The code itself is just some simple test code that prints a Mat type variable.
I compiled the static OpenCV library with cmake-gui. I selected UNIX Makefile and then selected 'specify options for cross-compiling' where I gave the path to the ARM (arm-linux-gnueabihf) gcc and g++ compiler. Then I unticked BUILD_SHARED_LIB so it compiled static libraries. It seemed to compile fine without errors. After that I did make & sudo make install.
I also tried it with shared libraries and that worked fine on the ARM board (once I copied the libraries to the board and exported the library path).
The static .a files landed nicely in the build folder. Apparently it can also find it when I -L link to it. I have tried reversing the order of the libraries, but to no avail.
So I'm a bit at a loss what is going wrong.
I solved it. Using the normal --static pkg-config command to compile with OpenCV libraries;
`pkg-config --libs --static opencv`
Of course I installed the static libraries also to the folder /usr/local/lib where libraries get installed first. But still i don't know what I missed in the command line I tried to use. I had a look in the config file /usr/local/lib/pkgconfig/opencv.pc
Here is whats in it:
# Package Information for pkg-config
prefix=/usr/local
exec_prefix=${prefix}
libdir=
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.4.9
Libs: ${exec_prefix}/lib/libopencv_calib3d.so ${exec_prefix}/lib/libopencv_contrib.so ${exec_prefix}/lib/libopencv_core.so ${exec_prefix}/lib/libopencv_features2d.so ${exec_prefix}/lib/libopencv_flann.so ${exec_prefix}/lib/libopencv_gpu.so ${exec_prefix}/lib/libopencv_highgui.so ${exec_prefix}/lib/libopencv_imgproc.so ${exec_prefix}/lib/libopencv_legacy.so ${exec_prefix}/lib/libopencv_ml.so ${exec_prefix}/lib/libopencv_nonfree.so ${exec_prefix}/lib/libopencv_objdetect.so ${exec_prefix}/lib/libopencv_ocl.so ${exec_prefix}/lib/libopencv_photo.so ${exec_prefix}/lib/libopencv_stitching.so ${exec_prefix}/lib/libopencv_superres.so ${exec_prefix}/lib/libopencv_ts.a ${exec_prefix}/lib/libopencv_video.so ${exec_prefix}/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl
Cflags: -I${includedir_old} -I${includedir_new}
I believe this is what is being called with the pkg-config <--something_or_other> opencv line.
And saw some other things that probably get linked when compiling -lrt -lpthread -lm -ldl Not really sure though as I tried it ina normal command line and I apparently still missed somethings.
But it worked, so didn't really bother too much with it much further :)
In your command:
*$arm-linux-gnueabihf-g++ `pkg-config --static opencv` -I/usr/local/include -L<path to static libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2*
The cflags was missing.
Try with:
$arm-linux-gnueabihf-g++ `pkg-config --cflags --static opencv` -I/usr/local/include -L<path to static cross-compiled libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2
Assuming here that your cross-compiled headers are saved in /usr/local/include (as you specified).

Resources