Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Install and export INTERFACE only library, CMake

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.

like image 714
Ward9250 Avatar asked Dec 08 '17 16:12

Ward9250


People also ask

What is Interface Library CMake?

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.

What is export in CMake?

Export targets or packages for outside projects to use them directly from the current project's build tree, without installation.

Can CMake install dependencies?

CMake itself does not allow to install dependencies automatically.

What is CMake target?

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.


1 Answers

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
like image 139
mchiasson Avatar answered Sep 21 '22 05:09

mchiasson