WIP: Add CMAKE_FIND_PACKAGE_INCLUDE variable
Introduce CMAKE_FIND_PACKAGE_INCLUDE
variable that can be used for customization of find_package
behavior without modifying user's CMake code.
Example:
cmake_minimum_required(VERSION 3.14)
project(app)
add_executable(app main.cpp)
find_package(foo CONFIG REQUIRED)
target_link_libraries(app PRIVATE foo::foo)
find_package(bar CONFIG REQUIRED)
target_link_libraries(app PRIVATE bar::bar)
System
By default packages will be found in system:
/usr/bin/g++
CMakeFiles/app.dir/main.cpp.o
-o app
/usr/local/lib/libfoo.a
/usr/local/lib/libbar.a
ExternalProject
If packages installed by ExternalProject we can add CMAKE_PREFIX_PATH
to specify the custom location:
/usr/bin/g++
CMakeFiles/app.dir/main.cpp.o
-o app
/home/travis/__EP_root/lib/libfoo.a
/home/travis/__EP_root/lib/libbar.a
add_subdirectory
If the project structure is:
CMakeLists.txt
third_party/foo/CMakeLists.txt
third_party/bar/CMakeLists.txt
You can add next CMake hook:
# hooks/subdir.cmake
# create empty ${CMAKE_FIND_PACKAGE_NAME}Config.cmake for find_package
# <some code>
add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/${CMAKE_FIND_PACKAGE_NAME})
And use this hook by adding -DCMAKE_FIND_PACKAGE_INCLUDE=hooks/subdir.cmake
without modifying original CMakeLists.txt
:
/usr/bin/g++
CMakeFiles/app.dir/main.cpp.o
-o app
third_party/foo/libfoo.a
third_party/bar/libbar.a
Mix
If you want to take foo
from add_subdirectory
and other packages from ExternalProject
:
# hooks/epsubdir.cmake
set(as_subproject foo)
if(NOT "${CMAKE_FIND_PACKAGE_NAME}" IN_LIST as_subproject)
return()
endif()
# create empty ${CMAKE_FIND_PACKAGE_NAME}Config.cmake for find_package
# <some code>
add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/${CMAKE_FIND_PACKAGE_NAME})
/usr/bin/g++
CMakeFiles/app.dir/main.cpp.o
-o app
third_party/foo/libfoo.a
/home/travis/__EP_root/lib/libbar.a
I.e., such approach can be used as a solution for #17735
FetchContent
Example of FetchContent hook:
# hooks/fetch.cmake
# create empty ${CMAKE_FIND_PACKAGE_NAME}Config.cmake for find_package
# <some code>
include(FetchContent)
FetchContent_Declare(
${CMAKE_FIND_PACKAGE_NAME}
GIT_REPOSITORY https://github.com/.../${CMAKE_FIND_PACKAGE_NAME}.git
GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(${CMAKE_FIND_PACKAGE_NAME})
/usr/bin/g++
CMakeFiles/app.dir/main.cpp.o
-o app
_deps/foo-build/libfoo.a
_deps/bar-build/libbar.a
Hunter
Hook for Hunter:
# hooks/hunter.cmake
hunter_add_package(${CMAKE_FIND_PACKAGE_NAME})
/usr/bin/g++
CMakeFiles/app.dir/main.cpp.o
-o app
/home/travis/.hunter/_Base/021aeb8/0ec0fcc/023562f/Install/lib/libfoo.a
/home/travis/.hunter/_Base/021aeb8/0ec0fcc/023562f/Install/lib/libbar.a
Test
Test for all the cases can be found here:
Results:
If it looks good, I can work on the rest of MR: documentation, tests, examples, etc.