CMake's CMAKE_INSTALL_RPATH_USE_LINK_PATH: A Guide for Setting Runtime Library Paths


Purpose

  • When enabled (TRUE), it helps ensure that executables can find the shared libraries (*.so or .dll) they depend on at runtime, even if those libraries are installed in non-standard locations.
  • This variable is a boolean value in CMake that controls how runtime library paths (rpaths) are set for installed executables.

How it Works

  1. Linking Phase
    • During the linking stage, CMake considers all directories that are:
      • In the linker search path (specified using compiler flags or CMake's link_directories command).
      • Containing linked library files.
  2. RPATH Construction
    • If CMAKE_INSTALL_RPATH_USE_LINK_PATH is set to TRUE:
      • CMake automatically adds these linker search path directories (except for those within the project's build tree) to the INSTALL_RPATH property of the target executable.
      • This INSTALL_RPATH property determines the runtime search paths for the installed executable.

Benefits

  • Simplified Deployment
    This can streamline deployment, especially when dealing with non-standard library installation locations.
  • Relocatable Packages
    By including necessary library locations in the rpath, executables can potentially be moved to different directories without needing to modify system-wide library search paths or resorting to absolute paths.

Example Usage

set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)  # Enable automatic rpath population

# ... your project configuration (libraries, executables)

install(TARGETS my_executable RUNTIME DESTINATION bin LIBRARY DESTINATION lib)

In this example:

  • Assuming the linked libraries are not in the build tree, CMake will automatically add the lib directory (and potentially other relevant directories) to the rpath of the installed my_executable.
  • The install command installs my_executable to the bin directory and its linked libraries to the lib directory.
  • CMAKE_INSTALL_RPATH_USE_LINK_PATH is set to TRUE.

Cautions

  • Consider using CMAKE_INSTALL_RPATH explicitly for more granular control over rpath settings.
  • It's generally recommended to use system-wide library search paths whenever possible for broader compatibility.
  • While CMAKE_INSTALL_RPATH_USE_LINK_PATH offers convenience, it can introduce potential security concerns if used excessively. The runtime search paths should be restricted to trusted locations.
  • This variable is available in CMake versions 3.0 and later.


Scenario 1: Simple Project with Standard Library Locations

This example shows how CMAKE_INSTALL_RPATH_USE_LINK_PATH can work automatically:

cmake_minimum_required(VERSION 3.0)
project(my_project)

# Create a shared library
add_library(my_library SHARED source1.cpp source2.cpp)

# Create an executable that links against the shared library
add_executable(my_executable main.cpp)
target_link_libraries(my_executable PRIVATE my_library)

# Enable automatic rpath population
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# Install the executable and library (assuming standard system-wide library search paths)
install(TARGETS my_executable RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
install(TARGETS my_library DESTINATION lib)
  • This allows my_executable to find my_library at runtime without needing explicit rpath configuration.
  • Since CMAKE_INSTALL_RPATH_USE_LINK_PATH is TRUE, CMake will automatically add these standard locations to the rpath of my_executable when it's installed.
  • The libraries are likely installed in standard locations like /usr/lib or /lib on Linux/Unix systems.

Scenario 2: Project with Non-Standard Library Locations

This example demonstrates how to use CMAKE_INSTALL_RPATH_USE_LINK_PATH with a custom library installation directory:

cmake_minimum_required(VERSION 3.0)
project(my_project)

# Create a shared library
add_library(my_library SHARED source1.cpp source2.cpp)

# Create an executable that links against the shared library
add_executable(my_executable main.cpp)
target_link_libraries(my_executable PRIVATE my_library)

# Enable automatic rpath population
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# Install the executable and library in custom locations
install(TARGETS my_executable RUNTIME DESTINATION bin LIBRARY DESTINATION my_libs)
install(TARGETS my_library DESTINATION my_libs)
  • With CMAKE_INSTALL_RPATH_USE_LINK_PATH enabled, the rpath of my_executable will include my_libs, ensuring it finds the library at runtime.
  • Libraries are installed in the my_libs directory instead of standard locations.

Scenario 3: Project with Explicit Rpath Control

This example shows how to use CMAKE_INSTALL_RPATH for more granular control alongside CMAKE_INSTALL_RPATH_USE_LINK_PATH:

cmake_minimum_required(VERSION 3.0)
project(my_project)

# Create a shared library
add_library(my_library SHARED source1.cpp source2.cpp)

# Create an executable that links against the shared library
add_executable(my_executable main.cpp)
target_link_libraries(my_executable PRIVATE my_library)

# Enable automatic rpath population (might include unnecessary directories)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# Set explicit rpath for finer control (replace "/path/to/other/lib" as needed)
set_target_properties(my_executable PROPERTIES INSTALL_RPATH "/path/to/my_libs")

# Install the executable and library
install(TARGETS my_executable RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
install(TARGETS my_library DESTINATION lib)
  • We explicitly set the rpath to /path/to/my_libs, ensuring my_executable only looks there for my_library.
  • Automatic rpath population might include unnecessary directories.
  • We use both CMAKE_INSTALL_RPATH_USE_LINK_PATH and set_target_properties for INSTALL_RPATH.


    • The most common approach is to leverage the system-wide library search paths during linking. These paths are typically configured in the linker's configuration files (/etc/ld.so.conf on Linux/Unix or system environment variables on Windows).
    • By installing your libraries to standard locations within these search paths (e.g., /usr/lib or /lib), executables can find them at runtime without needing to modify rpaths.
    • Benefits
      • Broad compatibility across different systems.
      • No need for manual rpath configuration for most users.
    • Drawbacks
      • Requires control over library installation locations, which might not always be feasible.
      • Might not work for private libraries or custom deployments.
  1. Package Managers

    • If you're using a package manager like apt (Debian/Ubuntu) or yum (Red Hat/CentOS), consider creating a package for your project. Package managers handle library dependencies and search paths automatically.
    • Benefits
      • Streamlined installation and dependency management.
      • Ensures libraries are found at runtime.
    • Drawbacks
      • Adds complexity to the build process.
      • Requires users to have the package manager installed and configured.
  2. Explicit RPATH Configuration

    • You can use the set_target_properties command to explicitly set the INSTALL_RPATH property for your target executables. This allows you to define the exact runtime search paths for each executable.
    • Benefits
      • Granular control over rpaths.
      • Useful for custom deployments or non-standard library locations.
    • Drawbacks
      • Can become tedious to manage for multiple executables.
      • Requires careful consideration to avoid introducing security vulnerabilities by including untrusted directories in the rpath.
  3. Deployment Tools

    • Some deployment tools might offer functionalities to copy necessary libraries alongside your executables. This approach eliminates the need for rpath manipulation altogether.
    • Benefits
      • Can simplify deployment for specific environments.
    • Drawbacks
      • Increases deployment package size.
      • Might not be suitable for all deployment scenarios.

Choosing the Right Approach

  • For deployments requiring additional control
    Explore deployment tools.
  • For complex projects or custom deployments
    Consider package managers or explicit RPATH configuration.
  • For simple projects with standard library locations
    Use system-wide search paths.