有没有一种惯用的方法可以使用 setuptools 安装 systemd 单元?

Is there an idiomatic way to install systemd units with setuptools?

我正在分发一个可以导入并用作库的模块。它还附带一个可执行文件——通过 console_scripts 安装——供人们使用。

该可执行文件还可以作为系统服务 (Type=simple) 启动,为系统提供守护进程。

systemd 服务需要在它们的 ExecStart 行中引用 绝对路径 ,所以我需要弄清楚 console_script 安装到哪里。

使用 CMake、autotools 或 Meson 等其他构建系统,我可以直接访问前缀,然后使用 configure_file(介子)之类的东西替换 foo.service.in 中的 @PREFIX@,并且然后将生成的单元安装到 $prefix/lib/systemd/system/.

我只是想不出如何使用设置工具来做到这一点。在 setup.py 中,sys.prefix 设置为 python 的前缀 ,这不是一回事。我尝试过覆盖 install_datainstall,但这些方法都有各种问题,例如在通过 pip 构建轮子时损坏,或者在卸载时留下文件。 (当我们没有在系统范围内安装时,我可以不安装服务;如果前缀不是 /usr/usr/local,systemd 将无法找到它。)

有人指点我at a website which says that you're not supposed to do this with setuptools:

Note, by the way, that this encapsulation of data files means that you can't actually install data files to some arbitrary location on a user's machine; this is a feature, not a bug.

这听起来好像我只是违背了这里的原则。我真的在寻找指示或示例来告诉我我应该在这里做什么。如果那是 "don't use setuptools",很好 - 但欢迎就首选的东西提出建议。

我会说不要为此使用 setuptools,这不是它的用途。而是使用目标发行版的包管理器(apt、rpm、flatpak、pacman、snap 等)。

我相信 systemd 以及特定于操作系统的东西(Linux 发行版,Linux init system) 超出了 Python 打包、pipsetuptools 等的范围。尽可能合理地保留在 setuptools 的职责,以便项目保持 pip-installable,并且项目本身提供了访问 [=24= 的简单方法]systemd 特定文件但不安装它们(例如,可能使用命令 my-thing-generate-systemd-files --target path/to/output,这将简化项目用户的任务)。另一方面,提供 Linux-特定于发行版的包(deb、rpm 等),如果我没记错的话,有一些工具可以从 Python 项目开始构建此类包(a sdist 或源代码库)。

一些想法(未经测试的快速搜索,不是推荐):