skip to Main Content

I haven’t changed a bit in the cmake configuration of the project. The only thing that has changed is the "in-house" built release of a new version of the opensource library (OpenCV). What is strange is that some of the libraries from the locally exracted folder are linked and found and others are not.

  • When cmake is called OPENCV_LIB variable is created with all of the libraries needed – this variable is used for linking
  • All such libraries are present in the folder
  • Whole library was built in one step (all for x64 configuration)
  • The project is correctly linked with the libraries from the library

Yet, when the ldd is called on the final executable, the result is quite confusing.

libopencv_core.so.406 => /LOCAL_FOLDER/OpenCV/lib/x64/libopencv_core.so.406 (0x00007f974e2df000)    
libopencv_calib3d.so.406 => /LOCAL_FOLDER/OpenCV/lib/x64/libopencv_calib3d.so.406 (0x00007f974d852000)    
libopencv_imgcodecs.so.406 => /LOCAL_FOLDER/OpenCV/lib/x64/libopencv_imgcodecs.so.406 (0x00007f974d795000)    
libopencv_imgproc.so.406 => /LOCAL_FOLDER/OpenCV/lib/x64/libopencv_imgproc.so.406 (0x00007f974b79c000)    
libopencv_features2d.so.406 => not found                                                                                                                                           
libopencv_flann.so.406 => not found  

All of the libraries are present in the OPENCV_LIB variable which is used for linking and all of them are present in the LOCAL_FOLDER. When ldd is called on the libraries which results in not found in the LOCAL_FOLDER some of their dependencies are not found as well. How come, some libraries are found and some are not, when they are from in the same folder?


The process of OpenCV library inclusion to the project:

Script creates the dependencies.cmake file which is included with include(dependencies.cmake). The file contains amongst others, the following lines:

set(OPENCV_INCLUDE_DIR "/LOCAL_FOLDER/OpenCV/include") 
include_directories(${OPENCV_INCLUDE_DIR})
link_directories("/LOCAL_FOLDER/OpenCV/lib/x64/")
set(OPENCV_LIB ${OPENCV_LIB} *.so) # * as substitution for all the libs that are "set" this way.

Then in a CMakeLists of the sub project it is used like so

target_link_libraries(${PROJECT_NAME} ${OPENCV_LIB} "-Wl,--disable-new-dtags")

ldd -v result for one of the libraries

/LOCAL_FOLDER/OpenCV/lib/x64/libopencv_calib3d.so.406:
                libgcc_s.so.1 (GCC_3.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
                libgcc_s.so.1 (GCC_4.0.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
                libm.so.6 (GLIBC_2.29) => /lib/x86_64-linux-gnu/libm.so.6
                libm.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libm.so.6
                libstdc++.so.6 (GLIBCXX_3.4.20) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (CXXABI_1.3.8) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.19) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.9) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.29) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.26) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.11) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (CXXABI_1.3) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.14) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.21) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4.15) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libstdc++.so.6 (GLIBCXX_3.4) => /lib/x86_64-linux-gnu/libstdc++.so.6
                libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
                libc.so.6 (GLIBC_2.3.4) => /lib/x86_64-linux-gnu/libc.so.6

The RPATH is set to origin like so

set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN")

I have also tried to set it as suggested in the post here Nothing has solved the problem.

Setting it explicitly to LOCAL_FOLDER does nothing.


When I download the older "in-house" built version of the same library and call ldd on some libraries that shows not found in the new one, it ends up in the same situation. Linking is always ok. Basically with older version of the library, the ldd shows the same for the libraries, but the resulting binary is ok (all libs are located properly) and can be run without issues. The only difference between the old library and the new one is that the old was built with GCC 8 and under Ubuntu 18. The new one with GCC 11 and under Ubuntu 20.

2

Answers


  1. Chosen as BEST ANSWER

    The issue was that the new version of dependent library has the RUNPATH defined, but the other project/libraries using this library are using RPATH. When the RUNPATH is defined it ignores any defined RPATH, therefore transitive dependencies do ignore the RPATH. The solution was to remove the RUNPATH from the new library and add RPATH. The RPATH has been deprecated so if anyone facing this can use RUNPATH instead of RPATH they should do so.

    The change from RUNPATH to RPATH was done with help of this answer.


  2. You have specified the RPATH for your target. So its direct dependencies are searched in the program’s directory. I think that your program directly depends only on libopencv_core.so.406, libopencv_calib3d.so.406, libopencv_imgcodecs.so.406 and libopencv_imgproc.so.406. The other two libraries are indirect dependecies (i.e. they are direct dependencies of one of the former libraries). So your programs RPATH is not applied when these indirect depenendcies are searched.

    I would recommend you to run your program like that.

    $ LD_LIBRARY_PATH=`pwd` ./your_program_binary_name

    Upd: Also you have specified all of the libraries in OPENCV_LIB variable, the linker throws some of them out because your program doesn’t use their symbols directly.

    You can check my answer by adding some explicit calls to the functions which are defined in libopencv_features2d.so.406 and libopencv_flann.so.406 and then running ldd. If I’m right then all the libs would be resolved.

    The linker optimizes library list because CMake call ld with -Wl,--as-needed parameters. You could also figure out how to turn off such behavior. I’m not a cmake guru to help you in that way.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search