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}
但这有一些问题:
我正在寻找一种与find_package模块模式和config模式一起使用的结构;像这样的东西:
<install_prefix>/
include/
foo/
foo.h
lib/
<PLAT x ARCH x CONFIG>/
cmake/
foo/
FooConfig.cmake
libFoo.a
目标是:
考虑到我将在这里主要安装第三方库,如果可以通过重写GNUInstallDirs中的var来完成,那么它可能适用于许多库。我猜其余的部分要么必须进行编辑,要么我就放弃并使用包含平台和架构的单独安装目录。
答案 0 :(得分:1)
如果您希望用户将某些标准目录设置为 CMAKE_PREFIX_PATH ,例如
/usr/local # installation prefix
但是您的项目会将内容安装到非标准的,平台特定的子目录中,例如
/usr/local/linux/x86/ # actual root directory where things are installed
您可以将FooConfig.cmake
放在标准子目录中:
/usr/local/lib/FooConfig.cmake
但要编写它,以便它从特定于平台的目录中搜索适当的.cmake
:
# File: FooConfig.cmake
# Location: lib/
#
# This is platform-independent script.
#
# Redirect configuration to the platform-specific script <system>/<cpu>/lib/FooConfig.cmake.
include(${CMAKE_CURRENT_LIST_DIR}/../${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/lib/FooConfig.cmake)
特定于平台的*Config.cmake
脚本可以用通常的方式编写。
所以,如果用户愿意写
find_package(Foo)
在为Linux/x86
设置的环境中,它将为该平台设置导入的目标。
答案 1 :(得分:1)
我会尽可能地发布为止,也许会有用。如果有人遗失物品,我会进行更新。
描述搜索顺序的文档在这里: https://cmake.org/cmake/help/v3.12/command/find_package.html?highlight=%3Cprefix%3E
有很多受支持的排列,所以我将从消除一些开始:
.../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风格,因为它适合我的偏爱。最后,我不太在乎“共享”文件夹,因为我们正在谈论的是C / C ++库。
所以最后我们只剩下这两个选择:
<prefix>/lib/<arch>/cmake/<name>*/
<prefix>/lib*/cmake/<name>*/
如果设置了lib/<arch>
变量,则启用带有CMAKE_LIBRARY_ARCHITECTURE
的路径。 CMAKE_<LANG>_LIBRARY_ARCHITECTURE
声明:
如果
<LANG>
编译器将特定于体系结构的格式传递给链接器 系统库搜索目录,例如<prefix>/lib/<arch>
this 如果/由CMake检测到,则变量包含<arch>
名称。
我知道这是专门针对支持多体系结构的某些发行版的,并且可以自动设置。但是,我不太确定这是否可以通过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模块模式兼容,在该模式下可以找到所有包含项,而无需配置模式以重定向到一些非标准目录。
部分解决方案是使平台在前缀中完全分开,但是至少可以拆分libs来组合至少64位和32位体系结构。
lib*
包含值lib64
,lib32
,libx32
或lib
中的一个或多个 (以该顺序搜索)。
- 如果在64位平台上搜索lib64路径,
FIND_LIBRARY_USE_LIB64_PATHS
属性设置为TRUE。- 如果在32位平台上搜索lib32的路径,
FIND_LIBRARY_USE_LIB32_PATHS
属性设置为TRUE。- 如果平台使用x32 ABI在平台上搜索libx32的路径,
FIND_LIBRARY_USE_LIBX32_PATHS
属性设置为TRUE。- 总是搜索lib路径。
这至少部分有帮助。我将继续使用lib作为64位,然后仅将lib32用于32位需求。