首页 > 解决方案 > 如何使用组件创建 cmake 项目

问题描述

我试图在 Cmake 中创建包含组件的项目。所以另一个项目可以使用这个项目:

find_package(ltk COMPONENTS Core Networking REQUIRED)
target_link_libraries(test ltk::Core ltk::Networking)

我的图书馆项目(称为 ltk)

这是一个项目树:

ltk/
|--- CMakeLists.txt
|--- ltkConfig.cmake.in
|--- ltkConfigVersion.cmake.in
|
+--- Core/
|    |--- core.cc 
|    |--- core.h
|    |--- CMakeLists.txt
|
+--- Networking/
     |--- networking.cc
     |--- networking.h
     |--- CMakeLists.txt

完整项目在这里:https ://gitlab.com/T0maas/cmake-testing

该文件ltk/CMakeLists.txt具有以下内容:

set(project ltk)
set(LTK_VERSION 0.0.1)
cmake_minimum_required(VERSION 3.21)
project(${project})
add_subdirectory(Core)
add_subdirectory(Networking)

foreach(p LIB BIN INCLUDE CMAKE)
  set(var INSTALL_${p}_DIR)
  if(NOT IS_ABSOLUTE "${${var}}")
    set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
  endif()
endforeach()


export(TARGETS Core Networking FILE "${PROJECT_BINARY_DIR}/ltkTargets.cmake")
export(PACKAGE ltk)

file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" "${INSTALL_INCLUDE_DIR}")

set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}")

configure_file(ltkConfig.cmake.in "${PROJECT_BINARY_DIR}/ltkConfig.cmake" @ONLY)
set(CONF_INCLUDE_DIRS "\${LTK_CMAKE_DIR}/${REL_INCLUDE_DIR}")

configure_file(ltkConfig.cmake.in   "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/ltkConfig.cmake" @ONLY)

configure_file(ltkConfigVersion.cmake.in  "${PROJECT_BINARY_DIR}/ltkConfigVersion.cmake" @ONLY)

install(FILES
  "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/ltkConfig.cmake"
  "${PROJECT_BINARY_DIR}/ltkConfigVersion.cmake"
  DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/${project}" )

install(EXPORT ltkTargets DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/${project}" )

其中Core/CMakeLists.txt包含:

set (component Core)
add_library(${component} SHARED core.cc )
add_library(${project}::${component} ALIAS ${component})

set_target_properties(${component} PROPERTIES PUBLIC_HEADER  "core.h")

install(TARGETS ${component} 
  EXPORT ltkTargets
  COMPONENT ${component}
  LIBRARY DESTINATION lib/ltk
  ARCHIVE DESTINATION lib/ltk
  RUNTIME DESTINATION bin
  PUBLIC_HEADER DESTINATION include/ltk/
)

Networking/CMakeLists.txt类似于_Core/CMakeLists.txt

文件ltkConfig.cmake.in包含以下内容:

get_filename_component(LTK_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(LTK_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")


if(NOT TARGET Core AND NOT LTK_BINARY_DIR)
  include("${LTK_CMAKE_DIR}/ltkTargets.cmake")
endif()

if(NOT TARGET Networking AND NOT LTK_BINARY_DIR)
  include("${LTK_CMAKE_DIR}/ltkTargets.cmake")
endif()

set(LTK_LIBRARIES Core Networking)

ltkConfigVersion.cmake.in

set(PACKAGE_VERSION "@LTK_VERSION@")

# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
    set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()

安装此项目后,我在以下位置看到一些文件/usr/lib/cmake/ltk

ltkTargets-noconfig.cmake
ltkTargets.cmake
ltkConfigVersion.cmake
ltkConfig.cmake

测试

但是现在当我尝试配置一些测试项目时,它有以下内容CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(test)
find_package(ltk COMPONENTS Core REQUIRED)
add_executable(main main.cc)
target_link_libraries(main ltk::Core)

它显示以下错误:

-- Configuring done
CMake Error at CMakeLists.txt:4 (add_executable):
  Target "main" links to target "ltk::Core" but the target was not found.
  Perhaps a find_package() call is missing for an IMPORTED target, or an
  ALIAS target is missing?


-- Generating done

我已阅读以下链接,但这对我没有帮助:

编辑

现在我添加NAMESPACE ltk:: to install(EXPORT)ltk/CMakeLists.txt

install(EXPORT ltkTargets DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/${project}" NAMESPACE ltk::)

但是包含#include <core.h>抱怨的测试项目:

fatal error: core.h: No such file or directory

路径/usr/include/ltk尚未导出。

编辑 2

修复了包含问题:添加到 {Core, Networking}/CMakeLists.txt

target_include_directories(${component} PUBLIC $<INSTALL_INTERFACE:include/ltk>)

现在我可以在我的测试项目中使用这个:

target_include_directories(main PUBLIC ltk)

标签: cmake

解决方案


推荐阅读