CMake - 如何在打包期间阻止执行安装脚本?

Posted

技术标签:

【中文标题】CMake - 如何在打包期间阻止执行安装脚本?【英文标题】:CMake - how to block executing installation scripts during packaging? 【发布时间】:2018-09-13 23:46:29 【问题描述】:

我的CMakeLists.txt 文件包含命令,应该由make install 执行,所有这些都可以正常工作。下面的示例 CMakeLists.txt 是我实际 CMake 文件的简短摘录(tm0001.cpp 的内容在这里并不重要 - 它可能是任何 C++ 程序):

cmake_minimum_required(VERSION 3.12)

project(tm0001)

set(CMAKE_CXX_STANDARD 11)
add_executable($PROJECT_NAME tm0001.cpp)

install(
  TARGETS $PROJECT_NAME
  DESTINATION /usr/local/bin
  PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)

install(CODE "message(\"-- This must be called during installation only\")")

set(CPACK_PACKAGE_CONTACT "HEKTO")
set(CPACK_GENERATOR "DEB")
include(CPack)

我看到message 命令也是由make package 执行的,这不是我想要的。

如何通过make package 命令告诉CMake 执行安装脚本?我找不到使用 CMake if 命令的任何方法。

【问题讨论】:

您能否提供一个最小的CMakeLists.txt 来重现问题? @compor - 完成,谢谢 从打包者的角度来看,我认为在安装包时更改系统状态是个坏主意。也许改为添加一条消息,管理员应该重新启动守护程序。 【参考方案1】:

正如评论中已经说过的那样,通过install 命令“使用systemd”(并执行与项目的构建或打包无关的任何事情)是一个非常糟糕的主意。 install 命令(甚至是SCRIPTCODE 签名)旨在用于安装操作,而不用于任何其他副作用

此处的正确做法是生成带有安装后脚本的本机软件包 (DEB/RPM),其中使用系统提供的宏(如 here 所述),您可以正确安装软件包。查看CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA 提供包安装操作的方式。

另一个坏事是使用硬编码路径 (/usr/bin/)。顺便说一句,我建议/usr/sbin/ 为(纯)守护程序应用程序提供更好的地方。查看GNUInstallDirs 模块附带 CMake 以获取更多参考。

【讨论】:

我问的是 CMake onlysystemctl 调用只是一个示例。实际上,我在安装过程中通过cmakedpkg 做了很多不同的事情——但我不想在打包过程中做这些事情。如果 CMake 不能做到这一点,那是 CMake 的问题,但不是我的问题。 /usr/bin 目录用法也是一个例子,我可以使用任何其他目录。 重点是不要做任何与 CMake 配置中的构建或打包过程无关的事情。将你的 很多不同的东西 移动到一些帮助脚本或其他任何东西——它不是你项目的一部分,显然,它应该是你的包的安装后操作。如果您在本地执行sudo make install,只需在...之后执行sudo ./run-post-install.sh 并将这些操作也包含到Debian 控制文件中。但是,真正的方法是在您不需要在本地 make install 时设计您的项目! :) 是的,这不是你的问题......这是你对开发过程的理解的问题(w/ CMake %)。可能我可以猜到将 CPack 执行的 make install 与手动执行区分开来的方法,但它将基于实现细节,因此不能被视为解决由于 CMake 的奇怪使用而引发的问题的可靠解决方案%) 我从这次谈话中得出的结论是,CMake 不允许目标 installpackage 很好地共存 nice的事情,一切都会nice :) -- 做dirty的事情......你知道 % ) 对我来说,这两个目标在相当复杂的项目中可以很好地共存。【参考方案2】:

我所做的是将带有 CODE/SCRIPT 的安装命令指定为单独的组件,例如安装(代码 ... 组件安装后)。

然后还添加了其他非代码安装命令作为不同的组件,例如安装(文件...组件文件-安装)

然后需要将 CPack 配置为仅打包文件-安装组件(此问题的解决方案很容易找到 - 提示:使用 CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE、CPACK_COMPONENTS_ALL 和 CPACK_(RPM/DEB/...)_COMPONENT_INSTALL 变量)。

当然,生成的包在安装包期间不会运行这些 CODE 组件 - 它们需要作为安装后脚本单独添加。

【讨论】:

【参考方案3】:

我正在回答我自己的问题,因为现有答案没有解决我的主要问题。我找不到任何方法(在 CMake 级别上)阻止 install 命令在 make package 期间运行 - 甚至 postinst 脚本也被此命令调用。

幸运的是,我可以修改 postinst 脚本本身,使其不做任何事情,以防它被 不是由 dpkg 调用:

if [ -z $DPKG_ADMINDIR ]; then
  echo "postinst: missing 'dpkg' environment (not an error during packaging)"
  exit 0
fi

这当然是个技巧,但它对我有用。

【讨论】:

以上是关于CMake - 如何在打包期间阻止执行安装脚本?的主要内容,如果未能解决你的问题,请参考以下文章

防止 cmake 运行 cpack

如何在不再次运行配置脚本/cmake 的情况下修改安装路径

如何安装Cmake3.11.3-win32-x86

iOS使用Jenkins自动打包发布测试

安装 CMake 组件时如何获取将要安装的文件列表

如何执行PHP脚本