更改组件 RPM 的 cpack 生成名称

Posted

技术标签:

【中文标题】更改组件 RPM 的 cpack 生成名称【英文标题】:change cpack generated name for component RPMs 【发布时间】:2017-07-26 16:17:37 【问题描述】:

我正在尝试使用创建多个 RPM 文件的 cpack(通过 cmake)创建一个 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: 例如

>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_&lt;component&gt;_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 中的某些内容会自动将组件名称添加到末尾。

很久以前here 的 .deb 包也有类似的问题,但如果可能的话,我宁愿避免这种复杂的解决方案。 生成后重命名包会更容易(但仍然感觉很hacky)。

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

更新:2017 年 8 月 1 日

我已经为 cmake here 添加了一个错误报告,因为我认为 CPACK_RPM_&lt;component&gt;_PACKAGE_FILE_NAME 的实现中存在一个错误。至少文档没有足够的帮助。

【问题讨论】:

做debs的时候遇到这个问题。只是放弃了它并制作了一些 shell 脚本来修复名称并做一些其他棘手的事情。 你能用一个可行的解决方案来完成你的问题吗?我无法让我的代码工作,无论我用 CPACK_RPM_&lt;component&gt;_FILE_NAME 做什么,它一直在使用 RPM-DEFAULT(使用 CMake 3.13.0) 【参考方案1】:

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

注意

变量的一部分最好是大写的(例如,如果组件被命名为 foo 然后使用 CPACK_RPM_FOO_XXXX 变量名格式),就像其他 CPACK__XXXX 变量一样。出于向后兼容性的目的(CMake/CPack 版本 3.5 和更低版本),对于在旧版本 CMake/CPack 中定义的变量仍然支持相同的封装组件(例如,fOo 将用作 CPACK_RPM_fOo_XXXX),但不保证对于将将来会添加。为了向后兼容,相同大小写的组件变量也会覆盖两者都存在的大写版本。

因此,如果您有一个名为 foo、FOO、fOo... 的组件,则变量为 CPACK_RPM_FOO_... 否则这些变量将被忽略 - 请注意,自 CPack 开始存在公共组件变量以来就是这种情况,例如CPACK_COMPONENT_foo_DESCRIPTION

在文件名旁边 - 在 CPack 3.6 之前,无法更改文件名而不会出现错误并且必须手动复制生成的包。从那个版本开始,您可以根据需要设置文件名或通过将CPACK_RPM_FILE_NAMECPACK_RPM_&lt;component&gt;_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_&lt;component&gt;_FILE_NAME 等效的 RPM 打包程序(因此您需要一个 for 循环或更多的复制粘贴...) - 请注意,如文档中所述,文件名必须结束使用.rpm,默认是(从文档中复制)&lt;CPACK_PACKAGE_FILE_NAME&gt;[-&lt;component&gt;].rpm,所以这就是为什么组件总是放在最后的解释。

这里有很多针对不同 CPack 打包器的测试:https://github.com/Kitware/CMake/tree/master/Tests/RunCMake/CPack/tests 所以你也可以探索那些 sn-ps。

附:总是欢迎对文档的贡献:)

【讨论】:

由于与 CPACK_PACKAGE_FILE_NAME 混淆,我使用 CPACK_RPM_&lt;component&gt;_PACKAGE_FILE_NAME 而不是 CPACK_RPM_&lt;component&gt;_FILE_NAME(没有包!)。

以上是关于更改组件 RPM 的 cpack 生成名称的主要内容,如果未能解决你的问题,请参考以下文章

没有出现cmake / cpack组件的debuginfo rpm包

CPack 将系统目录添加到生成的 RPM

cpack 生成带有 %files 条目的 RPM,这些条目与 RPM 规范冲突。怎么修?

仅在 CPack 中将文件添加到 ARCHIVE 包

如何将变更日志添加到使用 CPack 创建的 RPM

cpack 组件安装不起作用