Note: Re-asking a poorly-written earlier question.
How should a package/library developer, using CMake, allow for their package to be effectively installed on a system, as well as easily integrated/used in another CMake-based project?
According to the oft-linked-to talk by Daniel Pfeiffer (slides here), this is an example of how it's done:
In CMakeLists.txt
:
find_package(Bar 2.0 REQUIRED)
add_library(Foo ...)
target_link_libraries(Foo PRIVATE Bar::Bar)
install(TARGETS Foo EXPORT FooTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(EXPORT FooTargets
FILE FooTargets.cmake
NAMESPACE Foo::
DESTINATION lib/cmake/Foo
)
in a second file (which?):
include(CMakePackageConfigHelpers)
write_basic_package_version_file("FooConfigVersion.cmake"
VERSION ${Foo_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES "FooConfig.cmake" "FooConfigVersion.cmake"
DESTINATION lib/cmake/Foo
)
in a third file (which?):
include(CMakeFindDependencyMacro)
find_dependency(Bar 2.0)
include("${CMAKE_CURRENT_LIST_DIR}/FooTargets.cmake")
So, we have:
- At least four different CMake files (
CMakeLists.txt
,FooTargets.cmake
,FooConfig.cmake
,FooConfigVersion.cmake
) - ... more than one of which is generated, but more than one is written by hand
- ... and which also include each other
- ... and whose names do not make it clearer which does what
- ... with some, but not all of them, getting installed.
I keep getting confused and mixed-up about this. Pfeifer says "I wish this were easier; but at least it's straightforward" - it's not really that straightforward.
Questions:
- Can this be simplified somehow?
- If not, why are each of these files important to have?
- Can't some more of the files be auto-generated with less commands/scripts/files generated dynamically?