2016-02-15 13 views
2

Я пытаюсь выяснить, лучший способ распространения графического 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 и следуя инструкциям на экране графического интерфейса пользователя:.

standard UI for Mac OS X flat package

Запустите 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, чтобы узнать, помогает ли это.

+0

Вы проверили, поддерживает ли внешняя оболочка cmake внешнюю оболочку в pkg? cmake + Qt работают очень хорошо вместе (я отдал материал qmake) – bibi

+0

Я нашел поддержку пакета Mac Mac для Mac, чтобы быть раздражающим, поэтому я просто делаю сам пакет, используя простой сценарий оболочки. Во всяком случае, мой вопрос был больше о том, как работают пакеты Mac OS X. CMake отлично работает с Qt. –

+0

OS X не любит несколько копий одного и того же приложения с тем же URI и номером версии, что и [здесь] (http://stackoverflow.com/questions/33204293/services-menu-launches-wrong-application-bundle/33211493 # 33211493). Используя приложение «Консоль», просмотрите журнал установщика при запуске установки, и он покажет вам, что он делает. Вероятно, вы увидите, что он уже знает о присутствии приложения в вашей системе, поэтому не будет установлен в/Applications. – TheDarkKnight

ответ

0

Вот одно из решений, которое я нашел. Я не уверен, насколько он оптимален, но он работает.

Во-первых, создавать пустой список компонентов: (. Эта команда на самом деле преуспевает, даже если каталог zzz не существует)

pkgbuild --analyze zzz --root nocomponents.plist 

Позже, когда вы строите свой пакет, поставку этой опцион pkgbuild:

--components-plist nocomponents.plist