systemd - 使用 autotools 安装 systemd 服务
问题描述
我有一个自动工具项目,它成功地构建和测试了一个应用程序(https://github.com/goglecm/AutoBrightnessCam)。该应用程序安装在 bin 目录中(前面有用户指定的任何前缀)。这很简单。我现在需要创建一个 systemd 服务以在启动时启动它。我已经创建了服务文件并手动运行它,它工作正常。
最后一点是告诉 configure.ac 和 Makefile.am 用应用程序的正确路径修补 *.service.in 文件(就像 config.h 是从 config.h.in 创建的)。
使用 AC_CONFIG_HEADERS 是否适合将 *.service.in 修补到 *.service 中?也许还有另一个用于“非标题”的宏?
另外,我如何指定服务文件应该登陆(即安装)在/etc/systemd/system 中?
有没有更好的方法在没有 systemd 的情况下在启动时启动这个应用程序?
解决方案
如何指定服务文件应该登陆(即安装)在 /etc/systemd/system 中?
根据 Systemd 的daemon
手册页:
<开始报价>
安装 systemd 服务文件
在构建安装时(例如make install
,在包构建期间),建议将包安装在pkg-config systemd --variable=systemdsystemunitdir
(用于系统服务)或pkg-config systemd --variable=systemduserunitdir
(用于用户服务)返回的目录中的 systemd 单元文件。这将使系统中的服务在明确请求时可用,但不会在引导期间自动激活它们。可选地,在软件包安装期间(例如rpm -i
由管理员),应通过该systemctl(1)
工具的 enable 命令在 systemd 配置目录中创建符号链接,以便在启动时自动激活它们。
建议使用的包使用autoconf(1)
如下配置脚本摘录来确定源配置期间的单元安装路径:
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([systemdsystemunitdir],
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
[with_systemdsystemunitdir=auto])
AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
AS_IF([test "x$def_systemdsystemunitdir" = "x"],
[AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
[AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
with_systemdsystemunitdir=no],
[with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
[AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
这个片段允许在 systemd 机器上自动安装单元文件,并且即使在缺少 systemd 的机器上也可以选择允许它们安装。(用户单元目录的这个片段的修改留给读者练习。)
此外,为确保 make distcheck 继续工作,建议在基于项目的顶级Makefile.am
文件中添加以下内容:automake(1)
AM_DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
最后,单元文件应该安装在系统中,并带有如下的 automake 摘录:
if HAVE_SYSTEMD
systemdsystemunit_DATA = \
foobar.socket \
foobar.service
endif
...
</ENDQUOTE>
所以看起来你应该使用systemdsystemunitdir
and systemduserunitdir
。Autotools 对它的支持如何,嗯...
在 Fedora 31 上使用快速 grepgrep systemdsystemunitdir /bin/autoconf
并grep -IR systemdsystemunitdir /usr/share
显示尚不支持 Autotools。7年了,还在继续……
有没有更好的方法在没有 systemd 的情况下在启动时启动这个应用程序?
Systemd 应该可以启动您的应用程序。只需systemctl(1)
像往常一样使用来启用和启动它们。
根据您的GitHub 和autobrightnesscam.service.in
,我不会为此使用 Autotools。您可能会浪费大量时间来解决 Autotols 的缺点(根据经验)。
我的configure.ac
脚本(这只是一个 shell 脚本)将复制autobrightnesscam.service.in
到autobrightnesscam.service
,然后用于sed
复制正确的目录和文件。然后,我会将更新autobrightnesscam.service
的内容复制到AC_CONFIG_COMMANDS_POST
. 也许是这样的:
SERVICE_FILE=autobrightnesscam.service
SYSTEMD_DIR=`pkg-config systemd --variable=systemdsystemunitdir`
# Use default if SYSTEMD_DIR is empty
if test x"$SYSTEMD_DIR" = "x"; then
SYSTEMD_DIR=/etc/systemd/system
fi
AC_CONFIG_COMMANDS_POST([cp "$SERVICE_FILE" "$SYSTEMD_DIR"])
AC_CONFIG_COMMANDS_POST([systemctl enable "$SYSTEMD_DIR/$SERVICE_FILE"])
AC_CONFIG_COMMANDS_POST([systemctl start "$SERVICE_FILE"])
推荐阅读
- c# - MailKit 日志文件为空
- java - Spring Security 允许未经授权的请求
- php - 如何在 wordpress 用户表中添加自定义数据
- android - 在分屏的第一个窗口中启动外部应用程序
- node.js - 如何将图像插入 CouchDB
- php - 为什么我的 post 方法在 Laravel 中不起作用?
- vue.js - VueJS 模板中的元素引用 self
- python - 在 Python Socket 上通过 TCP 将 txt 文件发送到服务器
- python-3.x - python从给定位置的字符串中删除字符串
- node.js - NestJS - 每个模块使用多个 MongoDB 连接