Dependency

Operations to manipule dependencies. It requires CMake 3.20 or newer.

Synopsis

dependency(IMPORT <lib_name> <STATIC|SHARED> [RELEASE_NAME <raw_filename>] [DEBUG_NAME <raw_filename>] ROOT_DIR <directory_path> INCLUDE_DIR <directory_path>)
dependency(EXPORT <lib_name> <BUILD_TREE|INSTALL_TREE> [APPEND] OUTPUT_FILE <file_path>)
dependency(INCLUDE_DIRECTORIES <lib_name> <SET|APPEND> PUBLIC <gen_expr_list> ...)
dependency(IMPORTED_LOCATION <lib_name> [CONFIGURATION <build_type>] PUBLIC <gen_expr_list> ...)

Usage

dependency(IMPORT <lib_name> <STATIC|SHARED> [RELEASE_NAME <raw_filename>] [DEBUG_NAME <raw_filename>] ROOT_DIR <directory_path> INCLUDE_DIR <directory_path>)

Create an imported library target named <lib_name> by locating its binary files and setting the necessary target properties. This command combines behavior similar to find_library() and add_library(IMPORTED).

The command requires either the STATIC or SHARED keyword to specify the type of library. Only one may be used. At least one of RELEASE_NAME <raw_filename> or DEBUG_NAME <raw_filename> must be provided. Both can be used. These arguments determine which configurations of the library will be available, typically matching values in the CMAKE_CONFIGURATION_TYPES variable.

The value of <raw_filename> should be the core name of the library file, stripped of:

  • Any version numbers.

  • Platform-specific prefixes (e.g. lib).

  • Platform-specific suffixes (e.g. .so, .dll, .a, .lib).

The file will be resolved by scanning recursively all files in the given ROOT_DIR and attempting to match against expected filename patterns constructed using the relevant CMAKE_<CONFIG>_LIBRARY_PREFIX and CMAKE_<CONFIG>_LIBRARY_SUFFIX, accounting for platform conventions and possible version-number noise in filenames. More specifically, it tries to do a matching between the <raw_filename> in format <CMAKE_STATIC_LIBRARY_PREFIX|CMAKE_SHARED_LIBRARY_PREFIX><raw_filename> <verions-numbers><CMAKE_STATIC_LIBRARY_SUFFIX|CMAKE_SHARED_LIBRARY_SUFFIX> and each filename found striped from their numeric and special character version and their suffix and their prefix based on the plateform and the kind of library STATIC or SHARED. See the command module directory(SCAN), that is used internally, for full details.

If more than one file matches or no file is found, an error is raised.

Once located, an imported target is created using add_library(IMPORTED) and appropriate properties for each available configuration (RELEASE and/or DEBUG) are set, including paths to the binary and import libraries (if applicable), as well as the soname.

The following target properties are configured:

INTERFACE_INCLUDE_DIRECTORIES

Set to the directory given by INCLUDE_DIR. This path is propagated to consumers of the imported target during build and link phases. See the CMake doc for full details.

INTERFACE_INCLUDE_DIRECTORIES_BUILD

Set to an empty value. This is a custom property, not used by CMake natively, intended to track include directories for usage from the build-tree context.

INTERFACE_INCLUDE_DIRECTORIES_INSTALL

Set to an empty value. This is a custom property intended for tracking include paths during installation or packaging, for usage from the install-tree context.

IMPORTED_LOCATION_<CONFIG>

The full path to the actual library file (e.g. .a, .so, .dll), set separately for each configuration (RELEASE and/or DEBUG). See the CMake doc for full details.

IMPORTED_LOCATION_BUILD_<CONFIG>

Custom property set to an empty value. Intended for build-tree specific overrides of the library path, for usage from the build-tree context

IMPORTED_LOCATION_INSTALL_<CONFIG>

Custom property set to an empty value. Intended for install-time overrides of the library path, for usage from the install-tree context.

IMPORTED_IMPLIB_<CONFIG>

On DLL-based platforms (e.g. Windows), set to the full path of the import library file (e.g. .lib, .dll.a) for the corresponding configuration. See the CMake doc for full details.

IMPORTED_SONAME_<CONFIG>

Set to the filename of the resolved library (without path), allowing CMake to handle runtime linking and version resolution. See the CMake doc for full details.

IMPORTED_CONFIGURATIONS

Appended with each configuration for which a library was found and configured (e.g. RELEASE, DEBUG). See the CMake doc for full details.

Example usage:

dependency(IMPORT "mylib"
  SHARED
  RELEASE_NAME "mylib_1.11.0"
  DEBUG_NAME "mylibd_1.11.0"
  ROOT_DIR "${CMAKE_SOURCE_DIR}/libs"
  INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include/mylib"
)
dependency(EXPORT <lib_name> <BUILD_TREE|INSTALL_TREE> [APPEND] OUTPUT_FILE <file_path>)

Export an imported library target <lib_name> for use by external CMake projects. This command provides enhanced and customized behavior comparable to export() (for BUILD_TREE) and install(EXPORT) (for INSTALL_TREE), but specifically tailored to exported imported targets.

The output is a CMake script file named <file_path>, which can be included by downstream projects to import library target from the current project's build-tree or install-tree.

Depending on the tree context:

  • For BUILD_TREE: The file is generated in CMAKE_CURRENT_BINARY_DIR.

  • For INSTALL_TREE: The file is generated in CMAKE_CURRENT_BINARY_DIR/ CMakeFiles/Export and installed in the same relative directory structure under the install prefix.

If the APPEND keyword is specified, new export code is appended to the output file instead of overwriting it.

The exported script recreates the target and sets all relevant properties, so the target can be used transparently by other projects. It set the same properties than the module command dependency(IMPORT), so see its documentations for more details.

Example usage:

dependency(EXPORT "myimportedlib"
  BUILD_TREE
  APPEND
  OUTPUT_FILE "InternalDependencyTargets.cmake"
)

dependency(EXPORT "${imported_library}"
  INSTALL_TREE
  APPEND
  OUTPUT_FILE "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/cmake/InternalDependencyTargets.cmake"
)

The resulting file InternalDependencyTargets.cmake may then be included by CMake projects in <PackageName>Config.cmake.in to be used by configure_package_config_file() CMake command:

include("${CMAKE_CURRENT_LIST_DIR}/InternalDependencyTargets.cmake")
dependency(INCLUDE_DIRECTORIES <lib_name> <SET|APPEND> PUBLIC <gen_expr_list> ...)

Set or append public include directories via INTERFACE_INCLUDE_DIRECTORIES property to the imported target <lib_name>. This command works similarly to target_include_directories() in CMake, but introduces a separation between build-time and install-time contexts for imported dependencies.

The behavior differs from standard CMake in that it stores build and install include paths separately using generator expressions (see the section "Build specification with generator expressions").

The PUBLIC keyword indicates that the specified directories apply to the usage requirements of the target (i.e., will be propagated to consumers of the target). The directories following it must use generator expressions like $<BUILD_INTERFACE:...> and $<INSTALL_INTERFACE:...> to distinguish between build and install phases.

The command accepts the following mutually exclusive modifiers:

  • SET: Replaces any existing include directories.

  • APPEND: Adds to the current list of include directories.

This command internally sets or appends the following CMake properties on the target:

INTERFACE_INCLUDE_DIRECTORIES

This standard property determines the public include directories seen by consumers of the library. This will be populated using only the build-specific include paths (i.e., extracted from $<BUILD_INTERFACE:...>).

INTERFACE_INCLUDE_DIRECTORIES_BUILD

A custom property used internally to distinguish the build-time include paths. It stores the expanded list of directories extracted from the $<BUILD_INTERFACE:...> portion of the arguments.

INTERFACE_INCLUDE_DIRECTORIES_INSTALL

A custom property used to store include directories intended to be used after installation. It is extracted from the $<INSTALL_INTERFACE:...> expressions.

These custom properties (_BUILD and _INSTALL) are not directly used by CMake itself but are later re-injected into export files generated by dependency(EXPORT).

Example usage:

dependency(INCLUDE_DIRECTORIES "mylib" SET
  PUBLIC
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
    "$<INSTALL_INTERFACE:include>"
)

This example sets mylib to expose:

  • ${CMAKE_CURRENT_SOURCE_DIR}/include during the build.

  • <prefix>/include after installation (where <prefix> is resolved when imported via dependency(EXPORT)).

dependency(IMPORTED_LOCATION <lib_name> [CONFIGURATION <config_type>] PUBLIC <gen_expr_list> ...)

Set the full path to the imported target <lib_name> for one or more configurations. This command sets the IMPORTED_LOCATION_<CONFIG> property of the imported target from a generator expressions. More details in CMake doc.

If the CONFIGURATION option is specified, the path is set only for the given <config_type> (e.g. DEBUG, RELEASE), provided that this configuration is supported by the target. If CONFIGURATION is omitted, the path is set for all configurations supported by the imported target.

The PUBLIC keyword specifies the usage scope of the following arguments. These arguments must use generator expressions such as $<BUILD_INTERFACE:...> and $<INSTALL_INTERFACE:...> to distinguish between build and install phases (see the section "Build specification with generator expressions").

Example usage:

dependency(IMPORTED_LOCATION "mylib"
  CONFIGURATION "DEBUG"
  PUBLIC
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/debug/libMyLib.a>"
    "$<INSTALL_INTERFACE:lib/libMyLib.a>"
)