5

我正在开发一个多平台项目,该项目由在 Windows、Linux 和 Mac OSX 上运行的服务/守护程序组成。

我拥有的代码是可移植的,并且应用程序在所有系统上都可以正常运行(从命令行)。由于此应用程序设计为在后台运行,因此我将其设置为 Windows 上的 Windows 服务和用于 Linux 的 Linux 守护程序(在 init.d 中具有适当的脚本)。

现在我的问题是 Mac OSX:我对这个操作系统没有什么经验,而且我很难找出关于我的情况的最佳实践:

我想为我的项目安装一个安装程序(我相信一个 .dmg 文件,它可能会安装一个 .app;如果有更好的选择,请纠正我)。

这里有一些关于我的这个项目的信息:

  • 它完全用 C++ 构建(它使用 boost、curl、iconv)
  • 当前的构建系统不是 XCode(但是,如果有办法在将所有内容集成和构建到 XCode 中的同时保持我当前的代码布局,我不介意。无论如何我已经为 Windows 做了类似的事情)。
  • 没有图形用户界面
  • 守护程序应该在启动时自动启动(或者更好:让用户选择)。
  • 守护程序在执行期间需要 root 访问权限。

对于一个问题,这可能需要考虑很多上下文,因此我将尝试使其更易于阅读:

您将如何在 Mac OSX 上为纯 C++ 守护程序打包/创建安装程序?

4

3 回答 3

4

由于它没有 UI,我不会将其打包为 .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 的建议,您的包实际上应该包含“本地”目录(其中包含 libexec 子目录和您的二进制文件),并将其安装到 /usr 中——如果 /usr/local 已经存在,它只会与已经存在的东西合并,但如果不是,它会创建整个东西。另一方面,/Library/LaunchDaemons 保证存在,因此您的包只需要包含实际的 .plist 文件即可放入其中。

于 2013-11-08T16:59:39.630 回答
3

如果您要分发的不仅仅是一个命令行(例如,如果它具有需要随附的静态配置数据、图像、框架/dylib 等资源),则打包为 .app 是有意义的。

无论分发的究竟是什么,您都可以使用您已经拥有的工具创建安装程序 -pkgbuildproductbuild,两者都在 /usr/bin 中。使 OS X 安装程序包像 Pro - Xcode 开发人员 ID 就绪 pkg可以让您开始使用这些工具。

于 2013-11-08T15:05:40.310 回答
2

您是否查看过 Apple 提供的守护进程和服务编程指南?我认为这作为对平台的介绍非常有帮助,并且应该为您指明正确的方向(如果没有向您展示如何完全按照您的意愿行事)。

您还应该查看launchd(在该编程指南中进行了讨论)。launchd 是 OSX 的官方守护进程启动器/管理器,与操作系统高度集成。将现有的跨平台守护程序包装到已启动的守护程序中应该很容易,并且您可以与 OS X 集成,以便守护程序自动启动。

于 2013-11-08T14:50:32.133 回答