【问题标题】:How to Create Packages with CMake如何使用 CMake 创建包
【发布时间】:2019-04-11 14:44:10
【问题描述】:
.
+-- MyPack
|   +-- Lib1
|   |   +-- include
|   |   |   +-- Lib1.h
|   |   +-- src
|   |   |   +-- Lib2.cpp
|   |   +-- CMakeLists.txt
|   +-- Lib2
|   |   +-- include
|   |   |   +-- Lib2.h
|   |   +-- src
|   |   |   +-- Lib2.cpp
|   |   +-- CMakeLists.txt
|   +-- CMakeLists.txt
+-- SubProject1
|   +-- CMakeLists.txt
+-- SubProject2
|   +-- CMakeLists.txt
+-- CMakeLists.txt

大家好。

我是 CMake 的新手,我正在尝试获得类似以下内容。 考虑到我的 C++ 项目的上述目录树:

我有一个目录(比如说“MyPack”),其中包含几个子目录(Lib1、Lib2...),每个子目录代表我编写的一个 C++ 库。

如何设置所有内容以便可以在其他子项目中写入find_package(MyPack)

每个子项目都是一个独立的项目,不依赖于其他子项目,只依赖于“MyPack”中的库。

【问题讨论】:

  • 导出MyPack中的包,然后-DCMAKE_PREFIX_PATH=../../MyPack

标签: c++ cmake cmake-modules


【解决方案1】:

您的绘图有点混乱,因为在 Lib2 之后有一个 CMakeLists.txt,它不属于任何文件夹... 无论如何:是 MyPack

  • Lib1 和 Lib2 ?
  • Lib1/Lib2/Subproj1/Subproj2 ?

第二种情况:

顶层目录 CMakeLists.txt 让您可以访问 Lib1 和 Lib2 的目标,如果您有这样的东西,您可以在 SubProject1 和 SubProject2 中使用它们:

project(MyPack)
add_subdirectory(Lib1) # Building Lib1
add_subdirectory(Lib2) # Building Lib2
add_subdirectory(SubProject1) # you can use Lib1 & Lib2 targets here
add_subdirectory(SubProject2) # you can use Lib1 & Lib2 targets here

如果是第一种情况,MyPack只有Lib1和Lib2:

使用 find_package(MyPack) 意味着您需要创建一个配置文件并 install() 您的项目:

project(MyPack)
add_subdirectory(Lib1)
add_subdirectory(Lib2)

在 Lib1/CMakeLists.txt 中:

add_library(lib1 "")
add_library(MyPack::lib1 ALIAS lib1)
[...]
include(GNUInstallDirs)
install( 
  TARGET lib1
  EXPORT MyPackTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  )

在 Lib2/CMakeLists.txt 中:

add_library(lib2 "")
add_library(MyPack::lib2 ALIAS lib2)
[...]
include(GNUInstallDirs)
install( 
  TARGET lib2
  EXPORT MyPackTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  )

现在您在导出 MyPackTargets 中有 lib1 和 lib2。您还必须安装该导出。

上面之后的任何地方:

install(
  EXPORT MyPackTargets
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
  NAMESPACE MyPack::
  FILE MyPackTargets.cmake # Not sure if this is still needed
  )

include(CMakePackageConfigHelpers)
configure_package_config_file( 
  "Config.cmake.in" 
  "MyPackConfig.cmake"
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
  PATH_VARS
    CMAKE_INSTALL_LIBDIR
  )

write_basic_package_version_file(
  ${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake
  VERSION 1.0.0
  COMPATIBILITY SameMajorVersion
  )

### Install Config and ConfigVersion files
install(
  FILES "${CMAKE_CURRENT_BINARY_DIR}/MyPackConfig.cmake"
        "${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MyPack"
  )

用 :

创建一个文件 Config.cmake.in
@PACKAGE_INIT@
include( "${CMAKE_CURRENT_LIST_DIR}/MyPackTargets.cmake" )

现在,如果您构建并安装您的项目 MyPack,其他项目中的 find_package(MyPack) 应该会找到它并导入您创建的目标。

这里有一些文档: https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html

https://blog.kitware.com/cmake-superbuilds-git-submodules/

希望有帮助

【讨论】:

  • 谢谢!我仍然无法让它按我的意愿工作。首先,案例是您所了解的第一个案例。我将您建议的代码放入 lib1-2/CMakeLists.txt,导出 MyPackTargets。之后,我在 MyPack/ 中创建了 Config.cmake.in 和 CMakeLists.txt,我在其中添加了两个库的子目录,并放置了您建议的代码(安装 MyPackTargets 的代码)。最后,运行“cmake”。在项目文件夹中(MyPack 之外),它找到了 MyPack 包,但没有找到 MyPack/MyPackConfig.cmake 包含的 MyPack/MyPackTargets.cmake。还有什么建议吗?
  • 您的项目找到 MyPack 包配置是一个好兆头。现在看来 Config.cmake.in 中的路径不正确,您应该尝试将其调整为安装文件夹中 MyPackTargets.cmake 的位置
  • 问题是我在任何地方都找不到任何 MyPackTargets.cmake。顺便说一句,我解决了将所有库的 add_subdirectory (在 MyPack 的 CMakeLists.txt 中)和 add_subdirectory(MyPack) 放在我的项目的 CMakeLists.txt 中(在“MyPack”中)。我不得不删除 find_package 指令,它现在工作正常。也许不是最佳做法,但我可以做我想做的事。所以谢谢你!
  • 您主要执行了我之前解释过的第二种解决方案 - 因为您拥有所有源代码,您可以访问构建树中的目标。对于您原来的问题,MyPackTargets.cmake 应该通过 install(Export) 安装。检查该命令是否在正确的位置执行其工作(您可以检查 install_manifest.txt 以查看文件的安装位置)
  • 我相信它是“TARGETS”而不是“TARGET”,除了那个错字之外,这个解决方案效果很好。谢谢!
猜你喜欢
  • 2022-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2013-07-04
  • 1970-01-01
  • 2021-07-07
相关资源
最近更新 更多