Разпространяване на направени с Qt програми за macOS

Страницата е създадена на:15 април 2019 и редактирана на:31 януари 2021

В macOS след компилиране на направена с Qt програма се създава приложен пакет (bundle) - директория с разширение .app. Ако веднага копирате този пакет на друг компютър, на който няма инсталирана Qt, програмата няма да работи, защото изпълнимият файл, който се намира в приложния пакет, използва библиотеки от директорията с Qt.

Възможни са два начина за решаване на този проблем.
Първият - да се компилира програмата до статичен файл, който включва в себе си и функциите от библиотеките и при работата си не се обръща към тях. За целта трябва да имате статично компилирана Qt библиотека.
Вторият - да се предоставят заедно с приложния пакет и необходимите за работата му библиотеки. И двата начина са описани в документацията на адрес:

Qt for macOS | Qt 6.0
https://doc.qt.io/qt-5/macos-deployment.html

Ще опиша втория от тези начини.

От версия 4.5.0 на Qt заедно с библиотеките се предоставя и програмата macdeployqt, която извършва автоматично копиране на библиотеките в изпълнимия пакет. macdeployqt се намира в поддиректория bin на директорията с Qt. За да може лесно да я викате може да добавите bin директорията на Qt в променливата PATH.

След като сте компилирали до изпълним пакет програмата си, отворили сте Terminal и сте направили текуща, директорията с изпълнимия пакет, подайте команда:

macdeployqt MyProg.app

където MyProg.app е изпълнимият пакет на вашата програма.

Проблем с неподписани от регистриран програмист програми

Версия на macOS 10.15 - Catalina демонстрира нова политика на Apple по отношение на нерегистрираните в тяхната система програмисти. По подразбиране операционната система е настроена да изпълнява само свалени от App Store програми, а с промяна на съответна настройка (Вижте: Safely open apps on your Mac), може да се позволи стартиране и на изтеглени от други сайтове програми, но само подписани електронно от регистрирани програмисти. Така се ограничава силно стартирането на неподписани от регистрирани програмисти програми. Последното може да се случи само след изключване с команда от терминал на системата за сигурност (How to open apps from unidentified developers on Mac in macOS Catalina), което, разбира се, никак не се препоръчва.

Изводът е, че за да правите програми за Mac, трябва да сте регистриран в системата на Apple програмист (Apple Developer Program) и да подписвате своите програми. Последното е задължително при качване на програми в App Store, от където потребителите могат най-лесно да ги свалят и стартират. Ако сложите за теглене програма на друг сайт, то тя трябва да е подписана с получен от Apple сертификат и ще може да се стартира, ако потребителят позволи в системата да се стартират такива програми. Иначе, неподписана програма могат да стартират само потребители, които знаят как да изключат системите за сигурност на компютрите си. Генерирането и свалянето на сертификати за подписване се извършва с Xcode.

Инструментът macdeployqt на Qt има опция -codesign за подписване, с която се задава името на сертификата, съхраняван в KeyChain:

macdeployqt foo.app -codesign=MyCertificate

Името на сертификата трябва да се види в KeyChain. (macos - how to use the macdeployqt -codesign option with Qt 5.4.1 - Stack Overflow).

Относно регистрирането на програми iTunes Connect: Registering Products in App Store | Qt Purchasing 5.13.2.

Преместване, карантина

