我正试图找到将图形化Qt应用程序分发给Mac用户的最佳方法。
我已经了解了pkgbuild,产品建设,并使用了带有.pkg扩展的创建平面包。
然而,当我试图在MacOSX10.11上安装这样一个扁平的软件包时,我看到了一些非常奇怪的行为。看起来这些包的Mac安装程序在我的主目录中搜索我要安装的应用程序。如果它在那里找到了应用程序,那么它实际上窃取了该应用程序,将这些文件的所有权更改为root,并且它无法将应用程序安装在我希望安装它的/Applications文件夹中。
预期的行为是,包应该始终将我的应用程序安装到/Applications目录中,并且不应该修改主目录中任何文件的所有权。
这看起来真的很奇怪。怎么回事,我怎么能修好它?平面包看起来不错,但我想保证它们总是在正确的位置安装应用程序,我不希望它们修改用户主目录中的文件。
重现问题的步骤
在主目录中安装自制软件。
运行brew install qt5安装Qt5。
使用以下三个文件创建一个新目录:
Info.plist.in
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>main</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<key>CFBundleIdentifier</key>
<string>com.example.abc.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>test thing</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>NSHumanReadableCopyright</key>
<string>public domain</string>
</dict>
</plist>main.cpp
#include <stdio.h>
int main(int argc, char *argv[])
{
(void)argc; (void)argv;
printf("hello\n");
return 0;
}test.sh
c++ -isystem ~/opt/qt5/lib/QtCore.framework/Headers \
~/opt/qt5/lib/QtCore.framework/QtCore \
main.cpp -o main
rm -rf "staging"
mkdir -p "staging/abc.app/Contents/"{MacOS,Resources}
cp main "staging/abc.app/Contents/MacOS/"
cp Info.plist.in "staging/abc.app/Contents/Info.plist"
"$(brew --prefix qt5)/bin/macdeployqt" "staging/abc.app"
pkgbuild --identifier com.example.abc.pkg \
--version 1.0.0 \
--root staging \
--install-location /Applications \
app.pkg现在,通过在终端中键入test.sh运行./test.sh。在我的计算机上,输出如下所示:
pkgbuild: Inferring bundle components from contents of staging
pkgbuild: Adding component at abc.app
pkgbuild: Adding component at abc.app/Contents/Frameworks/QtWidgets.framework
pkgbuild: Adding component at abc.app/Contents/Frameworks/QtGui.framework
pkgbuild: Adding component at abc.app/Contents/Frameworks/QtCore.framework
pkgbuild: Adding component at abc.app/Contents/Frameworks/QtPrintSupport.framework
pkgbuild: Wrote package to app.pkg(显然,pkgbuild正在检测我的暂存文件夹中的组件。我希望它不会那样做。我希望它能简单地将所有这些文件安装到用户的/Applications目录中。如果仅仅因为这些文件有Info.plist文件而对它们进行特殊处理,这可能是件坏事。)
接下来,通过运行open app.pkg并按照屏幕上的GUI安装包:

运行ls /Applications/abc.app,您可以看到应用程序没有安装在预期的位置。
运行ls -l staging或find . -uid root,您可以看到staging/abc.app中的文件现在都是根用户拥有的,这是意外的。
现在用sudo rm -rf staging删除暂存目录。再试一次安装软件包。这一次,由于安装程序没有在我的主目录中找到应用程序,它已经成功地将其安装到/Applications中。
备选方案
我不想只将.app文件夹打包到.dmg文件中,因为我的应用程序实际上有一个图形用户界面和一个命令行组件,而且使用该方法很难将命令行组件放到用户的路径上。使用平面包,我可以通过向/etc/paths.d添加一个文件,轻松地将命令行组件放到路径上。
是否有更好的工具来创作Mac平台包?
pkgbuild的源代码可用吗?这样我就可以知道它在做什么了吗?
我可能会尝试这个答案中描述的更复杂的过程,看看这是否有帮助。
发布于 2016-02-16 01:09:06
这是我找到的一个解决办法。我不确定它是否是最佳的,但它似乎是可行的。
首先,生成一个空的组件列表:
pkgbuild --analyze zzz --root nocomponents.plist(即使zzz目录不存在,此命令实际上仍然成功。)
稍后,在构建包时,将此选项提供给pkgbuild
--components-plist nocomponents.plisthttps://stackoverflow.com/questions/35421273
复制相似问题