Это вторая часть серии статей, в которых мы создаем приложение «Hello World». Если вы опоздали на вечеринку, я рекомендую вам сначала проверить Часть 1.



Итак, наш Босс зашел проверить, как мы продвигаемся. Они начали задаваться вопросом, почему перенос трехстрочного приложения в новую систему занимает целый день. Но настоящая причина их визита заключалась в том, чтобы попросить новую функцию. В то время как наш бизнес «Hello world» процветает, отдел маркетинга считает, что отсутствие графического интерфейса снижает продажи.

Видите ли, никто не избежит раздувания программного обеспечения.

Еще. Стремясь заставить босса забыть о времени, необходимом для установки MSVC в Linux, я сделал все возможное и полностью переписал наше приложение.

Конечно, мы также предоставляем небольшой отличный файл сборки.

Версия для Linux все еще работает нормально. Ду

Давайте с энтузиазмом создадим версию для Windows

Да, оказывается, нам нужна сборка Qt, совместимая с нашим компилятором. Прямо сейчас даже QBS не знает о Qt.

Я пошел скачать Qt на https://www.qt.io/download. Этот сайт становится все хуже с каждым днем. Компания Qt пытается отговорить людей покупать версию с открытым исходным кодом. Но если вы перейдете на https://download.qt.io/, у вас будут все архивы и установщики.

Говоря об установщиках, они не предлагают 64-битную версию для Windows. в 2018 году. Возможно, нам придется ограничиться 32-битными сборками и извлечь их с помощью WINE. За исключением того, что это не работает, потому что среда установки Qt не имеет тихого режима (очевидно, вы можете создать сценарий тихого режима в 100 строках JavaScript) и использует некоторые методы Windows, не поддерживаемые WINE.

Ничего. Я сам построю Qt, чтобы доказать, насколько хорош мой набор инструментов WINE. И это будет 64 бита. Я получу повышение, и стажер с 4 докторскими диссертациями принесет мне капучино. Может быть, люди даже будут использовать мое имя как глагол (если вы еще не произносите Godbolt, вам стоит окончательно его проверить!).

Кроме. Qt по-прежнему использует qmake для сборки. И qmake существует только для того, чтобы cmake выглядеть круто и современно. Постоянно прилагаются усилия по сборке Qt с qbs, и хотя это очень увлекательно, это может показаться слишком передовым даже для этого блога.

Итак, мы застряли на qmake .qmake - это генератор системы сборки, который, к сожалению, объединяет инструментальные средства и системы сборки. Я попытался создать конфигурацию для своего набора инструментов Wine, на самом деле это было довольно просто, и он генерировал некоторые Makefile с соответствующими командами. Но это были файлы Makefile для nmake, который представляет собой инструмент, похожий на make для Windows, хотя и с форматом, который не совсем совместим с исходной программой make. Я пробовал использовать nmake (который отлично работает), но затем все подпрограммы cl.exe / link.execalls происходят в среде Wine, что означает, что он выполняет фактический cl.exe, а не нашу оболочку, и поэтому наш грубый скрипт преобразования косой черты в обратную косую черту никогда не запускается и компиляция не выполняется, потому что cl.exe предполагает, что все, что начинается с /, является опцией. И мы не можем заставить nmake вызывать нашу поддельную cl.exe оболочку, поскольку nmake - это процесс Windows, а Windows ничего не знает об ELF.

Читателю предоставляется в качестве упражнения подсчитать, сколько миллионов долларов обходится отрасли Windows, использующей \ в качестве разделителя путей.

Решением будет патч qmake. Чего даже сопровождающий qmake активно избегает делать. Так что не будем этого делать.

Мне очень жаль, но мы вернемся к нашей виртуальной машине Windows и построим Qt оттуда.

Это должно быть просто, правда?

Конечно, инструменты сборки VC не могут правильно настроить свою среду.

Сколько инженеров Microsoft требуется для настройки среды сборки? Конечно, довольно много, поскольку я смог найти около 1900 строк пакетных сценариев, служащих этой цели, в 20 или около того файлах. Наверное, есть еще.

