Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

c++ - Why is CMake designed so that it removes runtime path when installing

I built my shared library(I use a lib calculating the fibonacci number for example) myself and want to use it in my another c++ project built by CMake

Let's say the shared library and headers located in /path/to/my/lib, the shared library libfib.so is in /path/to/my/lib/lib and the header fib.h is in /path/to/my/lib/include and my own project located in /path/to/my/project

Here is my original CMakeLists.txt:

cmake_minimum_required(VERSION 3.2)
project(learn-lib)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
set(FIB_INCLUDE "${FIB_PREFIX}/include")
set(FIB_LIB "${FIB_PREFIX}/lib")
set(EXE mybin)
include_directories(${FIB_INCLUDE})
link_directories(${FIB_LIB})
add_executable(${EXE} main.cpp)
target_link_libraries(${EXE} fib)
install(TARGETS ${EXE} RUNTIME DESTINATION bin)

And I use this script to build and install my project:

mkdir -p build_dir
cd build_dir
cmake -DFIB_PREFIX=/path/to/my/lib 
      -DCMAKE_INSTALL_PREFIX=/path/to/my/project 
      ..
make
make install
cd ..

Now, after running the install script, I got two executables, one in build_dir, one in the install location path/to/my/project/bin, when running the program in build_dir, everything is fine, but when running the installed program, I get:

./bin/mybin: error while loading shared libraries: libfib.so: cannot open shared object file: No such file or directory

After some searching on google and stackoverflow, I knew it seems that CMake removed the runtime search path that is tied to the executable when building. I now know two ways to get it around:

  1. Add the library path where libfib.so locates to the environment variable LD_LIBRARY_PATH
  2. Add set_target_properties(${EXE} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) into my CMakeLists.txt

So, my questions are:

  1. Why is CMake designed so? When installing, why would it remove runtime path from executables instead of just copying the built executables to the install destination or whatever keeping the link path for the installed program?
  2. Which way is the best practice(or is there a best practice) to eliminate this problem? To set the environment or to add set_target_properties(...) into CMakeLists.txt ?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You may want to look into CMake's RPATH handling settings

This quote in particular seems relevant to your predicament:

By default if you don't change any RPATH related settings, CMake will link the executables and shared libraries with full RPATH to all used libraries in the build tree. When installing, it will clear the RPATH of these targets so they are installed with an empty RPATH.

You can set the RPATH that is set for installed binaries using the CMAKE_INSTALL_RPATH variable, for example:

SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

and you can also disable the RPATH stripping during installation:

SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...