为什么 foo-config.cmake 和 foo-config-version.cmake 应该分开?
Why should foo-config.cmake and foo-config-version.cmake be separate?
在 Daniel Pfeiffer 的演讲中(Effective CMake) and by Deniz Bahadir (More Modern CMake), and even in the CMake documentation,建议(至少)生成 .cmake
文件以便在其他项目中使用带有 CMake 的存储库:foo-config.cmake
和foo-config-version.cmake
(对于包 foo
;另一种可能的命名方案是 FooConfig.cmake
和 FooConfigVersion.cmake
)。
这对我来说已经很奇怪了。为什么 foo-config.cmake
不应该 information/commands 关于已安装的版本?这两个单独的文件是否存在某些 objective 原因,或者它只是一个 CMake 设计 'gaffe'?
编辑: 删掉了这个问题的其余部分,为了集中注意力,因为我弄错了。
评论太多但不是完整答案:
我生成的项目中的一个典型序列是使用 CMakePackageConfigHelper and GNUInstallDirs 模块
来自CMake。
不需要生成foo-config-version.cmake
模板。只需使用此模块中的 write_basic_package_version_file
命令即可完成工作。
如果您想使用构建目录中的配置包而不需要安装它们,export
命令会派上用场。
参见示例:
# Support find_package(Foo NO_MODULE).
set(FOO_DOC_DIR ${CMAKE_INSTALL_DOCDIR})
set(FOO_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
set(FOO_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
set(FOODIR ${CMAKE_INSTALL_PREFIX})
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
configure_package_config_file(foo-config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/foo-config.cmake"
INSTALL_DESTINATION ${FOO_CONFIG_PACKAGE_LOCATION}
PATH_VARS FOODIR FOO_INCLUDE_DIR FOO_LIB_DIR FOO_DOC_DIR
)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/foo-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
# To make the component usable not only from the install directory but also from the build directory
export(
TARGETS Foo
FILE foo-export.cmake
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/foo-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/foo-config-version.cmake"
DESTINATION ${FOO_CONFIG_PACKAGE_LOCATION}
COMPONENT development
)
install(EXPORT Foo
DESTINATION ${FOO_CONFIG_PACKAGE_LOCATION}
NAMESPACE ${PROJECT_NAME}::
FILE foo-export.cmake
COMPONENT development
)
Why shouldn't foo-config.cmake also have information/commands regarding the installed version?
包脚本foo-config.cmake
可以自由创建目标(不能删除),在父作用域中设置变量,等等。将 foo-config-version.cmake
拆分为在隔离范围内运行的脚本,可以轻松地进行包搜索,而不必担心破坏变量。 可能 将所有这些功能合并到一个文件中(find modules 的方式),但历史表明这种做法是错误的-容易和多余。
基本上有两个优点:
- 隔离。 运行 版本脚本不会破坏
find_package
调用程序中的变量。 foo-config.cmake
运行后,它可以设置包变量、创建目标等,并完全相信用户有意执行此操作。
- 减少样板文件。
CMakePackageConfigHelpers
可以在 CMakeLists.txt
文件中以两行为代价生成良好的版本脚本。鉴于 CMake 3.19 中的新版本范围功能,这是一项受欢迎的自动化任务。
在 Daniel Pfeiffer 的演讲中(Effective CMake) and by Deniz Bahadir (More Modern CMake), and even in the CMake documentation,建议(至少)生成 .cmake
文件以便在其他项目中使用带有 CMake 的存储库:foo-config.cmake
和foo-config-version.cmake
(对于包 foo
;另一种可能的命名方案是 FooConfig.cmake
和 FooConfigVersion.cmake
)。
这对我来说已经很奇怪了。为什么 foo-config.cmake
不应该 information/commands 关于已安装的版本?这两个单独的文件是否存在某些 objective 原因,或者它只是一个 CMake 设计 'gaffe'?
编辑: 删掉了这个问题的其余部分,为了集中注意力,因为我弄错了。
评论太多但不是完整答案:
我生成的项目中的一个典型序列是使用 CMakePackageConfigHelper and GNUInstallDirs 模块 来自CMake。
不需要生成foo-config-version.cmake
模板。只需使用此模块中的 write_basic_package_version_file
命令即可完成工作。
如果您想使用构建目录中的配置包而不需要安装它们,export
命令会派上用场。
参见示例:
# Support find_package(Foo NO_MODULE).
set(FOO_DOC_DIR ${CMAKE_INSTALL_DOCDIR})
set(FOO_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
set(FOO_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
set(FOODIR ${CMAKE_INSTALL_PREFIX})
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
configure_package_config_file(foo-config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/foo-config.cmake"
INSTALL_DESTINATION ${FOO_CONFIG_PACKAGE_LOCATION}
PATH_VARS FOODIR FOO_INCLUDE_DIR FOO_LIB_DIR FOO_DOC_DIR
)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/foo-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
# To make the component usable not only from the install directory but also from the build directory
export(
TARGETS Foo
FILE foo-export.cmake
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/foo-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/foo-config-version.cmake"
DESTINATION ${FOO_CONFIG_PACKAGE_LOCATION}
COMPONENT development
)
install(EXPORT Foo
DESTINATION ${FOO_CONFIG_PACKAGE_LOCATION}
NAMESPACE ${PROJECT_NAME}::
FILE foo-export.cmake
COMPONENT development
)
Why shouldn't foo-config.cmake also have information/commands regarding the installed version?
包脚本foo-config.cmake
可以自由创建目标(不能删除),在父作用域中设置变量,等等。将 foo-config-version.cmake
拆分为在隔离范围内运行的脚本,可以轻松地进行包搜索,而不必担心破坏变量。 可能 将所有这些功能合并到一个文件中(find modules 的方式),但历史表明这种做法是错误的-容易和多余。
基本上有两个优点:
- 隔离。 运行 版本脚本不会破坏
find_package
调用程序中的变量。foo-config.cmake
运行后,它可以设置包变量、创建目标等,并完全相信用户有意执行此操作。 - 减少样板文件。
CMakePackageConfigHelpers
可以在CMakeLists.txt
文件中以两行为代价生成良好的版本脚本。鉴于 CMake 3.19 中的新版本范围功能,这是一项受欢迎的自动化任务。