eclipse CDT: searching /usr/lib although not in lib search path - c++

I am trying to run a bit of pcl code (from their website). I am currently, on ubuntu, using boost 1_51 (that I built) and in my Eclipse C++ Build->Settings I have
/home/aly/libs/boost_1_51_0/stage/include in the include path and /home/aly/libs/boost_1_51_0/stage/lib in the library search path. I do not have /usr/include or /usr/lib.
At runtime I am getting some boost error, which made me think perhaps it is not running against the correct libraries as boost_1_46 is built in /usr/lib (this is the most up to date version in the ubuntu repos). So I removed a lib file (libboost_timer.so) from the /usr/lib dir and recompiled (which was fine) and then ran. At runtime I got the following error:
error while loading shared libraries: libboost_thread.so.1.46.1: cannot open shared object file: N
My question is, why if /usr/include and /usr/lib aren't in my include path and library search paths, is my program looking for the 1.46 version?
Additional info:
To compile eclipse is doing:
Invoking: Cross G++ Linker
g++ -L/home/aly/libs/OpenCV-2.4.3/release/lib -L/home/aly/libs/boost_1_51_0/stage/lib -o "3DObjectDetection" ./src/HFNodeSplitCalculator.o ./src/HFNodeUtils.o ./src/HFTreeNode.o ./src/HoughForest.o ./src/ImagePatch.o ./src/Main.o ./src/PatchGenerator.o ./src/utils.o -lvtkmetaio -lvtkImaging -lvtkIO -lvtkViews -lvtkVolumeRendering -lvtkalglib -lvtkDICOMParser -lvtkInfovis -lvtkFiltering -lvtkGeovis -lGL -lopencv_core -lopencv_highgui -lopencv_imgproc -lpcl_io -lpcl_visualization -lpcl_common -lpcl_surface -lpcl_kdtree -lpcl_search -lpcl_geometry -lpcl_features -lvtkproj4 -lvtkParallel -lvtksys -lvtkRendering -lvtkCommon -lboost_serialization -lboost_timer -lpthread -lboost_context -lboost_date_time -lboost_system -lboost_thread -lboost_filesystem -lboost_random -lboost_regex -lglut -lvtkexoIIc -lvtkCharts -lvtkGenericFiltering
Finished building target: 3DObjectDetection
And my $LD_LIBRARY_PATH is
:/home/aly/libs/boost_1_51_0/stage/lib/:/home/aly/libs/OpenCV-2.4.2/build/lib/:/usr/lib/:/home/aly/libs/cuda-5.0/lib:/home/aly/libs/cuda-5.0/lib64
As you can see the boost lib dir appears before /usr/lib

Related

Error loading shared libraries after cross compiling: No such file or directory

