对于以下CMakeLists.txt
文件
cmake_minimum_required(VERSION 3.15)\nproject(Testing)\n\ninclude(CMakePackageConfigHelpers)\nconfigure_package_config_file(FooConfig.cmake.in\n ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake\n INSTALL_DESTINATION lib/Goo/dmake\n)\n\ninstall(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake\n DESTINATION lib/Foo/cmake )\n
Run Code Online (Sandbox Code Playgroud)\n和FooConfig.cmake.in
文件
@PACKAGE_INIT@\n\ncheck_required_components(Foo)\n
Run Code Online (Sandbox Code Playgroud)\n它最终会安装FooConfig.cmake
到lib/Foo/cmake
\xef\xbc\x9a
$ cmake ..\n$ cmake --build .\n$ cmake --install . --prefix ../install/\n$ ls -R ../install/\n../install/:\nlib\n\n../install/lib:\nFoo\n\n../install/lib/Foo:\ncmake\n\n../install/lib/Foo/cmake:\nFooConfig.cmake\n
Run Code Online (Sandbox Code Playgroud)\n看来无论我为选项设置什么值INSTALL_DESTINATION
,configure_package_config_file
它都不会更改FooConfig.cmake
安装目录。但如果我评论INSTALL_DESTINATION lib/Goo/dmake
,CMake错误提示
\n\n没有为 CONFIGURE_PACKAGE_CONFIG_FILE() 指定 INSTALL_DESTINATION
\n
那么这个INSTALL_DESINATION
选项有什么用呢?它的值(具体来说,上面的设置lib/Goo/dmake
)实际上会影响什么?
文档:
\n\n\n给
\n<path>
定的 to必须是将文件安装到的INSTALL_DESTINATION
目标位置。FooConfig.cmake
我知道正确的方法是INSTALL_DESTINATION lib/Foo/cmake
。但正如我故意设置的那样lib/Goo/dmake
,该 FooConfig.cmake
文件仍然位于所需的目的地lib/Foo/cmake
。那么,为什么这个选项被设计为必须的呢?
Tsy*_*rev 10
函数configure_package_config_file 仅生成指定为第二个参数的文件。此功能既不安装生成的文件,也不影响其安装。因此,它的参数只能影响生成文件的内容。
如果您查看生成的脚本FooConfig.cmake
,那么您可以找到类似的行
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
Run Code Online (Sandbox Code Playgroud)
这就是脚本根据文件路径计算安装前缀的方式FooConfig.cmake
。
例如,当您安装带有前缀的软件包/usr/local
并且您的FooConfig.cmake
脚本将位于该目录中/usr/local/lib/Foo/cmake
时,引用的路径将扩展为/usr/local/lib/Foo/cmake/../../../
,对应于/usr/local/
.
脚本中的组件数量../
等于参数中的组件数量INSTALL_DESTINATION
。
假设一个包将所有公共标头安装到目录中include/
(相对于安装前缀),并且配置脚本需要通过变量将该目录传递给用户FOO_INCLUDE_DIR
。
最直接的方法是在脚本中编写以下内容:
# FooConfig.cmake.in
...
set(FOO_INCLUDE_DIR @CMAKE_INSTALL_PREFIX@/include)
Run Code Online (Sandbox Code Playgroud)
因此configure_package_config_file
将替换真正的安装前缀而不是@CMAKE_INSTALL_PREFIX@
.
但是将绝对路径嵌入到配置文件中会阻止程序包被重新定位。因此,一旦安装,该包只能从安装目录中使用,而不能复制到其他地方。
对于可重定位包,配置文件会计算相对于配置文件本身路径的所有安装路径,因为它是脚本调用时唯一已知的路径find_package
。就像可执行文件可以计算位于该可执行文件附近的文件的路径一样。
如果脚本安装到lib/Foo/cmake/FooConfig.cmake
,则包含目录的相对路径将为../../../include
,因此可以在该脚本中使用以下分配:
# FooConfig.cmake.in
...
set(FOO_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../include)
Run Code Online (Sandbox Code Playgroud)
因此,当find_package(Foo)
执行此脚本时,它将变量CMAKE_CURRENT_LIST_DIR扩展到可能重定位脚本的实际目录。
使用相对路径进行操作需要编码人员的大量关注,因此 CMake 允许自动执行此任务:
# CMakeLists.txt
...
# Path to the include directory in the installation tree
set(INCLUDE_DIR 'include')
configure_package_config_file(FooConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
INSTALL_DESTINATION lib/Foo/cmake
# Tell CMake to handle variable `INCLUDE_DIR` as a path
# under installation tree.
PATH_VARS INCLUDE_DIR
)
Run Code Online (Sandbox Code Playgroud)
# FooConfig.cmake.in
@PACKAGE_INIT@
# Here we could use `@PACKAGE_INCLUDE_DIR@` as reference
# to variable 'INCLUDE_DIR' set in the CMakeLists.txt.
set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_DIR@")
Run Code Online (Sandbox Code Playgroud)
如果您查看生成的文件,您会发现它@PACKAGE_INCLUDE_DIR@
被扩展为${PACKAGE_PREFIX_DIR}/include
,它使用变量PACKAGE_PREFIX_DIR
。
归档时间: |
|
查看次数: |
4353 次 |
最近记录: |