Мне удается отсортировать мою среду в 3 строки. Помните, что независимо от того, насколько сложна ваша система сборки, она сводится к нескольким переменным. Компилятору много не нужно.

set "INCLUDE=C:\Program Files (x86)\Microsoft Visual       Studio\2017\BuildTools\VC\Tools\MSVC\14.12.25827\include;
 %INCLUDE%"
set "LIB=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.12.25827\lib\x64\;%LIB%"
set "PATH=%PATH%;C:\Users\cor3ntin\Documents\qtbase-everywhere-src-5.10.0\gnuwin32"

После этого нужно было загрузить Qt 5.10 и настроить среду сборки x64 (я использовал vcvars64.bat + три строки выше, но вы можете настроить PATH вручную и вообще не беспокоиться о vcvars.bat).

Убедитесь, что perl установлен и в PATH.

Для целей этой статьи мне нужна только Qt Base (Core, Gui, Network…), так что это то, что я создаю. Сборка QtWebEngine, в которой используется хром, немного сложнее.

configure -release -opensource -confirm-license -platform win32-msvc -nomake examples -nomake tests
nmake
nmake install

Как только Qt завершит сборку, скопируйте папки обратно на свой Linux-хост. Вам нужно как минимум bin, include, lib, plugins. поместите их в новый каталог. Я позвонил своему qt5_10base-x64.

У меня были проблемы со ссылками на src. Таким образом, вы можете запустить perl bin\syncqt.pl -copy -windows -version 5.10.0 -outdir cpy из каталога Qt в Windows и использовать папку include, созданную в cpy. Даже тогда мне пришлось вручную скопировать несколько файлов (qconfig.h, q {core, gui, widgets, network, xml} -config.h) из папки src в соответствующую папку include. Определенно немного неудобно, но в конце концов вы доберетесь туда.

Итак, теперь у нас есть Qt. Но как мы можем сказать QBS, что она действительно используется?

Система профилей QBS - одна из тех вещей, которые делают его отличным. Вы можете настроить инструментальную цепочку компилятора глобально и легко переключаться с одного на другой.

Однако для работы с Qt qbs необходим полный набор модулей для каждого профиля. Профиль gcc, который мы использовали ранее, состоит из 160 файлов qbs, устанавливающих каждую библиотеку и компонент Qt.

К счастью, все, что вам нужно сделать, это вызвать этот удобный инструмент.

qbs-setup-qt -h                                             
This tool creates qbs profiles from Qt versions.

Usage:

    qbs-setup-qt [--settings-dir <settings directory>] --detect

    qbs-setup-qt [--settings-dir <settings directory>] <path to qmake> <profile name>

    qbs-setup-qt -h|--help

The first form tries to auto-detect all known Qt versions, looking them up via the PATH environment variable.

The second form creates one profile for one Qt version.

За исключением того, что мы не можем вызвать этот инструмент из Linux, потому что встроенный qmake - это приложение Windows, которое, как ожидается, будет работать в Windows. Надеюсь, когда-нибудь мы полностью избавимся от qmake, а пока вернемся к нашей машине с Windows.

Сначала мы устанавливаем сборку Windows qbs и запускаем инструмент.

qbs-windows-x86_64-1.10.0\bin\qbs-setup-qt.exe --settings-dir . bin\qmake.exe msvc14-x64-qt

Это должно создать папку qbs с правильной конфигурацией Qt. Переместите эту папку на свой Linux-компьютер в папку qt5_10base-x64, созданную ранее.

Если вы откроете файл .qbs, скажем 1.10.0/profiles/msvc14-x64-qt/modules/Qt/gui/gui.qbs, вы заметите ссылку на путь. Почему-то у меня это /usr/local/Qt-5.10.0. Думаю, я где-то напортачил, потому что у нас должен быть путь к окнам. В любом случае нам нужно преобразовать этот путь в фактическое расположение Qt на нашей Linux-машине, что легко сделать, просто используйте sed.

find -name "*.qbs" -exec sed -i -e 's\#/usr/local/Qt-5.10.0\#/home/cor3ntin/dev/cross-compilers/windows/qt-5.10-msvc-x64\#g' {} \;

Затем нам нужно изменить наш qbs.conf, чтобы использовать эти модули qt. Отредактируйте файл QBS, созданный в первой части, чтобы ссылаться на них:

qt-project\qbs\profiles\msvc14-x86_64\preferences\qbsSearchPaths=/home/cor3ntin/dev/Qt/qbs-wine-toolchain,/home/cor3ntin/dev/cross-compilers/windows/qt5_10base-x64/qbs/1.10.0/profiles/msvc14-x64-qt

Я понимаю, что все это немного сложно. В конце концов, мы можем запустить qbs, и он скомпилирует наш приветственный мир на основе Qt для Windows.

Он не запускается, потому что не может найти dll Qt. Вы можете скопировать dll в каталог сборки или убедиться, что они находятся в PATH. Windows / Wine PATH.

Я нашел единственный способ сделать это - запустить regedit - обязательно сделайте это из соответствующего WINEPREFIX и добавьте местоположение каталога bin Qt в Path, который находится под HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.

Если вы знаете, как это сделать, дайте мне знать.

Нам также нужно поместить qt.conf файл рядом с нашим встроенным двоичным файлом helloworld.exe, чтобы сообщить Qt, откуда загружать плагины. В моем случае

[Paths]
Prefix = /home/cor3ntin/dev/cross-compilers/windows/qt5_10base-x64/
Plugins = plugins

Вот и все ! Это было не так уж сложно, правда?

Итак, компилятор Microsoft Studio Visual C ++ - это лучшая вещь на свете!

Недавнее исследование, проведенное с участием двух дошкольников, показывает, что миллениалы любят радугу. Меня сразу попросили сделать наше приложение более радужным. Неоднозначно обозначенные кнопки, по-видимому, являются всадниками мнимого апокалипсиса, поэтому мы также избавимся от них.

Что нам нужно сделать, так это перебрать нашу строку и ввести некоторую html-разметку вокруг каждого символа, чтобы они отображались в разных цветах.

Обход некоторого контейнера потребует от нас использования range-v3. Другого пути буквально нет.

Разве это не здорово?

Но, и я уверен, вы будете совершенно поражены, узнав, что msvc не может компилировать range-v3. Я знаю, это полный удар и полное разочарование.

Компилятор Microsoft Studio Visual C ++ побежден.

Мы абсолютно ничего не можем поделать. Это не похоже на то, что существует msvc-совместимый порт range-v3 или какой-то другой способ преобразовать нашу строку. Пожалуйста, перестаньте говорить, что я специально придумал выдуманную историю, чтобы я мог использовать диапазоны и победить msvc с помощью радуги. Это было бы подло.

Разумно только отказаться от msvc и заменить его на что-нибудь другое. Но что ? Mingwне понимает заголовки и библиотеки MSVC, icc это довольно дорого, Cfront больше не поддерживается.

К настоящему времени вы наверняка знаете, к чему я клоню, не так ли? clang-cl! Если вы не знали о clang-cl, это капля на замену cl.exe, за исключением того, что он на самом деле звенит, поэтому внутри вас всех станет тепло и нечетко.

Clang был разработан правильно, и это замечательный инструмент по многим причинам, но самое главное:

  • Работает на всех основных ОС
  • Он не активирует специфичные для ОС функции во время компиляции, а во время выполнения.
  • Это означает, что вы сможете настроить таргетинг на что угодно и откуда угодно.
  • Он предлагает драйвер (интерфейс командной строки, если хотите), совместимый с драйвером msvc
  • Его легко собрать (и если вы когда-либо пытались собрать GCC, вы знаете, насколько сложной может быть сборка компилятора).
  • Это открытый исходный код, и его дизайн не ограничен политическими мотивами.

Итак, давайте использовать Clang!

Если вы clang не следуете документации вашего дистрибутива Linux, по умолчанию он должен иметь clang-cl (это просто символическая ссылка на clang).

Или, если вы похожи на меня, оформляйте заказ и соберите сундук, он полон добра!

Помимо того, что мы просто не можем заменить, нам нужно сделать еще несколько вещей. Модуль QBS toolchain, который мы написали для Wine, не совсем работает, поскольку он преобразует косую черту в обратную косую черту.

