在Mac OSX上,如何打包C++守护进程的推荐方法是什么?

6
我正在开发一个多平台项目,包括在Windows、Linux和Mac OSX上运行的服务/守护程序。
我的代码是可移植的,应用程序在所有系统上都可以通过命令行运行。由于该应用程序设计为在后台运行,因此我将其作为Windows服务运行,并在Linux上创建了守护进程(使用适当的init.d脚本)。
现在我的问题是Mac OSX:我对这个操作系统的经验很少,而且我很难找出最佳实践方法:
我想为我的项目制作一个安装程序(我相信是一个.dmg文件,可能会安装一个.app文件;如果有更好的选择,请纠正我)。
以下是关于这个项目的一些信息:
- 它完全基于C++构建(使用boost、curl、iconv)。 - 当前的构建系统不是XCode(但是如果有办法将当前的代码结构保持不变并集成和构建到XCode中,我不介意。我已经在Windows上做过类似的事情)。 - 没有图形用户界面。 - 守护程序应自动启动(或者更好的是:让用户选择)。 - 守护程序在执行过程中需要root权限。
这可能是要考虑的很多上下文信息,所以我会尽量让它更容易阅读:
如何在Mac OSX上打包/创建一个纯C++守护程序的安装程序?

如果你能阅读法语,这里有一篇非常好的博客文章,完美地回答了我所有的问题。 - ereOn
文章也可在此链接中阅读 - https://vincent.bernat.ch/en/blog/2013-autoconf-osx-packaging - Murukan
3个回答

4
由于这个程序没有用户界面,因此不应将其打包成 .app 文件 -- 这是适用于双击可执行的 GUI 应用程序的首选格式,而不是针对守护进程。如果只有一个二进制文件(除了配置文件等支持文件),我会遵循 Unix 约定,将二进制文件放在 /usr/local/libexec 这样的地方(或者您在 Linux 上的其他地方)。请注意,/usr/local 在 OS X 上默认不存在,因此如果不存在,则需要您的安装程序创建它。
关于如何让其执行:我会同意 James Bedford 的建议,使用 launchd。launchd .plist 文件应安装在 /Library/LaunchDaemons 中(LaunchDaemons 在启动时以 root 身份运行,而 LaunchAgents 在用户登录时作为普通用户运行)。确保守护进程不会自动进入后台 -- launchd 会监视其启动的程序,如果它们进入后台,它会认为它们已崩溃,并尝试重新启动它们,这并不是很好。您可以调整设置以处理后台程序,但最好让它在前台运行。
关于打包:在这里,我同意 mah 的看法 -- 使用安装程序包。实际上,我仍然喜欢旧的 GUI PackageMaker 工具(虽然已被弃用,但它仍然有效),但新的 CLI 工具在这一点上可能更好。如果您遵循我关于 /usr/local/libexec 的建议,那么您的包实际上应该包含 "local" 目录(带有 libexec 子目录和其中的二进制文件),并将其安装到 /usr 中 -- 如果 /usr/local 已经存在,则它只会与已经存在的内容合并,但如果不存在,则会创建整个目录。另一方面,/Library/LaunchDaemons 可以保证存在,因此您的包只需要包含要放置在其中的实际 .plist 文件即可。

非常感谢您,@Gordon。当您提到“新的CLI工具”时,您是指pkgbuild吗?此外,是否有关于如何嵌入所依赖的库的指南?(例如boost和curl,我基本上是从homebrew中获取的。我应该自己编译它们吗?) - ereOn
1
对于 pkgbuild,是的。至于嵌入库,我的第一个想法是将它们静态链接,这样它们就被嵌入到可执行文件中,不会有问题。如果它们需要动态链接,我不确定最好的捆绑方式是什么。您需要编译它们并与可执行文件一起分发,因为 OS X 不包括编译器(除非您安装了一个)。我会倾向于在 /usr/local/libexec 下创建一个子目录,并将所有部件放在那里,但这并不是非常干净或标准的做法。 - Gordon Davisson
苹果的文档还建议将守护进程可执行文件安装到 /usr/local/libexec 目录下:https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7-104142-BCICCCFI - freshtop

3
将程序打包成.app格式有一定的意义,如果你要分发的内容不仅仅是一个命令行(例如,它包含资源,如静态配置数据、图像、框架/动态链接库等),则需要将这些资源一并打包。

无论要分发的内容是什么,你都可以使用已有的工具来创建安装程序——pkgbuildproductbuild,它们都在/usr/bin中。 通过Making OS X Installer Packages like a Pro - Xcode Developer ID ready pkg 熟悉这些工具以便更好地使用它们。

2
你看过苹果提供的《守护进程和服务编程指南》了吗?我觉得作为平台介绍,这本书会非常有帮助,而且应该能够指引你朝着正确的方向前进(如果不能满足你的需求,至少也能告诉你如何实现)。
此外,你还应该查看一下launchd(在那本编程指南中有讨论)。launchd是OSX的官方守护进程启动器/管理器,并与操作系统紧密集成。将你现有的跨平台守护进程包装成一个launched守护进程应该很容易,而且你可以与OS X集成,使守护进程能够自动启动。

谢谢你。确实很有帮助!(加一分)你有关于打包部分的信息吗?我应该把它做成一个.app文件吗?如果是这样,怎么做呢? - ereOn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接