Я пытаюсь выяснить, лучший способ распространения графического Qt приложения для пользователей Mac OS X.Mac OS X пакет изменяет файлы в моем домашнем каталоге, вместо установки Приложения
я узнал о pkgbuild, productbuild, и использовали их до create flat packages с расширением .pkg
.
Тем не менее, я вижу очень странное поведение, когда пытаюсь установить такой плоский пакет на Mac OS X 10.11. Похоже, что установщик Mac OS X для этих пакетов ищет мой домашний каталог для приложения, которое я пытаюсь установить. Если он находит приложение там, то он фактически крадет это приложение, меняя права собственности на эти файлы на root, и он не может установить приложение в папку /Applications
, где я хотел, чтобы он был установлен.
Ожидаемое поведение заключается в том, что пакет должен всегда устанавливать мое приложение в каталог /Applications
и не должен изменять права собственности на любые файлы в моем домашнем каталоге.
Это кажется действительно странным. Что происходит и как я могу это исправить? Плоские пакеты кажутся приятными, но я хочу гарантировать, что они всегда устанавливают приложение в нужное место, и я не хочу, чтобы они изменяли файлы в домашнем каталоге пользователя.
Шаги по воспроизведению проблемы
Установите Homebrew в вашем домашнем каталоге.
Запустить 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
и следуя инструкциям на экране графического интерфейса пользователя:.
Запустите ls /Applications/abc.app
, и вы увидите, что приложение не было установлено в ожидаемом месте.
Запустите ls -l staging
или find . -uid root
, и вы увидите, что файлы в staging/abc.app
теперь принадлежат владельцам root, что является неожиданным.
Теперь удалите промежуточную директорию с sudo rm -rf staging
. Попробуйте снова установить пакет. На этот раз, поскольку установщик не нашел приложение в моем домашнем каталоге, он успешно установил его на /Applications
.
Альтернативы
Я не заинтересован в просто упаковывать папку .app
в .dmg
файл, потому что мое приложение будет на самом деле имеет графический интерфейс и компоненты командной строки, и было бы трудно получить компонент командной строки на путь пользователя с помощью этого метода. С помощью плоских пакетов я могу легко получить компонент командной строки на пути, добавив файл в /etc/paths.d
.
Есть ли более эффективные инструменты для разработки плоских пакетов Mac OS X?
Доступен ли исходный код pkgbuild
, чтобы я мог выяснить, что он делает?
Я могу попробовать более сложную процедуру, описанную в this answer, чтобы узнать, помогает ли это.
Вы проверили, поддерживает ли внешняя оболочка cmake внешнюю оболочку в pkg? cmake + Qt работают очень хорошо вместе (я отдал материал qmake) – bibi
Я нашел поддержку пакета Mac Mac для Mac, чтобы быть раздражающим, поэтому я просто делаю сам пакет, используя простой сценарий оболочки. Во всяком случае, мой вопрос был больше о том, как работают пакеты Mac OS X. CMake отлично работает с Qt. –
OS X не любит несколько копий одного и того же приложения с тем же URI и номером версии, что и [здесь] (http://stackoverflow.com/questions/33204293/services-menu-launches-wrong-application-bundle/33211493 # 33211493). Используя приложение «Консоль», просмотрите журнал установщика при запуске установки, и он покажет вам, что он делает. Вероятно, вы увидите, что он уже знает о присутствии приложения в вашей системе, поэтому не будет установлен в/Applications. – TheDarkKnight