GLR
GLR

Reputation: 1120

cmake: "make install" does not link against libraries in Ubuntu

I am relatively new to CMake, and I have developed a small project which builds a library that links to a shared library, named external_library. My CMakeLists.txt file looks something like this:

cmake_minimum_required(VERSION 2.8.12)
project(project_name)

include_directories(path_to_external_library_source_code)
add_subdirectory(path_to_external_library_header_files subproject/external_library)

target_link_libraries(project_name external_library)
install(TARGETS project_name DESTINATION installation_path)

When I build the project (using make), it works perfectly, and it creates the links correctly (I have checked it with the ldd command). However, when I try to install it (with make install), the generated file in the installation path is not linked against the specified shared library.

Using ldd again, I have checked that the shared library is not found by the library generated in the installation path, although it is found in the library generated in the build path. How could I fix this?

Thanks.

Pd: I am using CMake 3.5.1 in Ubuntu 16.04.2 LTS.

Upvotes: 5

Views: 4273

Answers (2)

DevSolar
DevSolar

Reputation: 70293

Shared libraries are looked for in certain paths, configured in /etc/ld.so.conf.

If a shared library is in one of these paths, it should be found. If it is not in one of these paths, you have four options:

  1. Having the library installed in a system default path (which might not be desirable with experimental software, or even possible given your permissions);
  2. edit the system-wide search path (not really desirable to touch system-wide settings, and perhaps not possible due to permissions),
  3. setting LD_LIBRARY_PATH (not recommended as it overrides system search paths, it's a debugging feature basically), or
  4. setting an RPATH, i.e. "telling" / "hardcoding" the binary where to look for its library.

What happens is that CMake automatically sets the RPATH of your binary, to reference the shared library from your project build in ${CMAKE_BINARY_DIR}. (This makes perfect sense, since you want to test the binary against the library you just built, not against one installed previously.)

By default, this RPATH setting is cleared by make install (so the installed binary no longer references the library in ${CMAKE_BINARY_DIR}, and instead searches the system search path -- where, it is assumed, the library has been installed as well).

If you are installing to a destination that is not in the system search path, your binary now no longer "sees" its shared library. Consult CMake RPATH handling to have CMake set the RPATH of your binaries to the installation path of your shared library.

Upvotes: 10

GLR
GLR

Reputation: 1120

I have found that the problem can be solved using the command find_library, specifying the path of the built shared library, doing something like this:

cmake_minimum_required(VERSION 2.8.12)
project(project_name)

include_directories(path_to_external_library_source_code)
find_library(LIBNAME LibName_1 LibName_2 HINTS built_lib_directory)    

target_link_libraries(project_name ${LIBNAME})
install(TARGETS project_name DESTINATION installation_path)

Upvotes: 0

Related Questions