I want to build an executable file that looks for its dependencies in a determined relative path. In other words, I want to distribute a zip that contains 2 elements: An executable file and a folder with shared libraries. The executable must be able to find those shared libraries at runtime.
For now, I have the project compiled with cmake
. I'm using the cmake's command find_library
to find the abs. path to the dependencies.
Here is the CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
project( flowers )
find_library( VFC_LIB1 NAMES opencv_calib3d PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib )
find_library( VFC_LIB2 NAMES opencv_core PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib )
...
find_library( VFC_LIB16 NAMES opencv_videostab PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib )
SET(VFC_LIBS ${VFC_LIB1} ${VFC_LIB2} ... ${VFC_LIB16} )
SET(VFC_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/opencv)
IF (VFC_LIB1 AND VFC_LIB2 AND ... AND VFC_LIB16)
include_directories( ${VFC_INCLUDE} )
include_directories( FlowersDetector NeuronalNet )
add_executable( flowers FlowersDetector/Flowers.cpp FlowersDetector/FlowersDetector.cpp )
add_definitions(-std=c++11)
add_definitions(-D_DEBUG) # TODO remove this for release
target_link_libraries( flowers ${VFC_LIBS} )
ELSE (VFC_LIB1 AND VFC_LIB2 AND ... AND VFC_LIB16)
MESSAGE(FATAL_ERROR "OpenCV libraries not found")
ENDIF(VFC_LIB1 AND VFC_LIB2 AND ... AND VFC_LIB16)
The ...
indicates that the rest is the same as the previous, but changin the sequence number.
For example, VFC_LIB1 AND VFC_LIB2 ... AND VFC_LIB16
means that is alwais VFC_LIBx
, where x
is from 3 to 15.
The problem is that find_library
is used to get the absolute path (I have read that), so that does not allow me to copy-paste the executable to other computer and still be able to run it.
What I need is to find the libraries with a relative path, or other equivalent solution.
I have tried to make a "big" executable file with all the libraries "inside it". For that purpose, I have read that I have to link static libraries. I have re-compiled OpenCV building the static libraries (now I have the *.a files plus *.so files.
I have changed the CMakeLists.txt to add these static libraries:
cmake_minimum_required(VERSION 2.8)
project( flowers )
find_package( OpenCV REQUIRED )
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
SET(BUILD_SHARED_LIBRARIES OFF)
SET(CMAKE_EXE_LINKER_FLAGS "-static")
include_directories( ${OpenCV_INCLUDE_DIRS} )
include_directories( FlowersDetector NeuronalNet )
add_executable( flowers FlowersDetector/Flowers.cpp FlowersDetector/FlowersDetector.cpp )
add_definitions(-std=c++11)
add_definitions(-D_DEBUG)
target_link_libraries( flowers ${OpenCV_LIBS} )
The cmake
command runs ok, but when I try to make
the project I obtain many errors. Actually, it appears to be only an error, but replied several times. This error is: statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Here is the list of errors, avoiding the similar ones: (if the full list may be helpfull, tell me and I'll upload it)
Linking CXX executable flowers
/usr/bin/ld: cannot find -latk-1.0
/usr/bin/ld: cannot find -lgdk_pixbuf-2.0
/usr/local/lib/libopencv_core.a(opencl_core.cpp.o): In function `(anonymous namespace)::opencl_fn14<41, int, _cl_command_queue*, _cl_mem*, unsigned int, unsigned long const*, unsigned long const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, void const*, unsigned int, _cl_event* const*, _cl_event**>::switch_fn(_cl_command_queue*, _cl_mem*, unsigned int, unsigned long const*, unsigned long const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, void const*, unsigned int, _cl_event* const*, _cl_event**)':
opencl_core.cpp:(.text._ZN12_GLOBAL__N_111opencl_fn14ILi41EiP17_cl_command_queueP7_cl_memjPKmS6_S6_mmmmPKvjPKP9_cl_eventPSA_E9switch_fnES2_S4_jS6_S6_S6_mmmmS8_jSC_SD_+0x1c0): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `lookup_gid_name':
(.text+0x11a7): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
[And many similar errors]
collect2: error: ld returned 1 exit status
CMakeFiles/flowers.dir/build.make:143: recipe for target 'flowers' failed
make[2]: *** [flowers] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/flowers.dir/all' failed
make[1]: *** [CMakeFiles/flowers.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
I've tested the to re-install OpenCV with only the static libraries (*.a) and to use the default OpenCV CMakeLists:
cmake_minimum_required(VERSION 2.8)
project( flowers )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
include_directories( FlowersDetector NeuronalNet )
add_executable( flowers FlowersDetector/Flowers.cpp FlowersDetector/FlowersDetector.cpp )
add_definitions(-std=c++11)
add_definitions(-D_DEBUG)
target_link_libraries( flowers ${OpenCV_LIBS} )
I can compile all, even I can execute the program, but when the program tries to show an image I have the following error:
OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /media/ubuntu/67803d44-978a-493e-bdfb-5730e7e9f5a8/opencv-3.1.0/modules/highgui/src/window.cpp, line 527
terminate called after throwing an instance of 'cv::Exception'
what(): /media/ubuntu/67803d44-978a-493e-bdfb-5730e7e9f5a8/opencv-3.1.0/modules/highgui/src/window.cpp:527: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvNamedWindow
Aborted (core dumped)
I have installed with apt-get install
libgtk2.0-dev
and pkg-config
, and also I have downloaded and installed the ATK lib (from http://www.linuxfromscratch.org/blfs/view/svn/x/atk.html).
After that, I have rebooted and re-run cmake
and make
. When I execute the program, the error persists.
On Linux executable stores information about paths to its libraries using RPATH mechanism. This information is used by the linker when it loads executable into memory.
For make paths to libraries relative, there is special path component $ORIGIN
, which is evaluated to directory with executable.
In CMake, for set RPATH for executable built, use variable CMAKE_INSTALL_RPATH:
# sets RPATH for *install*ed files
set(CMAKE_INSTALL_RPATH "\$ORIGIN/lib") # Note CMake escaping aroung '$' sign.
# *built* files will also used RPATH which has been set before
set(CMAKE_BUILD_WITH_INSTALL_RPATH on)
# Use 'find_library' calls. They return absolute paths needs for *link* stage.
find_library(...)
...
set(VFC_LIBS ...)
# Create executable and link it using variables filled by 'find_library'
add_executable(flowers ...)
target_link_libraries(flowers ${VFC_LIBS})
Now, if you move(or install) executable into some directory <dir>
and all libraries to directory <dir>/lib/
, executable can be run.
For more info about RPATH handling in CMake see CMake wiki.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With