Cmake doesn't install RPATH when adding link_library with -L
When setting up link libraries like this
target_link_libraries (SOME_TARGET -L/somedir -lfoo)
cmake does not handle RPATH. Is "-L" and "-l" not best practice, or really wrong? When I create my own Find * .cmake I usually use find_library()
, but the find script I got doesn't do it and resorts to the above form using '-L' and '-l'.
The documentation doesn't really explain how the RPATHs are assembled, and also the documentation isn't really quite clear how it handles "-l" and "-L", the only pointer you get is
"Element names starting with - but not -l or -framework are considered linker flags."
source to share
Specifying toolchain-specific flags such as -l
and -L
is generally discouraged as it impairs portability and may have different effects than expected.
The correct way to specify the linker path is with a command link_directories
.
The idiomatic solution in CMake is to use find_library
to find the library and then pass the full path to the linker, so you don't need to worry about link directories at all.
Now RPATH is a different beast as it also defines where dynamic libraries can be located at runtime. Usually the default settings work quite well here. If you ever find yourself in a sad situation where this is not the case, there are a number of CMake target properties and variables that affect this:
There are several properties used to specify RPATH rules. INSTALL_RPATH a semicolon-separated list of rpath to use for the stated target (for platforms that support it). INSTALL_RPATH_USE_LINK_PATH a boolean value that, if true, will add directories in the linker search path and outside the project to INSTALL_RPATH. SKIP_BUILD_RPATH - A Boolean value that indicates whether to automatically skip the generation of the rpath, which allows the target to be run from the build tree. BUILD_WITH_INSTALL_RPATH Boolean indicating whether to bind the target in the build tree using INSTALL_RPATH. This takes precedence over SKIP_BUILD_RPATH and avoids the need to re-link the mount. INSTALL_NAME_DIR - string defining the directory part of the 'install_name' fieldshared libraries in Mac OSX to use for established purposes. When the target is created, the values โโof the variables CMAKE_INSTALL_RPATH, CMAKE_INSTALL_RPATH_USE_LINK_PATH, CMAKE_SKIP_BUILD_RPATH, CMAKE_BUILD_WITH_INSTALL_RPATH and CMAKE_INSTALL_NAME_DIR are used to initialize these properties.
(From the set_target_properties
documentation )
Also you may need to look at the CMake wiki page for RPATH handling .
The whole RPATH business is unfortunately quite complex and it will take a lot more space to explain in detail than is appropriate for Stack Overflow's answer, but I hope this is enough to get you started.
source to share
Mostly you are using it target_link_libraries()
wrong. According to the documentation , you should provide target, libraries, and possibly some CMake specific binding flags.
For example, something like this:
target_link_libraries(my_build_target somedir/foo.so)
If you are using your own developed solutions Find*.cmake
, it is usually done as follows:
find_library(foo)
//build main target somewhere here
//now link it:
target_link_libraries(my_build_target ${FOO_LIBRARIES})
NOTE. ... I am assuming your generated files Find*.cmake
follow these guidelines and populate CMake variables like SOMELIB_LIBRARIES
, and / or SOMELIB_INCLUDE_DIRS
, etc.
NOTE 2: for my personal opinion, target_link_directories()
this is a pain in the butt and you should avoid using it unless you really need it. This is difficult to maintain and uses paths relative to the current source directory.
source to share