Linux copying dependencies using file(GET_RUNTIME_DEPENDENCIES..)

Hi there, I’m trying to make a simple OpenCV Linux application but it works only on OpenCV installed OS, so I wan’t to copy all of it’s dependencies into build folder via cmake to make it also work on the other computers as well without installing opencv on them.
So
I have red this topic:
Copying dependent DLLs to executable directory?
But I can’t use “file(GET_RUNTIME_DEPENDENCIES…)” command in my try.
Could you please show me the changes to make to achieve copying all required libs into build folder.

my Project tree:

my_project/CMakeLists.txt
my_project/DisplayImage.cpp
my_project/build/

my_project/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
set (CMAKE_CXX_STANDARD 11)
project( DisplayImage )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

my_project/DisplayImage.cpp:

#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv )
{
    if ( argc != 2 )
    {
        printf("usage: DisplayImage.out <Image_Path>\n");
        return -1;
    }
    Mat image;
    image = imread( argv[1], 1 );
    if ( !image.data )
    {
        printf("No image data \n");
        return -1;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE );
    imshow("Display Image", image);
    waitKey(0);
    return 0;
}

my_project/build/: empty

many thanks

You need to, after the executable is built, run a CMake script which does file(GET_RUNTIME_DEPENDENCIES) on the executable. This gets you a list of paths to libraries needed by the executable which can then be filtered before doing configure_file(${src} ${dest} COPY_ONLY) into your build tree.

Thank you,
So should I create a new CMakelLists.txt file on build directory ?
How can I use file(GET_RUNTIME_DEPENDENCIES) and
configure_file(${src} ${dest} COPY_ONLY)
lines to perform that the created executable “DisplayImage” gets all of its dependencies copied into build?
Could You please write the CMakelLists.txt script, that you’ve mentioned before, for this example.
I’m totally beginner and I can learn mostly from working examples, I’ll be pleased for your answers.
And how can I link the executable “DisplayImage” with copied ones instead of which are under /usr/lib and its subdirectories ?

Please help me,
Thanks a lot :innocent:

I can’t guarantee this is fully working, but it’s a sketch:

file(GET_RUNTIME_DEPENDENCIES
  EXECUTABLES "${exe_path}"
  RESOLVED_DEPENDENCIES_VAR found_deps
  UNRESOLVED_DEPENDENCIES_VAR unfound_deps)
if (unfound_deps)
  # not all required libraries found, probably error
endif ()

foreach (found_dep IN LISTS found_deps)
  # Determine if the dep library should be copied.
  if (dep_not_wanted)
    continue()
  endif ()
  configure_file("${found_dep}" "${dest_libdir}" COPY_ONLY)
endforeach ()

file(TOUCH "${tagfile}")
add_custom_command(
  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/tagfile"
  COMMAND "${CMAKE_COMMAND}"
          "-Dexe=$<TARGET_FILE:myexe>"
          "-Ddest_libdir=${CMAKE_BINARY_DIR}/lib"
          "-Dtagfile=${CMAKE_CURRENT_BINARY_DIR}/tagfile"
          -P "${path_to_above_file}"
  DEPENDS
    "$<TARGET_FILE:myexe>"
    "${path_to_above_file}"
  DOC "Copying dependencies for myexe")
1 Like

I have found one line terminal command to get all dependecies:
ldd | grep “=> /” | awk ‘{print $3}’ | xargs -I ‘{}’ cp -v ‘{}’

But this only copies into a specified folder, after that we must set some environment variables on the target pc. But I want that the dependencies are located on a subfolder of executables location so that where ever I put the main folder it still finds its libraries without searching env variables.

Much obliged for your answer,
I’ve created a CMakelists.txt file in another folder out of project and just copied the executable “DisplayImage” in it and copied your answer into the CMakelists.txt, changed string ‘myexe’ with ‘DisplayImage’ and also I changed ‘${exe_path}’ to ‘./DisplayImage’
but since my CMake Version is 3.5, some commands couldn’t work well.
I’ll try it later.
Thank you very much:)

For Linux, use and RPATH setting of $ORIGIN/rel/path/to/libdir should make that work.

Thanks, finally I could have done it.
by just changing the CMakeListst.txt:

cmake_minimum_required(VERSION 3.9)
set (CMAKE_CXX_STANDARD 11)
set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/lib)
set(INSTALL_RPATH_USE_LINK_PATH true)
project( DisplayImage )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
install(TARGETS DisplayImage
        RUNTIME
                DESTINATION "./"
        LIBRARY
                DESTINATION "./lib"
        ARCHIVE 
                DESTINATION "./archive"
)

set(CMAKE_INSTALL_PREFIX "./install" )

I’m grateful :innocent: