Это третья часть моей серии статей о кросс-компиляции. Вы можете сначала ознакомиться с Частью 1 и Частью 2!
Вы не можете удовлетворить потребности пользователей Windows и Linux, игнорируя третью по значимости, ну, на самом деле, вторую - настольную операционную систему.
Операционная система, о которой я говорю, конечно, разработана и коммерциализирована компанией, наиболее известной как та, которая подарила миру Clang, в основном отвечает за поддержку WebKit (после того, как большая часть отрасли перешла на Chromium), и создала еще несколько удивительное программное обеспечение с открытым исходным кодом, такое как CUPS.
И за это мы должны быть благодарны.
Можно подумать, что компания, которая взяла на себя труд запустить совершенно новый компилятор, чтобы предложить лучший пользовательский интерфейс, упростит кросс-компиляцию для своей платформы.
Тем не мение.
Эта компания - Apple.
Как и в Linux и Windows, нам нужно будет приобрести и настроить 3 штуки. Компилятор, некоторые системные заголовки и библиотеки, такие как libc++
и Sdk, для интеграции с настольными компьютерами.
Если вы раньше занимались разработкой для OS X, то знаете, что все, что можно найти, можно найти в XCode, пакете инструментов объемом 5 ГБ, большая часть которого нам не понадобится.
XCode - бесплатное программное обеспечение. Как в пиве. Которых нам понадобится очень много. Однако XCode проприетарный, и это нормально.
Проблема в том, что если вы прочитаете Положения и условия, прилагаемые к XCode, вы найдете следующий пункт.
2.7 Ограничения; Запрет на другое разрешенное использование Гранты, изложенные в настоящем Соглашении, не разрешают Вам, и Вы соглашаетесь не устанавливать, не использовать и не запускать Программное обеспечение Apple или Сервисы Apple на любом компьютере или устройстве, не принадлежащем Apple, или чтобы позволить другим сделать это.
Я не юрист. Однако мне кажется, что Apple активно запрещает кросс-компиляцию с использованием своих библиотек, независимо от технических возможностей.
Таким образом, некоторые из идей, обсуждаемых в остальной части статьи, в случае их применения могут привести к аннулированию любого вашего соглашения с Apple.
Вам нужен Apple ID, поэтому вам необходимо создать учетную запись на apple.com. Я не припомню, чтобы когда-нибудь был более ужасный опыт создания учетной записи. Самым большим нарушением, безусловно, является их устаревшая политика безопасности.
Затем они отправят вам электронное письмо для проверки, что прекрасно. Но вместо ссылки в электронном письме вы получите код, который вы даже не сможете вставить, и вам придется вводить его вручную.
Затем вы выполните поиск XCode. К счастью, некоторые хорошие самаритяне поддерживают действующие ссылки для скачивания на Stackoverflow с 2012 года.
Это снова превратилось в тираду «Все программы ужасны». Мне жаль.
К счастью, кто-то уже создал хорошую коллекцию скриптов, чтобы вы начали создавать цепочку инструментов OsX в Unix. Также работает с Cygwin!
Вам нужно будет его клонировать.
Это вилка работы Thomas Pöchtrager, которую мне пришлось залатать.
XCode 7.3 поставляется как DMG, и хотя это формат файла, специфичный для osx, osxcross поставляется со сценарием для его извлечения, хорошо используя Darling. Подробнее об этом позже.
osxcross/tools/gen_sdk_package.sh Xcode_xxx.dmg
К сожалению, сообщество с открытым исходным кодом все еще ждет, когда Apple выпустит компоновщик ld64 с поддержкой файлов TBD v2, которые используются в более поздних версиях osx, чтобы не отправлять .dylib в sdk.
Файлы TBD - это довольно круто, они представляют собой YAML-представление символов, включенных в динамическую библиотеку, что устраняет необходимость поставлять фактическую библиотеку. Они очень похожи по концепции на .lib
файлы, которые создаются MSVC при создании библиотеки DLL. Я думаю, что файлы TBD можно использовать на разных платформах, но на данный момент LLVM не может справиться с ними (пока?), А ld64 с открытым исходным кодом не может справиться с новой версией.
Поэтому нам придется придерживаться SDK 10.11. Это разумно! Я решил поддержать xip
файлы, которые используются для упаковки более поздних версий XCode. Формат, вдохновленный куклами бабушек, но со сжатыми архивами. К сожалению, мы не можем использовать что-либо новее, чем XCode 7.3. Надеюсь, скоро все изменится!
Затем вы можете запустить, переместить сгенерированныйMacOSX10.11.sdk.tar.xz
в osxcross/tarballs
, затем запустить SDK_VERSION=10.11 ./osxcross/build.sh
Вам также потребуется запустить osxcross/build_llvm_dsymutil.sh
И в кратчайшие сроки у вас будет полный набор инструментов для OSX, как для i386
, так и для x86_64
(даже если у вас нет абсолютно никаких причин создавать что-либо в 32-битном формате при ориентации на OSX).
В него входят мои личные фавориты: otool
и install_name_tool
. Если вы когда-либо создавали что-то на OSX, вы знаете, насколько ужасны эти инструменты. А точнее насколько ужасен загрузчик OSX.
Я впечатлен работой, проделанной над osxcross.
Настроить QBS довольно просто, хотя есть некоторые вещи, о которых нужно позаботиться.
В osxcross/target/bin
запустите:
ln -s x86_64-apple-darwin15-ld ld cp osxcross-llvm-dsymutil x86_64-apple-darwin15-dsymutil
Позже это поможет найти нужные инструменты. Если вы хотите поддерживать несколько цепочек инструментов, поместите ld
в подпапку
Вот моя конфигурация профиля, которую вы можете адаптировать
Параметры -prefix
указывают clang, где найти правильный ld
(ld64), поскольку системный компоновщик не подходит для связывания приложения Mach-O.
Остальное просто дает qbs правильные пути поиска.
К сожалению, поддержка .plist в qbs не переносима, поэтому вы столкнетесь с ошибкой
ERROR: TypeError: Result of expression 'PropertyList' [[object Object]] is not a constructor. at JavaScriptCommand.sourceCode at Rule.prepare in /opt/qtcreator/share/qbs/modules/cpp/DarwinGCC.qbs:262:18
Закомментируйте правило в DarwinGCC.qbs, чтобы исправить проблему.
Конечно, невозможность создавать info.plist
файлов будет сильно ограничивать, и было бы здорово, если бы QBS могла обрабатывать эти файлы независимо от платформы.
На данный момент во всех наших файлах проекта .qbs мы добавим следующее, чтобы отключить объединение и, следовательно, создание Info.plist.
Depends { name: "bundle" } bundle.isBundle: false
На этом этапе мы можем создать простую консоль Hello World, показанную в Части 1.
# file helloworld Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|WEAK_DEFINES|BINDS_TO_WEAK|PIE>
Но может ли он работать?
О дорогой !
Для запуска нашего приложения для Windows мы использовали вино. Это было довольно недавнее усилие - оно началось в 2012 году, а WINE - в 1993 году; Только что была выпущена Windows 3.1! - чтобы предложить уровень перевода под названием дорогой. Проект далек от зрелости и, похоже, не имеет каких-либо финансовых возможностей. служба поддержки. Надеюсь, он приживется.
Вы можете клонировать и собрать любимый, F следуйте инструкциям на github. На моей машине все это заняло чуть меньше часа. После установки его размер составляет около 800 МБ. что неудивительно, поскольку это полная система, которая поставляется со всеми обычными инструментами, включая g ++, ruby, python, Perl, git, bash, swift, ssh…
Но сборка завершена без ошибок, и, что удивительно, она работает и кажется очень реактивной. Будучи более современным, чем вино, оно хранится в контейнерах!
Добавление магии с помощью binfmt
Итак, теперь мы можем запустить команду для Mac, но что, если бы мы могли просто скрыть магию?
Используя средство ядра и службу systemd, я смог создать файл /etc/binfmt.d/darling.conf
, чтобы ядро могло обрабатывать запуск файлов Mach-O.
:Mach-O 64b:M::\xcf\xfa\xed\xfe::/usr/bin/darling_interpreter: :Mach-O 32b:M::\xce\xfa\xed\xfe::/usr/bin/darling_interpreter: :Mach-O FAT:M::\xca\xfe\xba\xbe::/usr/bin/darling_interpreter:
/ usr / bin / darling_interpreter - это сценарий, запускающий дорогую оболочку - он должен быть исполняемым.
#!/bin/bash /usr/local/bin/darling shell "$1"
Милая документация предполагает, что darling <binary>
должен работать, но это не так.
После перезапуска службы binfmt (systemctl restart systemd-binfmt
) мы можем прозрачно запускать приложение OSX.
Что означает, что мы можем это сделать
Да, кстати, вы можете сделать то же самое для исполняемых файлов Windows и WINE. Некоторые дистрибутивы делают это из коробки.
Во второй части я попытался установить win32-версию Qt Framework в Linux без использования Windows. Я потерпел неудачу.
Можем ли мы получить Qt для Mac без Mac?
Я скачал установщик. Это .dmg. Это было бы проблемой, но с силой любимого мы можем монтировать DMG в Linux. Совершенно никаких проблем. Вот чем мы здесь занимаемся.
Но установка dmg установщика Qt показывает, что он содержит двоичный файл и файл .dat
, а не простую папку или что-то управляемое.
Предположительно бинарный файл является установщиком. Может, на любимой работает? Нет. Жесткая зависимость от фреймворка OpenGL.
Отличное программное обеспечение, упакованное в дрянные, непригодные для использования пакеты, кажется повторяющейся темой.
Вся надежда снова потеряна? Не в этот раз.
Мы можем собрать Qt для Mac, как мы пытались сделать это для Windows. Но это сработает. У Mac есть make
. Он знает о clang и gcc, во многих аспектах он очень похож на Linux. В конце концов, там есть UNIX (но у меня всегда было ощущение, что внутренности OSX ужасны, скрыты под красивым пользовательским интерфейсом. Для начала, большое количество инструментов не поддерживалось после того, как их исходная версия была переведена на GPLv3 , 10 лет назад ).
Увы, это означает иметь дело со сложной системой сборки Qt. Чтобы взломать qmake
файлы сборки, потребовалось некоторое время. Видите ли, Qt делает ужасное предположение, что вся цепочка инструментов на osx включает xcode. У нас нет xcode.
Но как только вы обойдете все автоматические проверки и предположения о том, что установлено в системе…
… .Вы можете заставить его работать!
#configure -release -opensource -confirm-license -xplatform macx-cross-clang -skip qtwebengine -nomake examples -nomake tests -prefix /home/cor3ntin/dev/cross-compilers/osx/qt5_10
Это был еще не конец пути. Виджеты Qt не удалось построить из-за отсутствия зависимостей. QtLocation не удалось собрать, потому что заголовки libc ++ были слишком старыми или поврежденными (я исправил это, скопировав последнюю версию libc ++ в OSX SDK. Это сработало). Затем QtLocation пожаловался, потому что std::auto_ptr
не был определен, поэтому я взломал несколько заголовков.
Я пытался получить qwebengine
(хром) для сборки, но он все еще использует другую систему сборки, и я сделал достаточно взлома системы сборки за одну ночь.
Но в итоге большая часть Qt собрана.
И то, что у нас есть, является довольно интересным. Бинарные файлы - это исходные файлы Linux ELF, а фреймворки и библиотеки - Macho-O. Это будет удобно через минуту.
Qt - это большая часть программного обеспечения, в полной мере использующая возможности базовой системы с точки зрения интеграции с ОС. Если мы сможем это построить, мы сможем построить практически все, что угодно.
Сначала я назвал свой файл mkspec darling-clang
. У меня была плохая репутация. это также помешало qbs понять, что это сборка для Mac. Вместо того, чтобы переименовывать mkspec и перестраивать Qt, я модифицировал qbs. код qbs-setup-qt
фактически анализирует .conf
файлы mkspec с помощью регулярных выражений. Как-то это работает. Только не дыши на это.
В конце концов, как только я дал qbs то, что он ожидал понять, что мы имеем дело с Mac, я смог позвонить
qbs-setup-qt osx/qt5_10/bin/qmake osx-x64-qt510
Которые создали нужные профили и модули. Я очистил свои профили вручную, чтобы объединить clang-osx
и osx-x64-qt510
И тогда мы сможем скомпилировать великолепное приложение Hello World!
Что теперь ?
Ну, у нас есть полный набор инструментов, может, что-нибудь проверим?
Используя otool -L
, эквивалент ldd
для osx, мы можем утверждать, что действительно связываемся с некоторыми библиотеками.
Мы можем использовать другие инструменты. такие как nm
или strings
или ужасный install_name_tool
К сожалению, Darling пока не может обрабатывать что-либо удаленно графическое, поэтому нам нужен Mac для запуска нашего приложения.
Настоящий макинтош; Визуализация Mac OSX является незаконной, кроме как на Mac. На ум приходят несколько слов. Представьте мой французский.
Поговорим о Mac. Mac. Вы, наверное, знаете его. У большинства компаний он есть.
Раньше он принадлежал Бобу. Это макинтош Боба. Но затем, 5 лет назад, Боб умер, и Алисе был предложен Т Мак. Вскоре после этого Алиса покинула компанию - вероятно, чистое совпадение.
И все же Mac всегда был Mac. У него нет хозяина. Куклы тоже нет. Вы можете подключиться к нему по адресу ssh [email protected]
. Пароль просто pass
. Он не находится в той же локальной сети, что и другие серверы, работающие где-то на виртуальных машинах. Он никоим образом не администрируется и представляет собой удобный черный ход в сети, которая в остальном надежно защищена.
Когда он работает. Иногда он просто падает на несколько дней. Людям не просто наплевать, они еще и не знают, где это физически. Mac mini легко потерять. Под чьим-то столом вклинивается старый стул, используемый как журнальный столик.
В прошлый раз, когда он разбился, его нужно было выслеживать три дня подряд, как в погоне за большой кошкой в горах. Вы даже пытались позвонить вдове Боба.
Наконец-то вы нашли Mac, зажатый между экраном Кэрол и Оксфордским словарем. «Это был рост префекта!» - возразила Кэрол, когда вы забрали ее стойку для монитора за 800 долларов. Вы обменяли Mac на старый каталог ИКЕА, который Кэрол сочла таким же практичным, если не большим, чем Mac-Mini.
Вы снова подключили Mac и тщательно обновили его до последней версии OSX, «Cougar» (или чего-то подобного, это сложно отследить).
И когда, несколько дней спустя, ваш коллега получил новую машину, а вы потеряли свой дом, я задумался: уместно ли требовать кредитную карту для применения бесплатных исправлений безопасности?
Но правда в том, что Mac выполняет важную работу. Выполнение всех задач, которые можно запустить только на Mac. Подписание установщиков, создание пакетов для Mac, прочее для iOS, работа на Нью-Йоркской фондовой бирже… вы не совсем уверены, в конце концов, это Боб.
Возможно, жизнь сложилась бы иначе, если бы мы могли виртуализировать OSX.
У меня есть Mac-mini 2011 года выпуска, подаренный бывшим работодателем. Его жизнь немного отличалась от жизни Mac. Его никогда не любили и последние два года он провел в коробке. Он позволяет увидеть жизнь дня только для нужд этой статьи. Это также причина того, что я опаздываю на 4 дня в графике публикации. Пробовал установить High Sierra - Серый экран; Мне пришлось переформатировать, установить Lion, а затем установить El Captain. Итак, Эль-капитан - это то, что мы будем использовать. Он имеет колоссальные 2 ГБ памяти, из которых система использует 3/4.
Вы должны включить VNC, удаленный общий доступ и SSH в системных параметрах вашего Mac.
Эта статья становится слишком длинной. Итак, вот краткое визуальное описание проделанной работы:
Мы должны перестать дурачиться.
- Скопируйте вашу сборку OSX Qt на машину OSX. Можно использовать
scp -r
,rsync
или общую папку (через самбу) - Скопируйте свой
helloworld-gui
на машину снова, используяscp -r
. - Наша кросс-скомпилированная сборка Qt не содержит
macdeployqt
. Вы можете получить его, установив официальную версию Qt на Mac напрямую. Чтобы избежать этого и не иметь дела с грязным беспорядкомinstall_name_tool
, мы можем настроитьDYLD_FALLBACK_FRAMEWORK_PATH
, чтобы он указывал на папку, содержащую всеQt*.framework
. DYLD_FALLBACK_FRAMEWORK_PATH несколько разумно, но может не работать и имеет некоторые связанные риски безопасности. Пожалуйста, не используйте его в поставляемых приложениях.
export DYLD_FALLBACK_FRAMEWORK_PATH=/Users/cor3ntin/dev/cross-compilation/qt5_10/lib
- Как и в Windows, нам нужно предоставить
qt.conf
файл рядом с нашимhelloworld-gui
, чтобы сообщить Qt, откуда загружать свои плагины (иначе приложение просто не запустится). Мой выглядит так
[Paths] Prefix=/Users/cor3ntin/dev/cross-compilation/qt5_10/ Plugins=plugins
Теперь, подключившись к Mac через ssh
, вы можете запустить свое приложение, и оно появится на экране Mac и в сеансе удаленного дисплея / VNC.
Можем ли мы сделать все это законным?
Clang, LLVM, ld64 и связанные с ними инструменты являются проектами с открытым исходным кодом. Это не означает, что версии с открытым исходным кодом соответствуют версии, которую использует Apple.
Фактически, Clang от Apple - это модифицированная версия собственно Clang, и они на несколько версий отстают от исходной версии. Что иронично, учитывая, что они начали проект.
LD64 И «cctools» выпускаются под «лицензией Apple Open Source». И версии этих инструментов, используемых XCode, на 2 года опережают то, что есть у сообщества открытого исходного кода.
Сами фреймворки не имеют открытого исходного кода и, как я уже упоминал в начале, не подлежат распространению.
И альтернатива с открытым исходным кодом cocotron
, которую сейчас поддерживают только Darling
люди, недостаточна.
Есть несколько проблем с этим
- У них нет сценария сборки для фактического создания SDK, а только для установки
.dylib
. это, вероятно, можно было бы исправить довольно легко. - У них ограниченный набор фреймворков, и этого набора недостаточно для сборки Qt. Qt использует следующую структуру, префиксы с префиксом
!!!!
отсутствуют в Darling
* AppKit * ApplicationServices !!!! AssetsLibrary * AudioToolbox !!!! AudioUnit !!!! AVFoundation !!!! Carbon * Cocoa !!!! CoreAudio !!!! CoreBluetooth * CoreFoundation * CoreGraphics !!!! CoreLocation !!!! CoreMedia !!!! CoreMotion * CoreServices * CoreText * CoreVideo !!!! fftreal * Foundation * ImageIO !!!! IOBluetooth * IOKit !!!! OpenCL * QuartzCore * Security !!!! SystemConfiguration
- Вы могли бы скомпилировать Qt Framework на OSX, а затем скопировать их на свою Linux-машину, это, вероятно, сработает в большинстве случаев.
- Использование SDK, который не является официальным SDK, как бы побеждает цель кросс-компиляции для проверки работы вашего программного обеспечения на Mac. вы просто проверяете, работает ли он на Darling. Нет никакой гарантии, что заголовки Darling SDK соответствуют официальному. Мингв тоже страдает от этой проблемы.
Таким образом, технически возможно кросс-компиляция сложных приложений (включая приложения на основе Qt и Qt) для Mac в Linux. Можно даже напрямую и без проблем запускать неграфические приложения и модульные тесты.
Но использование SDK незаконно, что делает все это бессмысленным в зависимости от вашего законодательства. Альтернатива с открытым исходным кодом существует, но может быть недостаточной и достаточно надежной.
И хотя мы можем надеяться, сомнительно, что у Apple когда-либо будет более дружелюбная к разработчикам политика.
И на этом ужасном разочаровании пора заканчивать!