От версия 10.12 Sierra до версия 10.14 Mojave на macOS за изтеглени от Интернет приложения се прилага мярка за сигурност - преместване или поставяне в карантина. (Вижте: https://lapcatsoftware.com/articles/app-translocation.html и https://derflounder.wordpress.com/2012/11/20/clearing-the-quarantine-extended-attribute-from-downloaded-applications/) Когато потребителят стартира изтеглено от Интернет приложение, което не е подписано от регистриран в Apple програмист, системата автоматично създава достъпен само за четене образ на диск в директория /private/var/folders/.../AppTranslation/, копира изпълнимия пакет на приложението в него и го стартира от там. Проблем възниква при програми, които са придружени и се нуждаят за нормалната си работа от файлове, разположени извън .app пакета. Такива програми може да не открият, файловете от които се нуждаят.

За да не се извърши преместване трябва да се премахне атрибутът com.apple.quarantine от файловете в изпълнимият пакет на приложението, което се извършва от потребителя с команда от терминал:

sudo xattr -r -d com.apple.quarantine пътДо/имеНаПакет.app

(Прочетено от: https://derflounder.wordpress.com/2012/11/20/clearing-the-quarantine-extended-attribute-from-downloaded-applications/)


 

Това, което прави програмата macdeployqt, преди създаването й се правеше ръчно. Ако ви е интересно, ето как:

Структурата на приложния пакет на дадена програма може да разгледате като го отворите с Finder. Щракнете с десния бутон на мишката върху името на пакета и изберете от изскачащото меню Show Package Contents. Отваря се прозорец на Finder, в който се вижда една директория Contents. Тази директория винаги съдържа поддиректория MacOS, в която се намира изпълнимия файл на програмата, както и други поддиректории и файлове.

Директорията, в която трябва да се намират библиотеки е с име Frameworks и е поддиректория на Contents. Ако в приложният пакет на Вашата програма няма поддиректория Frameworks, създайте такава. Може да го направите от прозореца на Finder като щракнете десния бутон на мишката, изберете New Folder и зададете име Frameworks на новата директория.

За да откриете от кои библиотеки на Qt се нуждае Вашата програма, отворете Terminal, с команда cd отидете в директорията, в която се намира изпълнимия пакет и ако името на програмата е например MyProg подайте команда:

otool -L MyProg.app/Contents/MacOS/MyProg

Показват се имената на необходимите библиотеки. Обърнете внимание кои от тях са от директория /usr/local/Trolltech/Qt-4.5.3/lib. Това са библиотеките, които трябва да копирате в директория MyProg.app/Contents/Frameworks. Може да го направите с Finder или с команда от терминала. Например, за да копирате библиотеката QtGui, подайте от терминала команда:

cp -R /usr/local/Trolltech/Qt-4.5.3/lib/QtGui.framework MyProg.app/Contents/Frameworks

Аналогично копирайте и останалите библиотеки.

Само копирането на библиотеките в приложния пакет не е достатъчно. Необходимо е още да се укажат новите им места във всички файлове с обектен код, от които стават обръщания към тях т.е. в изпълнимия файл на програмата и в самите библиотеки (защото функциите в някои от Qt библиотеките се обръщат към други Qt библиотеки). Например, за да се насочи изпълнимия файл на програмата MyProg към новото място на библиотеката QtCore се подава команда install_name_tool -change:

install_name_tool -change

/usr/local/Trolltech/Qt-4.5.3/lib/QtCore.framework/Versions/4/QtCore

@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore

MyProg.app/Contents/MacOs/MyProg

За яснота, тук командата е показана на три реда, но в действителност се пише на един ред. Командата приема три, отделени с интервали, параметри: името на библиотека, което трябва да бъде сменено; новото име, което трябва да получи тази библиотека и името на файла с обектен код, в който се прави смяна на имената.

Библиотеката QtGui от своя страна ползва библиотеката QtCore, ето защо и на нея трябва да се посочи новото място на QtCore:

install_name_tool -change

/usr/local/Trolltech/Qt-4.5.3/lib/QtCore.framework/Versions/4/QtCore

@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore

Bible.app/Contents/MacOs/../Frameworks/QtGui.framework/Versions/4/QtGui

Подготвянето на една програма за разпространение може да се автоматизира с помощта на подходящ скрипт. Например, ако програмата MyProg използва Qt библиотеките: QtCore и QtGui, този скрипт изглежда така:

#!/bin/sh

 

mkdir MyProg.app/Contents/Frameworks

 

cp -R /usr/local/Trolltech/Qt-4.5.3/lib/QtGui.framework

MyProg.app/Contents/Frameworks

 

cp -R /usr/local/Trolltech/Qt-4.5.3/lib/QtCore.framework

MyProg.app/Contents/Frameworks

 

install_name_tool -change

/usr/local/Trolltech/Qt-4.5.3/lib/QtGui.framework/Versions/4/QtGui

@executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui

MyProg.app/Contents/MacOs/MyProg

 

install_name_tool -change

/usr/local/Trolltech/Qt-4.5.3/lib/QtCore.framework/Versions/4/QtCore

@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore

MyProg.app/Contents/MacOs/MyProg

 

install_name_tool -change

/usr/local/Trolltech/Qt-4.5.3/lib/QtCore.framework/Versions/4/QtCore

@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore

MyProg.app/Contents/MacOs/../Frameworks/QtGui.framework/Versions/4/QtGui

Важно: Някои от редовете в този скрипт са дълги, затова тук са показани на няколко реда, а именно, редовете, които тук започват по-навътре от останалите, са продължение на реда над тях.

След като съставите подобен скрипт и го запишете, например, под име mac.sh, трябва да му зададете атрибут на изпълним файл с команда от терминала:

chmod a+x mac.sh

А за да го изпълните подайте команда от терминала:

./mac.sh

След успешно изпълнение на този скрипт приложният пакет MyProg.app е готов за копиране и на компютър, на който няма Qt. Може да проверите дали това наистина е така, като временно преименувате директорията с Qt и стартирате програмата. За да направите това от терминала влезте в директория /usr/local/Trolltech с команда: cd /usr/local/Trolltech/. Вземете права на администратор с команда: sudo su и изписване на паролата. С командата: mv Qt-4.5.3 Qt-4.5.3- преименувайте директория Qt-4.5.3 на Qt-4.5.3-. Отворете с Finder директорията с пакета MyProg.app. Щракнете двойно върху пакета. Ако програмата се отвори, всичко е наред, можете да копирате този пакет и на друг компютър. Ако се покаже прозорче със съобщение: The application quit unexpectedly, щракнете бутона "Raport...". Отваря се прозорец, от който може да се види дали не липсва още някоя библиотека. Например, ако е необходима и библиотеката QtAssistant в него ще видите:

Dyld Error Message:

Library not loaded: /usr/local/Trolltech/Qt-4.5.3/lib/QtAssistant.framework/Versions/4/QtAssistant

Referenced from: /Users/youname/Desktop/MyProg/MyProg.app/Contents/MacOS/MyProg

Reason: image not found

Ако е необходимо добавете в скрипта команди за копиране и посочване на новото място и на тази библиотека и изпълнете скрипта отново. След, така описаната проверка, не забравяйте да възстановите правилното име на Qt директорията с команда: mv Qt-4.5.3- Qt-4.5.3

 

Copyright CC BY-ND 4.0.
Посещения на страницата: общо 2386 днес 0
Направено с VanyoG CMS.

Force Reload