Importing dependencies#
The modern method of importing dependencies is to use
FetchContent_Declare(FIND_PACKAGE_ARGS)
which allows the user to choose how
to import the dependency: from the system (find_package
) or downloaded/local
source (FetchContent
).
Required dependency#
If the dependency is required, and it is a CMake based project, you can
straightforwardly use FetchContent_Declare(FIND_PACKAGE_ARGS)
. Note that
this feature is only introduced in CMake 3.24. Back-porting this feature can be
quite involved:
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(ProjectB
...
FIND_PACKAGE_ARGS CONFIG
)
else ()
if (NOT DEFINED FETCHCONTENT_SOURCE_DIR_PROJECTB)
if (NOT DEFINED FETCHCONTENT_TRY_FIND_PACKAGE_MODE)
set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE OPT_IN)
endif ()
if (FETCHCONTENT_TRY_FIND_PACKAGE_MODE MATCHES "(OPT_IN|ALWAYS)")
find_package(ProjectB QUIET CONFIG)
endif ()
endif ()
if (NOT ProjectB_FOUND)
FetchContent_Declare(ProjectB
...
)
endif ()
endif ()
See controlling dependency import for more details on how to control the import.
Optional dependency#
For optional dependencies, unfortunately the fallthrough using
FetchContent_Declare(FIND_PACKAGE_ARGS)
does not allow the dependency to not
be imported. For this the only clean design is to use find_package
, with
CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
and
CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
to control the dependencies.
Find<PackageName>.cmake
#
In order to provide compatibility with non-CMake projects, you can provide a
Find<PackageName>.cmake
file to search for this dependency. But keep in mind
that integrating this to make it work with the project’s export can be quite
tricky, since these modules should not be exported outside of the project, in
order to avoid conflicts with other similarly defined modules.
If you still need such a module, an example module can look as follows:
set(CMAKE_REQUIRE_FIND_PACKAGE_Example FALSE)
find_package(Example CONFIG QUIET)
if (Example_FOUND)
find_package_handle_standard_args(Example CONFIG_MODE)
return()
endif ()
pkg_search_module(Example IMPORTED_TARGET
example
)
if (Example_FOUND)
add_library(Example::hello ALIAS PkgConfig::Example)
return ()
endif ()
find_library(Hello_LIBRARY
NAMES hello
)
mark_as_advanced(Hello_LIBRARY)
find_path(Example_INCLUDE_DIR
NAMES hello.h
PATH_SUFFIXES example
)
mark_as_advanced(Example_INCLUDE_DIR)
find_package_handle_standard_args(Example
REQUIRED_VARS Hello_LIBRARY Example_INCLUDE_DIR
)
if(Example_FOUND)
set(Example_INCLUDE_DIRS ${Example_INCLUDE_DIR})
set(Example_LIBRARIES ${Hello_LIBRARY})
add_library(Example::hello UNKNOWN IMPORTED)
set_target_properties(Example::hello PROPERTIES
IMPORTED_LOCATION ${Hello_LIBRARY}
)
target_include_directories(Example::hello INTERFACE ${Example_INCLUDE_DIRS})
target_link_libraries(Example::hello INTERFACE ${Example_LIBRARIES})
endif()