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."

+4


source to share


2 answers


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.

+7


source


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.

+1


source







All Articles