更改 cpack 为组件 RPM 生成的名称

change cpack generated name for component RPMs

我正在尝试使用 cpack(通过 cmake)创建一个创建多个 RPM 文件的 RPM 安装程序。我几乎已经开始工作了,但剩下的最后一个绊脚石是控制包名称。 具体来说我想控制组件名称在 RPM 文件名中出现的位置

这是我的实验性 CMakeLists.txt 文件,它将 foo.txtbar.txt 安装到两个不同的软件包 "myproject-foo" 和 "myproject-bar"。 我希望 RPM 遵循我自己的命名约定(实际上我想要对 FSH 更友好的约定)但是 出于某种原因 cmake 坚持在末尾添加组件名称。所以我得到:

myproject-comp-1.0.i686-foo.rpm
myproject-comp-1.0.i686-bar.rpm

而不是:

myproject-compfoo-1.0.i686.rpm
myproject-compbar-1.0.i686.rpm

我注意到它命名了源 RPM "more correctly": 例如

>rpm -qip <package> | grep source
Source RPM  : myproject-foo-1.0-1.src.rpm

虽然我实际上根本不想要源 RPM(有没有办法空白此字段?)

cmake_minimum_required(VERSION 2.8)

message("CMAKE_VERSION=${CMAKE_VERSION}")

SET(DOCDIR "doc")
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "core")
install(FILES foo.txt COMPONENT foo DESTINATION "${RPMBUILDROOT}${DOCDIR}")
install(FILES bar.txt COMPONENT bar DESTINATION "${RPMBUILDROOT}${DOCDIR}")

project(myproject CXX)

set(CPACK_PACKAGE_NAME "myproject")
set(CPACK_RPM_COMPONENT_INSTALL ON)
set(CPACK_PACKAGE_VERSION 1.0)
set(CPACK_PACKAGE_VENDOR "some org")

set(CPACK_COMPONENT_foo_DESCRIPTION "the foo component")
set(CPACK_COMPONENT_bar_DESCRIPTION "the bar component")

# mentioned in cpack docs but doesn't seem to do anything here
set(CPACK_COMPONENT_foo_DISPLAY_NAME "foo display name?")
set(CPACK_COMPONENT_bar_DISPLAY_NAME "foo display name?")

set(CPACK_COMPONENT_bar_DEPENDS foo)

set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "describe the complete suite of stuff")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/README.txt)

# added in cmake 3.6?
set(CPACK_RPM_foo_PACKAGE_SUMMARY "describe the foo package")
set(CPACK_RPM_bar_PACKAGE_SUMMARY "describe the bar package")
set(CPACK_RPM_foo_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-foo")
set(CPACK_RPM_bar_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-bar")

set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/README.txt)

#set(CPACK_RPM_foo_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-foo-${CPACK_PACKAGE_VERSION}.i686")
#set(CPACK_RPM_bar_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-bar-${CPACK_PACKAGE_VERSION}.i686")


set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-comp${CPACK_COMPONENT_DISPLAY_NAME}-${CPACK_PACKAGE_VERSION}.i686")

set(CPACK_RPM_PACKAGE_ARCHITECTURE "i686")
set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)

include(CPack)

cpack_add_component(foo
                    DISPLAY_NAME foo comp
                    DESCRIPTION this is the foocomp)
cpack_add_component(bar
                    DISPLAY_NAME bar comp
                    DESCRIPTION this is the bar comp
            DEPENDS foo)

似乎 CPACK_PACKAGE_<component>_FILE_NAME or CPACK_PACKAGE_FILE_NAME 不太好用。 我已经尝试使用 cmake 3.4.3 和最新版本(在撰写本文时为 3.9.0),因为有一些建议 fixes to component based installs in 3.6.0

没有我在CPACK_PACKAGE_FILE_NAME中使用的CPACK_COMPONENT_DISPLAY_NAME这样的变量。 cmake 中还有一些东西会自动将组件名称添加到末尾。

很久以前就有一个关于 .deb 包的类似问题 here 但我宁愿尽可能避免这种复杂的解决方案。 生成后重命名包会更容易(但仍然感觉很老套)。

我也注意到包依赖set(CPACK_COMPONENT_bar_DEPENDS foo)没有记录在bar包中

更新:2017 年 8 月 1 日

我已经为 cmake here 添加了错误报告,因为我认为 CPACK_RPM_<component>_PACKAGE_FILE_NAME 的实现存在错误。至少文档没有足够的帮助。

首先在文档顶部有一个大注释:

Note

part of variables is preferred to be in upper case (for e.g. if component is named foo then use CPACK_RPM_FOO_XXXX variable name format) as is with other CPACK__XXXX variables. For the purposes of back compatibility (CMake/CPack version 3.5 and lower) support for same cased component (e.g. fOo would be used as CPACK_RPM_fOo_XXXX) is still supported for variables defined in older versions of CMake/CPack but is not guaranteed for variables that will be added in the future. For the sake of back compatibility same cased component variables also override upper cased versions where both are present.

因此,如果您有一个名为 foo、FOO、fOo 的组件...变量是 CPACK_RPM_FOO_...否则变量将被忽略 - 请注意,自 CPack 存在以来就是这种情况对于公共组件变量,例如CPACK_COMPONENT_foo_DESCRIPTION <- foo 部分必须大写。

在文件名旁边 - 在 CPack 3.6 之前,不可能更改文件名而不出现错误并且必须手动复制生成的包。从那个版本开始,您可以根据需要设置文件名或通过将 CPACK_RPM_FILE_NAMECPACK_RPM_<component>_FILE_NAME 设置为 RPM-DEFAULT 来请求平台特定的包名称(由 rpm 安装定义)。参见 https://cmake.org/cmake/help/v3.6/module/CPackRPM.html?highlight=cpack_rpm_file_name#variable:CPACK_RPM_FILE_NAME

另外 set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-comp${CPACK_COMPONENT_DISPLAY_NAME}-${CPACK_PACKAGE_VERSION}.i686") 也不起作用,因为 ${CPACK_COMPONENT_DISPLAY_NAME} 不是锚点,会在该位置自动替换 - 不是由您设置,因此替换文本是空字符串...因此,如果您真的想手动设置名称,您应该为每个组件设置与该变量 CPACK_RPM_<component>_FILE_NAME 等效的 RPM 打包程序(因此您需要一个 for 循环或更多的复制粘贴...) - 请注意,如前所述在文档中,文件名必须以 .rpm 结尾,默认为(从文档中复制)<CPACK_PACKAGE_FILE_NAME>[-<component>].rpm 所以这就是为什么组件部分总是放在最后的解释。

这里有很多针对不同 CPack 打包器的测试:https://github.com/Kitware/CMake/tree/master/Tests/RunCMake/CPack/tests 因此,您也可以探索这些片段。

P.S。随时欢迎对文档做出贡献:)