new CMake user here.
I've made a simple header only library, with the following CMake file:
cmake_minimum_required(VERSION 3.7)
project(mylib VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
#add_compile_options(-Wa -aslh)
# Define the library target
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include/)
add_executable(mytest test/basic_checks.cpp)
target_link_libraries(mytest mylib)
From http://foonathan.net/blog/2016/03/03/cmake-install.html
I've learned there are several steps to getting a library installed and to have it useable from another CMake project. First it must be "installed" and then it must be "exported". Then there's find_package, but I'll cross that bridge after I've gotten over the first two steps.
So following the example, I figure that I could add the following to the bottom of my CMake file:
# Install the header file.
install(FILES include/mylib.hpp DESTINATION "include/mylib-${PROJECT_VERSION}")
But the guide talks about also using install on TARGETS, and then adding EXPORT to the target install commands.
How much of this applies to a header only library in which I have no other compiled code of files other than the header?
How do I apply the steps described in : http://foonathan.net/blog/2016/03/03/cmake-install.html To an INTERFACE only library? The lack of .cpp files in my project is leading me to question which instructions apply and don't apply.
Interface Libraries add_library(<name> INTERFACE) Creates an Interface Library. An INTERFACE library target does not compile sources and does not produce a library artifact on disk. However, it may have properties set on it and it may be installed and exported.
Export targets or packages for outside projects to use them directly from the current project's build tree, without installation.
CMake itself does not allow to install dependencies automatically.
A CMake-based buildsystem is organized as a set of high-level logical targets. Each target corresponds to an executable or library, or is a custom target containing custom commands.
try this:
cmake_minimum_required(VERSION 3.7)
project(mylib VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
#add_compile_options(-Wa -aslh)
# Define the library target
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/mylibConfigVersion.cmake"
VERSION 0.1
COMPATIBILITY AnyNewerVersion
)
install(TARGETS mylib
EXPORT mylibTargets
LIBRARY DESTINATION lib COMPONENT Runtime
ARCHIVE DESTINATION lib COMPONENT Development
RUNTIME DESTINATION bin COMPONENT Runtime
PUBLIC_HEADER DESTINATION include COMPONENT Development
BUNDLE DESTINATION bin COMPONENT Runtime
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/mylibConfig.cmake.in"
"${PROJECT_BINARY_DIR}/mylibConfig.cmake"
INSTALL_DESTINATION lib/cmake/mylib
)
install(EXPORT mylibTargets DESTINATION lib/cmake/mylib)
install(FILES "${PROJECT_BINARY_DIR}/mylibConfigVersion.cmake"
"${PROJECT_BINARY_DIR}/mylibConfig.cmake"
DESTINATION lib/cmake/mylib)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)
add_executable(mytest test/basic_checks.cpp)
target_link_libraries(mytest mylib)
the content of cmake/mylibConfig.cmake.in
should only be this
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/mylibTargets.cmake")
check_required_components("@PROJECT_NAME@")
if you do all of this, not only that it makes your header-only library 'installable', but it also makes it 'findable'. users will be able to import your library like so:
find_package(mylib CONFIG REQUIRED)
target_link_libraries(MyApp mylib) # installed include/ path automatically added
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With