gpt4 book ai didi

c++ - 对于可重定位的多平台安装,理想的 cmake 安装目录结构是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:42:27 24 4
gpt4 key购买 nike

CMake 安装采用目标目录,通常使用 GNUInstallDirs 加载目标名称的标准值。例如:

include(GNUInstallDirs)
install(TARGETS Foo
EXPORT Foo
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

但是它不提供针对不同平台或架构构建的不同路径。我一直在通过 CMAKE_INSTALL_PREFIX 安装到我的项目中特定于平台的文件夹,如下所示:

CMAKE_INSTALL_PREFIX=dist/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}

虽然这有一些问题:

  • 它复制跨平台相同的包含。
  • 如果我将不同平台安装到同一根目录但更改了 lib 目录,cmake 将无法在 lib/non/standard/path/cmake/FooConfig.cmake 中找到 cmake 配置目标
  • 而且模块模式搜索也无法正确找到库,这在完成模块模式搜索时会出现问题。如果库碰巧也有一个 cmake 模块,它要求每个 find_package 必须指定“CONFIG”,这开始变得奇怪,特别是当第 3 方库被告知将此安装目录视为一个共同的依赖项时,就会发生这种情况,并且不要不要在 find_package 中指定 CONFIG,因为他们为什么要这样做?

我正在寻找一个与 find_package 模块模式和配置模式一起工作的结构;像这样:

<install_prefix>/
include/
foo/
foo.h
lib/
<PLAT x ARCH x CONFIG>/
cmake/
foo/
FooConfig.cmake
libFoo.a

目标是:

  • 可以为不同的平台、架构和配置共同安装库
  • 包含内容可以共享
  • 找到包含应该在典型的模块模式搜索中工作
  • 应该只与 vanilla find_package(Foo REQUIRED) 一起工作,但适用于适当的平台和架构。

考虑到我会在这里安装大部分第 3 方库,如果这可以通过覆盖 GNUInstallDirs 中的变量来完成,它可能适用于许多库。我想剩下的要么必须编辑,要么我就放弃并使用包括平台和架构的单独安装目录。

最佳答案

我会尽我所能发布,也许它会有用。如果有人遗漏了部分,我会更新。

描述搜索顺序的文档在这里: https://cmake.org/cmake/help/v3.12/command/find_package.html?highlight=%3Cprefix%3E

有很多受支持的排列,所以我将从消除一些开始:

  • 忽略 Apple 的变体,因为那是针对框架的。
  • 忽略仅适用于 Windows 的路径,因为它对于任何其他平台来说都不是真正惯用的。
  • 最后,每个都有与 cmake 脚本所在位置相关的变体。我只选择 .../cmake/<name>*/风格。

剩下(**添加额外空间以显示相似性):

<prefix>/        (lib/<arch>|lib*|share)/cmake/<name>*/         (U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/ (W/U)

文档指出某些搜索路径适用于某些平台,但从技术上讲,我认为所有搜索路径都已尝试过。这只是平台惯用的问题。但是,因此,您不能使用不同的样式作为平台差异化因素。事实上,这应该意味着 Unix 选项对 Windows 也有效。

正如您在上面看到的,Windows 友好的 Unix 格式的唯一区别是名称的额外前缀。两者都是有效的选择,所以现在我将只引用 Unix only 风格,因为它符合我的偏好。最后,我不太关心“共享”文件夹,因为我们正在谈论 C/C++ 库。

所以最后我们只剩下这两个选择:

<prefix>/lib/<arch>/cmake/<name>*/
<prefix>/lib*/cmake/<name>*/

选项 1:多架构

带有 lib/<arch> 的路径如果 CMAKE_LIBRARY_ARCHITECTURE 被启用变量已设置。 CMAKE_<LANG>_LIBRARY_ARCHITECTURE状态:

If the <LANG> compiler passes to the linker an architecture-specific system library search directory such as <prefix>/lib/<arch> this variable contains the <arch> name if/as detected by CMake.

我知道这更专门针对某些支持多体系结构的发行版,并且应该自动设置。但是,我不太清楚这是否可以通过 cmake 轻松利用来实现这里的目标;你会在cmake中设置什么来控制它?在多架构系统上,库 Foo 和 Bar 可能看起来像:

<prefix>/lib/x86_64-linux-gnu/
foo-1.1/
cmake/FooConfig.cmake
bar/
cmake/BarConfig.cmake
foo-1.1.so
foo-1.1.lib
foo-1.1.dll
foo-1.1.dylib
bar.so
bar.lib
bar.dll
bar.dylib

如果我们可以控制 multiarch 的值是什么,这个选项可以很容易地用于其他平台,如:Darwin_x86_64、Windows_x86_64 等。它可能与 find_package 模块模式兼容,在该模式下可以找到所有包含,而不需要配置模式重定向到一些非标准目录。

选项 2:库变体

部分解决方案是在前缀中将平台完全分开,但至少可以将 64 位和 32 位架构组合在一起,只需拆分库即可。

lib* includes one or more of the values lib64, lib32, libx32 or lib (searched in that order).

  • Paths with lib64 are searched on 64 bit platforms if the FIND_LIBRARY_USE_LIB64_PATHS property is set to TRUE.
  • Paths with lib32 are searched on 32 bit platforms if the FIND_LIBRARY_USE_LIB32_PATHS property is set to TRUE.
  • Paths with libx32 are searched on platforms using the x32 ABI if the FIND_LIBRARY_USE_LIBX32_PATHS property is set to TRUE.
  • The lib path is always searched.

这至少有部分帮助。我会继续将 lib 用作 64 位,然后仅将 lib32 用于 32 位需求。

关于c++ - 对于可重定位的多平台安装,理想的 cmake 安装目录结构是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51112173/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com