Я скопировал модули инструментальной цепочки и исправил некоторые другие детали. Скоро это будет на GitHub.

Создать профиль QBS для clang-cl очень просто, скопируйте профиль из Wine, измените имя инструментальной цепочки с msvc на clang-cl и укажите toolchainInstallPath где-нибудь, содержащее clang-cl и lld-link.

О, разве я не упомянул lld-link? Это капля на замену link.exe. lld также является заменой ld в unix, и он намного, намного быстрее, чем ld и gold, поэтому вам следует проверить это и использовать!

Мы еще не закончили.

Microsoft Windows разработана для файловых систем без учета регистра. Что, я уверен, в то время казалось хорошей идеей.

Однако, если вы не являетесь достаточно мазохистом, чтобы запускать свою Linux-машину на FAT, скорее всего, ваша файловая система чувствительна к регистру. И это для нас проблема.

Насколько это плохо на самом деле? Хорошо…

AclUI.Lib
ahadmin.lib
wdsClientAPI.LIB
Psapi.Lib
sensorsapi.lib
SetupAPI.Lib

Это лишь небольшая часть файлов. Я не думаю, что они могут что-то сделать, чтобы исправить это сейчас, слишком поздно.

Мы могли бы попытаться исправить проблемы с делом, изменив имя файла каждой библиотеки и заголовок. Но это, вероятно, не сработает, поскольку сторонние библиотеки также несовместимы. Поэтому, даже если мы попытаемся исправить наши файлы сборки рано или поздно, мы будем работать над проблемой.

Итак, «правильным» (для некоторого определения правильного) решением было бы обмануть ядро ​​Linux, сделав его нечувствительным к регистру. И для этого нам нужно использовать систему без учета регистра. К счастью, файл может быть файловой системой, поэтому мы создадим файл, достаточно большой для хранения Windows SDK, отформатируем его в файловой системе без учета регистра, такой как EXFAT, и поместим туда SDK. Обратите внимание, что NTFS чувствителен к регистру, даже если ядро ​​Windows - нет.

dd if=/dev/zero of=win_sdk_10.fs bs=1024 count=$((1024 * 100 * 3))
mkfs.exfat win_sdk_10.fs
mv sdk_10 sdk_10.bak
mkdir sdk_10
sudo mount win_sdk_10.fs
mv sdk_10.bak/* sdk_10

Вы должны любить Linux.

И теперь компиляция с помощью clang-cl работает. Однако при запуске программы обнаруживается ошибка.

И все же тот же исполняемый файл, скопированный на виртуальную машину, работает нормально.

Я все еще не уверен, где на самом деле ошибка. Похоже, он находится либо в диапазоне-v3, либо в моем его использовании, и все же кажется странным, что он обнаружил бы другое поведение во время выполнения.

Но это то, что здорово в наличии большего набора сред разработки: если у вас есть ошибки, они с большей вероятностью будут обнаружены. Во-первых, этот неприятный графический сбой заставил меня понять, что я должен обрабатывать пробелы как особый случай.

Да, и если вы хотите проверить, что на самом деле делает clang, вы можете использовать dumpbin.exe от Microsoft, найденный в msvc2017/bin/Hostx64/x64/. Этот инструмент эквивалентен ldd и nm для unix.

Интересно, что артефакт clang выглядит точно так же, как созданный msvc, хотя и с несколькими дополнительными секциями. Включая ЭЛТ и vcruntime!

Вот бинарный файл, созданный MSVC.

Сейчас ldd-link все еще экспериментальный и не поддерживает отладочную информацию. clang-cl в основном сделано, за исключением обработки некоторых исключений. Вы можете смешивать и сочетать cl.exe clang-cl link.exe и lld-link.

Я не могу посоветовать вам использовать clang-cl в производственной среде (пока что это уже скоро), но это замечательный инструмент, который можно добавить в вашу CI и среду разработки.

Это все, что у меня есть для вас сегодня. Надеюсь, вы кое-чему научились!

… Еще кое-что …

Увидимся в части 3!