I'm having problems to load share libraries after cross-compiling my C++ code using Docker Buildx, having a Raspberry Pi Zero W as the target.
After I perform the build, I copy the generated binary to a Raspberry Pi Zero already running and with OpenCV4 installed.
When I run the executable, the following error message is shown:
pi#raspberrypi:/mnt/system/$ ./software.run
./software.run: error while loading shared libraries: libopencv_freetype.so.4.2: cannot open shared object file: No such file or directory
Despite OpenCV4 being already installed, this particular lib wasn't in the /usr/lib. So, I copied it, run sudo ldconfig but, even after this procedure, my software still cannot find the lib.
I even added the /usr/lib to the path of the system, but, it didn't work.
pi#raspberrypi:/usr/lib $ sudo ldconfig -v | grep libopencv_free
ldconfig: Can't stat /usr/local/lib/arm-linux-gnueabihf: No such file or directory
ldconfig: Path `/lib/arm-linux-gnueabihf' given more than once
ldconfig: Path `/usr/lib/arm-linux-gnueabihf' given more than once
ldconfig: /lib/arm-linux-gnueabihf/ld-2.28.so is the dynamic linker, ignoring
ldconfig: /lib/ld-linux.so.3 is the dynamic linker, ignoring
libopencv_freetype.so.4.2 -> libopencv_freetype.so.4.2.0
pi#raspberrypi:/mnt/system/ $ file software.run
software.run: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=409a24c10761e2b9fd7a310cddfb09c86fb3a207, not stripped
pi#raspberrypi:/mnt/system $ echo $LD_LIBRARY_PATH
/usr/lib
Makefile:
CC = g++
STD = --std=c++14
SOFTWARE_SRC = $(wildcard src/software/*.cpp)
SOFTWARE_BIN = software.run
CV_LIBS = $(shell pkg-config --cflags --libs opencv4)
SOFTWARE_INC = -Iinclude -I/usr/include -I/usr/local/include
SOFTWARE_LDFLAGS = -lraspicam_cv -L/opt/vc/lib -lmmal -lmmal_core -lmmal_util -lwiringPi
all: software-out
software-out:
$(CC) $(STD) $(SOFTWARE_SRC) -o $(SOFTWARE_BIN) $(CV_LIBS) $(SOFTWARE_INC) $(SOFTWARE_LDFLAGS)
Other software that also uses OpenCV is working properly.
I also build a "Hello World" software just to validate my cross-compiling environment and it is working.
Thank you all in advance
EDIT
After several attempts, I was able to fix the problem by building the libs locally.
I couldn't identify what caused it, but, the libs generated by the Buildx environment weren't working properly in the Raspberry Pi Zero.
I'm building a truly cross-compiling environment to address this issue.

linux linking to a .so , but still getting undefined reference

I am trying to create an executable that uses code from both static libraries and a shared library:
The static libs are several boost .a , pthread and libbus.a. The shared lib is a libwrap.so.
Note that the libwrap , uses code from libbus and libbus uses code from pthread. Finally, the executable uses code from libwrap and from boost.
Since the order of libraries included in the linker matters I am trying to find the "winning" sequence.
The linking stage is the following (pasted in multiple lines for convenience):
$ /usr/bin/c++
-Wall -Wextra
-fPIC
-fvisibility=hidden -fno-strict-aliasing -Wno-long-long
-m64
-rdynamic
-D_UNICODE -DUNICODE
CMakeFiles/Wrapper_Test.dir/test.cpp.o
/usr/local/lib/libboost_log.a
/usr/local/lib/libboost_system.a
/usr/local/lib/libboost_filesystem.a
/usr/local/lib/libboost_date_time.a
/usr/local/lib/libboost_thread.a
/usr/local/lib/libboost_log_setup.a
/usr/local/lib/libboost_chrono.a
-pthread
/home/nass/dev/Data_Parser/trunk/external/lib/linux64_gcc_release/libbus.a
-L/home/nass/dev/Data_Parser_build/lib #this is where the libwrap.so is located
-Wl,-rpath,/home/nass/dev/Data_Parser_build/lib
-lwrap #the shared lib
-o ../../../bin/Wrapper_Test
The link error is
CMakeFiles/Wrapper_Test.dir/test.cpp.o: In function `main':
test.cpp:(.text+0x2e): undefined reference to `wrapperNamespace::GetWrapper()'
collect2: error: ld returned 1 exit status
The GetWrapper() is located in libwrap.so of course, and I can verify it is a symbol that can be found in there:
$ nm -Ca ../../../lib/libwrap.so | grep GetWrapper
00000000000423d6 t wrapperNamespace::GetWrapper()
However, the linker cannot find it. what am I doing wrong here?
EDIT:
The linking command above is generated by the following CMakeLists.txt file:
set(TARGET_NAME Wrapper_Test)
#set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
#set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
#set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
# INCLUDE INTERNAL FOLDER
include_directories(${CMAKE_SOURCE_DIR}/include/Wrapper)
add_executable(${TARGET_NAME} test.cpp)
add_boost_lib(${TARGET_NAME} log system filesystem date_time thread log_setup chrono)
setup_libbus(${TARGET_NAME}) #the libbus.a
target_link_libraries(${TARGET_NAME} -L../../../lib -lwrap)
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER test)
I would start by looking at the cmake file which generates these lines.
It should be simple to add shared libaries to your path, for example:
find_library(
LIBWrapper
NAMES wrap
PATHS /home/nass/dev/Data_Parser_build/lib
)
And then link them to your test file, for example
add_executable(test src/test.cpp)
target_link_libraries(test ${LIBWrapper})
Similar should work for static libraries. This has the advantage that you don't have to deal with all the compiler/platform specific details which CMake supposedly handles for you, and which can be fairly complex & obscure.
If your library is generated dynamically, i.e. before cmake configuration time, you could just pass the appropriate linking flags to target_link_libraries:
target_link_libraries(test -L/home/nass/dev/Data_Parser_build/lib -lwrap)
I have used this suggestion in a few projects (e.g. https://github.com/caskorg/cask/blob/master/CMakeLists.txt) which dynamically generate the library, then link against it. If this doesn't work I suspect something else is wrong.
You should use -Wl,-Bstatic in front of static libs and -Wl,-Bdynamic for the dynamic ones. You also need to use -l for libraries and -L for library paths.
Something like:
$ /usr/bin/c++ test.cpp.o \
-L/usr/local/lib \
-Wl,-Bstatic \
-lboost_log \
-lsystem \
-L/home/nass/dev/Data_Parser_build/lib \
-Wl-Bdynamic \
-Wl,-rpath,/home/nass/dev/Data_Parser_build/lib \
-lwrap \
-o ../../../bin/Wrapper_Test
looks better. Many things depend on the version of your compiler/linker/OS.

Using Shared Object Files

I installed opencv 2.4.3 on ubuntu 12.04 using cmake. At the time of installation, .so files were put in /usr/local/lib directory. When I compile my code using the following line in terminal using the default location of .so files (i.e. /usr/local/lib) then it works fine
g++ fileName.cpp -lopencv_core -lopencv_highgui -lopencv_imgproc
I am trying to experiment with the shared object files. I copied the required shared object files from /usr/local/bin and put them in a new folder location /home/nishant/Desktop/lib. I copied the following files and their respective .so.2.4 and .so.2.4.3 files:
1) libopencv_core.so
2) libopencv_highgui.so
3) libopencv_imgproc.so
Then I changed there names to libcore.so , libhighgui.so and libimgproc.so respectively. I changed their name so that the old .so files should not be used from /usr/local/lib. Now when I try compiling my code using the shared object files in the new folder location then I get the following error:
Terminal Command:
g++ filename.cpp -L/home/nishant/Desktop/lib -lcore -lhighgui -limgproc
Error:
/usr/bin/ld: cannot find -lcore
/usr/bin/ld: cannot find -lhighgui
/usr/bin/ld: cannot find -limgproc
collect2: ld returned 1 exit status
It is interesting to note that the following works:
g++ filename.cpp -L/home/nishant/Desktop/lib -lopencv_core -lopencv_highgui -lopencv_imgproc
Reason: The .so files from /usr/local/lib are being used.
My Question : How can I use the .so files from the new folder location to make my code work.
I see three ways:
1.
Please update your LD_LIBRARY_PATH - add path to your libraries before running g++.
2.
Please add the directory where your libraries are located to /etc/ld.so.conf and run:
sudo ldconfig
Then run g++.
3.
Please create a new file: /etc/ld.so.conf.d/local.conf and add path do the directories with your libs to it and run:
sudo ldconfig
Then run g++.

Runtime errors when coding OpenCV programs using codeBlocks in linux

When I try to compile a C++ program which uses the openCV library in CodeBlocks it gives me a runtime error :
error while loading shared libraries: libopencv_calib3d.so.2.2:
cannot open shared object file: no such file or directory
This is in spite of the fact that I have added all the required libraries using linker settings for the Code Blocks IDE (including the one named libopencv_calib3d.so.2.2 which is a symbolic link).
However I'm able to compile the program using the command line by issuing the command :
g++ hello-world.cpp -o hello-world \
-I /usr/local/include/opencv -L /usr/local/lib
\ -lm -lcv -lhighgui -lcvaux
Can somebody advise me on how I can get to run the same using Code Blocks.
Thanks!
The file libopencv_calib3d.so.2.2 is part of OpenCV 2.2. There is, however, no libcv, libhighgui or libcvaux part of OpenCV 2.2. This means that your g++ call links against another version of OpenCV.
To link against OpenCV 2.2, you would need flags like -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann.
You should also not put them in manually, but instead use
export PKG_CONFIG_PATH=/usr/local/share/opencv/:$PKG_CONFIG_PATH
g++ `pkg-config --cflags --libs opencv` hello-world.cpp -o hello-world
I would recommend installing a reasonably up-to-date version of OpenCV for Linux, 2.4.9 for example, at this time of writing, appears to build with the current version of gcc that I have (4.8.2). There are a few steps you need to complete in order to get a simple OpenCV example up and running in Code::Blocks. The OpenCV documentation tells you to create a build directory within your OpenCV root directory and run cmake, make, sudo make install etc in order to generate the libraries your project may need to link to, including the libopencv_calib3d.so you mention:
This blog posting gives explanations on how to install OpenCV and configure it's use for Code::Blocks in Ubuntu Linux environments:
http://www.technical-recipes.com/2014/using-opencv-in-codeblocks-in-linux/

How to use C++ Boost library with pkg-config?

I successfully compiled and installed the latest version of the Boost library onto my linux machine.
Now, I would like to be able to use pkg-config to ease the process of providing linking paremeters with GCC.
Since I am too lazy for hand-coding my own .pc file, is there a script/tool which would automatically generate the needed .pc file or in some other way update pkg-config with boost flags?
(If someone already has that .pc file, a share would be welcome as well.)
What you're looking for seems to be a bit complicated, and a long-requested feature, as indicated in this 3 year old post https://svn.boost.org/trac/boost/ticket/1094 on Boost's trac. Reading through it shows that the feature was repeatedly postponed and never implemented (as of 1.4.3). The cause of the inability to generate a .pc file usable by pkg-config happens to do with boost's inconsistency in naming their library versions / build variants.
FWIW, an alternative for "automating" your building process is to use autotools (autoconf/automake). There's a link that might be of use to you (which I can't post because SO thinks I'm a spammer instead of a newcomer!), just google "tsuna boost m4 github" and it should take you there :)
Was facing a similar issue with boost. Wrote simple python script to generate a .pc file. Saved me the pain of having write all the linker commands. I've posted it on https://github.com/nmante/pkg-config-generator.
Essentially, you give the script a directory where the library files are (.so, .a, .dylib files) and it will generate the linker commands (e.g. -lboost_graph). Feel free to tweak and fork to your needs.
Here's a sample boost.pc file I generated for my machine (Mac OS X). You can tweak it manually, or you can use my github program to generate it on your machine.
# Package Information for pkg-config
prefix=/usr/local/Cellar/boost/1.60.0_2
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/boost
includedir_new=${prefix}/include
Name: Boost
Description: Boost is awesome
Version: 1.60.0
Libs: -L${exec_prefix}/lib -lboost_prg_exec_monitor-mt
-lboost_math_c99f-mt -lboost_unit_test_framework-mt
-lboost_container-mt -lboost_log_setup -lboost_math_tr1l
-lboost_graph-mt -lboost_wserialization-mt -lboost_log-mt
-lboost_math_c99f -lboost_type_erasure -lboost_signals-mt
-lboost_test_exec_monitor -lboost_filesystem -lboost_thread-mt
-lboost_math_tr1f-mt -lboost_date_time -lboost_timer
-lboost_math_tr1f -lboost_test_exec_monitor-mt -lboost_container
-lboost_math_tr1 -lboost_type_erasure-mt
-lboost_program_options-mt -lboost_graph -lboost_log_setup-mt
-lboost_random -lboost_system -lboost_system-mt -lboost_locale-mt
-lboost_wserialization -lboost_regex -lboost_exception
-lboost_timer-mt -lboost_signals -lboost_filesystem-mt
-lboost_math_c99-mt -lboost_math_tr1-mt -lboost_serialization-mt
-lboost_serialization -lboost_prg_exec_monitor -lboost_exception-mt
-lboost_coroutine -lboost_math_c99 -lboost_iostreams-mt
-lboost_random-mt -lboost_program_options -lboost_atomic-mt
-lboost_date_time-mt -lboost_math_c99l -lboost_math_tr1l-mt
-lboost_context-mt -lboost_regex-mt -lboost_coroutine-mt
-lboost_log -lboost_chrono-mt -lboost_wave-mt
-lboost_iostreams -lboost_chrono -lboost_unit_test_framework
-lboost_math_c99l-mt
Cflags: -I${includedir_old} -I${includedir_new}