Link PCL libraries while compiling C++ programs in Linux - c++

I am new to the Point Cloud Library. There is a thing that has been bugging me for some time.
So, on my system, whenever I have to compile a C++ program, which requires OpenCV libraries to be linked, I use the following terminal command:
g++ -std=c++11 fileName.cpp -o executableFile `pkg-config --cflags --libs opencv`
Now, things have turned to a point where I have to use PCL. But, everywhere (including the PCL's official website) people link PCL libraries using a CMake file, and I am not familiar with CMake.
Is there a way to include the PCL libraries without writing a CMake file and just including some more flags/parameters to the terminal command?
I am using Ubuntu 18.04.

I experimented for a while, and here is how I figured this out.
man pkg-config tells you the folders where pkg-config looks for .pc files. So, I checked those folders for the exact .pc file names that I want pkg-config to link with my .cpp file. I found the required file (pcl_io-1.11.pc) at \usr\local\lib\pkgconfig
Next, I modified my terminal command to the following (please consider two back-quotes as a single back-quote below)
g++ -std=c++14 pcd_write.cpp -o pcd_write ``pkg-config --cflags --libs pcl_io-1.11`` -lboost_system
Note: Not including the -lboost_system would result in another error message. I found this helpful.
This compiled successfully. But, on running the executable, I would get this error message:
./pcd_write:error while loading shared libraries:libpcl_io.so.1.11:cannot open shared object file:No such file or directory
The solution to this problem was found here
sudo /sbin/ldconfig -v
Then, running the executable gave the expected results.

Related

Error loading SDL2 shared libraries while executing program on another pc

I'm trying to compile a program i made using SDL2 to work on others computers (or testing VM in this case).
I've been compiling it with what i think are the correct flags, e.g. g++ main.cpp -o main -lSDL2, however when i try executing it on another Ubuntu installation i get this error.
error while loading shared libraries: libSDL2-2.0.so.0: cannot open shared object file: No such file or directory
From my understanding it's not a problem in my compiling but with how i expect it to work on another Linux installation; I've cross-compiled (using mingw32) and tested it (using a freshly installed VM) on Windows adding the correct dlls with the exe (seems to work fine) and I was expecting for it to work in a similar fashion.
What's the standard in this cases? Should i write a setup scripts to install the library dependencies on the target machine? Is there another way I'm not aware of? I've never released an application for Linux (nor Windows) and I'm struggling to find the resources to do things "the right way".
Thanks for everyone suggestions, I ended up settling for the easy way, compiling the "easy to install" libraries dynamically e.g.-lSDL2 and the others statically (checked the licenses and it should be fine) like so:
g++ main.cpp -o main -Wl,-Bdynamic -lSDL2 -lSDL2_image -lSDL2_ttf -Wl,-Bstatic -lSDL2_gfx -static-libgcc -static-libstdc++
I'll put in my documentation how to install the required SDL2 libraries.
I am not sure how familiar you are with pkg-config, but the output for sdl2 is this:
-D_REENTRANT -I/usr/include/SDL2 -lSDL2
This was found from running this:
pkg-config --cflags --libs sdl2
Basically, you need to point to where SDL2 is located BEFORE you actually link to it.
The tool pkg-config is designed to tell you the information you need when you want to link to a package in Linux. You were linking with the library, but you forgot to tell GCC where the library is located.
If you want to compile you code, try this:
g++ main.cpp -o runme `pkg-config --cflags --libs sdl2`
This will automatically grab all of the flags that you need to compile with SDL2 included.
Oh, and you should note, ORDER MATTERS WHEN ADDING FLAGS AND LIBRARIES!!!
There are many questions on SO where the order of compiler options caused all of the problems. Do not be like those people. I suggest you search SO for more info on that.

libopencv_imgcodecs.so.3.2: cannot open shared object file: No such file or directory

I know that a similar question has been asked before, but none of the suggestions have helped.
I am trying to compile an OpenCV project using C++ in Ubuntu 15.10. I can run the project correctly in Netbeans. But I am supposed to send this to someone who will be using the command line. I can compile the program with the line:
g++ -ggdb -o convert *.cpp \`pkg-config --cflags --libs opencv\`
Where convert is the chosen name for the executable. There are no problems after executing this line. But when I run
./convert "image1.tif" "image2.tif"
I get:
./convert: error while loading shared libraries: libopencv_imgcodecs.so.3.2: cannot
open shared object file: No such file or directory
In my .cpp files, I have:
#include "/usr/local/include/opencv2/highgui/highgui.hpp"
The file libopencv_imgcodecs.so.3.2 is in my /usr/local/lib folder. I tried putting -L/usr/local/lib in the command line, but this did not help. Perhaps this file path needs to go in a specific order in the command line? The order mattered for the pkg-config --cflags --libs opencv, which had to come after the -o convert *.cpp.
Just for convenience, as the first comment said, you just need:
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib
if your CMAKE_INSTALL_PREFIX=/usr/local
Your libopencv_imgcodecs.so isn't linked correctly. You can check that by using ldd:
$ ldd ./convert
/path/to/program/convert:
...
libopencv_imgcodecs.so.3.2 => not found
libopencv_imgproc.so.3.2 => not found
libopencv_core.so.3.2 => not found
...
You can find where libopencv_imgcodecs.so is installed:
$ find / -type f -name libopencv_imgcodecs.so.3.2
/usr/local/lib/libopencv_imgcodecs.so.3.2
Save this directory to LD_LIBRARY_PATH variable.
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib

Executing cross-compiled C++ program using Boost on Raspberry Pi

I have built a GCC cross toolchain for the RPi and can cross-compile C++ source and successfully run it after copying the executable to the RPi.
Next I built the Boost libraries targeting ARM, using the cross toolchain. I can successfully build and link C++ source to those Boost libraries using the cross toolchain on my PC.
I then copied the program, dynamically linked to Boost, to the RPi and copied all built libraries into /usr/local/lib on the Pi. However, executing fails:
$ ./my_program
./my_program: error while loading shared libraries: libboost_system.so.1.60.0: cannot open shared object file: No such file or directory
Again, this library, libboost_system.so.1.60.0, exists in /usr/local/lib.
I also tried
export LD_LIBRARY_PATH='/usr/local/lib'
but that doesn't change anything. What am I doing wrong?
EDIT:
I build all source files like this (rpi-g++ is a symlink to my cross-compiler):
rpi-g++ -c -std=c++1y -Wall -Wextra -pedantic -O2 -I /path/to/cross/boost/include *.cpp
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -lboost_system -pthread
EDIT 2:
When linked with
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -rdynamic -lboost_system -pthread
the problem remains the same. I have checked and verified everything suggested by Technaton as well. Strangely, ldd insists that the created executable is "not a dynamic executable" (checked that on my PC and on the RPi), which doesn't make sense to me.
There are several things you can check. I've posted a complete check list here, but judging from your linker command line, number 5 is probably the culprit.
Check that your library and your program are correctly build for the target architecture. You can verify that by using file ./myprog and file libboost_system.so.1.60.0.
Make sure that you have copied the actual shared object, and not a link to it.
Ensure that the shared object file's permissions are sane (0755).
Run ldconfig -v and check that your shared object file is picked up. Normally, /usr/local/lib is in the standard library search path, and LD_LIBRARY_PATH is not required.
Make sure that your program is actually dynamically linked by running ldd ./myprog. Judging from your linker command line, that is the problem: You're missing -rdynamic.
Check the paths returned from ldd: If you have linked with rpath, the library search path might be screwed up. Try again without -rpath.

Linking the Allegro library to a C++ application using the g++ compiler (Ubuntu)

In trying to get Allegro (A C++ game programming library) to work with a very simple C++ application in Ubuntu 12.04, I am unable to get the program to compile with the allegro header definitions. It returns the error allegro.h - no such file or directory found. I tried running a pkg-config to find the proper linker command, but that didn't help in compilation.
I am almost certain it is installed correctly at this point. I tried using a pkg-config --cflags --libs allegro-5.0 for the include file paths, none of which worked when using in the g++ compile line.
Thanks in advance.
Running a pkg-config --cflags --libs allegro-5.0 told me wrong on the include path. It told me to use -I/usr/local/include and after some digging into that folder, I found that the include path is -I/usr/local/include/allegro5 instead. It is compiling fine now.

Problems compiling gtkmm

OS: Fedora 14
Compiler: g++ (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)
I installed gtkmm24-devel from repository via yum. To make sure the install went as planned I decided to try one of the examples on the page.
#include <gtkmm.h>
int main(int argc, char *argv[]) {
Gtk::Main kit(argc, argv);
Gtk::Window window;
Gtk::Main::run(window);
return 0;
}
I ran the example, and, hey! It said it couldn't find gtkmm.h, no problem, I just forgot to link the library. I added /usr/include/gtkmm-2.4 to my library search through Eclipse. No bueno, g++ still can't find it!
fatal error: gtkmm.h: No such file or directory
I then try to include gtkmm by using #include <gtkmm-2.4/gtkmm.h> and recompile, another error! :(
/usr/include/gtkmm-2.4/gtkmm.h:87:20: fatal error: glibmm.h: No such file or directory
Thanks for reading.
Short answer
Use the output of 'pkg-config gtkmm-2.4 --cflags' for include paths and 'pkg-config gtkmm-2.4 --libs' for libraries to link.
Long answer
It said it couldn't find gtkmm.h, no problem, I just forgot to link the library.
Building a C/C++ program is done in two separate steps. First the source files are compiled, outputting object files; and then the object files are linked together. The error you are getting comes from the compiling step.
On Linux, most libraries come with pkgconfig files to make it easier for other programs to use the libraries. gtkmm also comes with its own pkgconfig files.
You are trying to manually specify /usr/include/gtkmm-2.4 for include path; this is wrong. Instead, use the output of pkgconfig to figure out where the header files are located. To get all the include directories needed for gtkmm, use the following command:
pkg-config gtkmm-2.4 --cflags
For linking, use the following pkgconfig command to get the libraries you need to link with:
pkg-config gtkmm-2.4 --libs
You can test it on the command line by invoking g++ directly.
g++ myfirstprogram.cpp -o myfirstprogram `pkg-config gtkmm-2.4 --cflags --libs`
For more information, see the gtkmm docs: http://library.gnome.org/devel/gtkmm-tutorial/unstable/sec-basics-simple-example.html.en
These steps usually help resolving this problem:
Search your computer for glibmm.h
If found - add its directory to the include path list
If not found - Google for glibmm.h and find out which library it is contained in. You will find out in this case it's (surprise!) glibmm. Install it using your package manager.
The problem, as noted in comments, is a compiler error and the compiler is arguing about a missing (header) file. The steps I described above either find the location of the missing file or help you to install a library that the header file belongs to.