【问题标题】:cpack conditonal behaviour based on generator基于生成器的 cpack 条件行为
【发布时间】:2020-08-26 22:16:06
【问题描述】:

我有一个构建,当前设置的步骤如下:

cmake
make
cpack -G TGZ
cpack -G RPM

我现在有一个问题,我希望将一些文件包含在 RPM 中,但不包含在 tarball 中。有没有办法根据使用的生成器使安装命令有条件?

简单明了的方法是错误的:

if (NOT ${PACKAGE_TYPE} STREQUAL "TGZ")
   message("HELLO ${PACKAGE_TYPE}")
   install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/foobar DESTINATION "/usr/lib" COMPONENT core RENAME "/usr/lib/only-install-me-for-RPM")
endif()

我认为这是错误的,因为配置阶段(运行 cmake)会评估条件,但 cpack 不会。 我不想要两个版本,因为安装阶段是唯一不同的部分。我确实想要不止一种安装包。

背景

我为什么要做这么奇怪的事情?我可以想到其他合理的原因,但在这种情况下是因为引入了/usr/lib/.build-id。 无法从 cmake 禁用此行为(尽管可以在 .spec 文件中查看 https://bugzilla.redhat.com/show_bug.cgi?id=1724153

在 RHEL8 中,rpmbuild 在 /usr/lib/.build-id 中安装文件(实际上是链接),我自己没有具体说明。 为了说服 cmake 使 /usr/lib 可重定位,我必须在 /usr/lib 中安装一个虚拟文件 - 请参阅 https://gitlab.kitware.com/cmake/cmake/-/issues/20691

这对于 tarball 来说不是必需的。

【问题讨论】:

  • 事实证明我可以使用 set(CPACK_RPM_SPEC_MORE_DEFINE "%define _build_id_links none") 在 RPM 规范中禁用 .build-id 来解决我的问题,但如何以其他方式执行此操作的问题仍然存在.
  • 不是答案,因为我不知道 cmake,但传统上你需要在规范文件中添加额外的“源”行,eg Source1: myfile.txt跨度>

标签: cmake rpmbuild cpack


【解决方案1】:

当前使用的 CPack 生成器可以从 CPACK_GENERATOR 变量中检索。但这种含义仅适用于使用CPACK_PROJECT_CONFIG_FILE 变量指定的脚本。在CMakeLists.txt 内部,变量CPACK_GENERATOR 有其他含义。

因为install 命令只能在CMakeLists.txt 中发出,所以这个命令不能是有条件的(基于CPack 生成器)。但是您可以为此安装分配一个COMPONENT。以后可以将该组件从组件列表中排除。

CMakeLists.txt

# Assign 'core_special' COMPONENT for installation
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/foobar DESTINATION "/usr/lib" COMPONENT core_special RENAME "/usr/lib/only-install-me-for-RPM")

# ...

# Set config script for CPack. 
set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_SOURCE_DIR}/cpack_project_config.cmake")

cpack_project_config.cmake

# Exclude component "core_special" for all CPack generators except TGZ.
if (NOT CPACK_GENERATOR STREQUAL "TGZ")
  list(REMOVE_ITEM CPACK_COMPONENTS_ALL "core_special")
endif()

# Need to set 'CMAKE_<GENERATOR>_COMPONENT_INSTALL' to ON, otherwise CPack ignores CPACK_COMPONENTS_ALL variable
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_RPM_COMPONENT_INSTALL ON)

# E.g create single archive/package from all components
# (other values - "IGNORE", "ONE_PER_GROUP" - will also work)
set(CPACK_COMPONENTS_GROUPING "ALL_COMPONENTS_IN_ONE")

【讨论】:

  • 这看起来有道理但很痛苦(以 cmake 通常的方式)。如果您已经在使用组件安装,我不确定它是否会正常运行。额外的文件将在一个单独的可选组件中,而不是在同一个文件中,不是吗?我想你是在确认我想做的事情是不可能的?
  • "额外的文件将在一个单独的可选组件中,而不是在同一个文件中,不是吗?" - 如果您不使用按组件安装,那么CPACK_COMPONENTS_ALL 将描述进入结果文件的所有组件。额外的文件(不适合列出的组件)将无处可去。据我了解,这正是您想要的。
  • 不幸的是,我确实使用了按组件安装,但您的解决方案看起来很适合单组件情况。
  • 我刚刚在不同的修改中测试了我的方法。一旦 CMAKE_<GENERATOR>_COMPONENT_INSTALL 变量设置为 ON,CPack 将遵循设置 CPACK_COMPONENTS_ALL 变量。也就是说,删除的组件既不会出现在 ALL_COMPONENTS_IN_ONE 包中,也不会在“IGNORE”情况下生成每个组件的包。 (如果 ONE_PER_GROUP 包是基于 groups 列表创建的。如果两个组都不包含已删除的组件,则也不会为该组件生成任何文件。)
猜你喜欢
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多