Пакет Mac OS X изменяет файлы в моем домашнем каталоге вместо установки в приложения

Я пытаюсь найти лучший способ распространения графического приложения Qt среди пользователей Mac OS X.

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

стандартный интерфейс для Mac OS X плоский пакет

Бежать 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 доступно, чтобы я мог понять, что он делает?

Я мог бы попробовать более сложную процедуру, описанную в этом ответе, чтобы посмотреть, поможет ли это.

1 ответ

Вот одно решение, которое я нашел. Я не уверен, что это оптимально, но, похоже, работает.

Сначала создайте пустой список компонентов:

pkgbuild --analyze zzz --root nocomponents.plist

(Эта команда на самом деле успешно, хотя zzz Каталог не существует.)

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

--components-plist nocomponents.plist
Другие вопросы по тегам