Это правильный вариант Hello World в C ++. Все остальные Hello World неверны. Но я не здесь рассуждаю о том, как using namespace std; кристаллизует все, что было испорчено с преподаванием C ++. Возможно, в другой раз.

Сегодня мы собираемся скомпилировать этот hello world , чтобы его можно было запустить в целевой системе.

Но сначала позвольте мне рассказать вам кое-что обо мне. Я использую Linux для развлечения и получения прибыли. Я считаю, что это лучшая система. Для меня. Как разработчик. Иногда я свысока смотрю на разработчиков, использующих Windows, и удивляюсь, как им удается добиться чего-либо, щелкая мышью по объектам. И вполне вероятно, что пользователь vim на Arch свысока смотрит на меня за то, что я использую Ubuntu. Никто не идеален.

В любом случае, давайте запустим терминал

# sudo apt-get install g++
# g++ -o helloworld helloworld.cpp
# ./helloworld
Hello, World!
#

Хорошо, это просто, пойдем домой и выпьем пива!

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

Посмотрев друг на друга некоторое время, как будто мы застряли в картине Эшера, я нехотя вспоминаю, что я занимаюсь тем, чтобы делать своих клиентов счастливыми, и поэтому мы собираемся портировать наш hello world приложение для Windows. Нашему начальнику все равно, какую среду мы используем для создания этого новаторского приложения, и у них нет проблем с тем, что я продолжу одновременно работать над версией для Linux, поэтому я решил разработать это приложение для Windows, в Linux; Что возможно могло пойти не так ?

Кроме того, тогда будет намного проще настроить ферму сборки и непрерывную интеграцию. У вас даже может быть ваш CI подготавливать свежие контейнеры докеров на лету для создания приложения Windows в контролируемой и свежей среде. Хотя я склонен думать, что Dockers - это своего рода культ карго, использование Docker вместе с Jenkins на самом деле имеет большой смысл. И если вам нравится ваш системный администратор, не заставляйте его иметь дело с серверами Windows.

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

Как оказалось, Microsoft достаточно любезна, чтобы предложить компилятор для Windows под названием msvc, и у меня такое чувство, что msvc лучше для Windows, чем g++, поскольку именно на этом компиляторе построена вся экосистема. И, надеюсь, Microsoft лучше всех знает свои собственные инструменты, форматы и соглашения о вызовах. Я никогда не делал лишних усилий, чтобы проверить это, и вы найдете сторонников любого подхода в Интернете. Но команда MSVC со мной согласна. Шокер.

В любом случае, пока давайте останемся на этом.

# apt-get install msvc
E: Unable to locate package msvc

Удивительно, но это не работает. Нельзя винить парня за попытку. Но чтобы объяснить почему, позвольте мне рассказать вам, как работает компилятор.

Компилятор открывает файл, преобразует содержимое этого файла во что-то, что может быть выполнено, и записывает это в какой-то другой файл. Иногда у вас есть более одного исходного файла, поэтому вам нужен компоновщик, который представляет собой программу, которая открывает кучу файлов и записывает исполняемый файл. Исполняемый файл - это файл, ничего волшебного в этом нет. Иногда нужны библиотеки. Библиотека - это файл. И вам, скорее всего, понадобятся тонны заголовков, которые… вы понимаете, файлы. обычные старые скучные файлы. Затем исполняемый файл загружается другим исполняемым файлом, который также является файлом, полностью вниз. Хорошо, а может и нет, у Plan 9 есть еще файлы.

Чтобы было ясно, компиляторы - это чрезвычайно сложные элементы инженерии, особенно компиляторы C ++, и вы должны предлагать cookie всем разработчикам компиляторов, с которыми вы встречаетесь. Однако с точки зрения системной интеграции они настолько тривиальны, насколько это возможно. Большинство компиляторов даже не беспокоятся о потоках. Они позволяют системе сборки заниматься этим. И это прискорбно, поскольку большинству систем сборки еще предстоит научиться завязывать шнурки на обуви.

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

  • Открытие, чтение и запись файлов
  • Чтение содержимого каталогов
  • Выделение памяти

Поэтому вы можете подумать, что это достаточно разумный список, и поэтому задаетесь вопросом, почему msvc недоступен в Linux. Конечно, создание приложений Linux / ELF с помощью msvc было бы огромным и, вероятно, бессмысленным мероприятием, но все, что мы хотим, - это создать приложение для Windows, и, конечно же, Microsoft упростит мне задачу так хорошо?

Но есть такая штука. Windows - это «экосистема». Это означает, что они хотят продавать свою ОС как пользователям, так и разработчикам, продавать свои инструменты разработчикам и следить за тем, чтобы никто не узнал о том, о чем говорят другие легенды ОС. Итак, если вы хотите создать приложение для Windows, вам понадобится Windows. Дерьмо.

К счастью, кто-то переписал Windows на Linux и назвал это вином. Наверное, потому, что им нужно было быть очень пьяным, чтобы даже подумать об этом. Чтобы вино достигло 1.0, потребовалось всего 15 лет. Но он сейчас 3.0, так что, может, мы сможем его использовать? В сообществе открытого исходного кода есть небольшие чудеса, и WINE, безусловно, является одним из них.

В течение очень долгого времени MSVC входил в состав Visual Studio. Это означает, что если вы хотите скомпилировать приложение C ++ в Windows с помощью Qt Creator, CLion, Eclipse или notepad ++, вам все равно потребуется Visual Studio. Экосистема и все такое.

Сейчас дела обстоят лучше, вы можете установить «инструменты сборки», так что вам нужно будет установить только около 5 ГБ… материалов. Давайте сделаем это.

О, очевидно, компилятор распространяется как исполняемый файл, который затем загружает через Интернет то, о чем вы не просили. Может быть, это лучше, чем zip на 40 ГБ?

# wine vs_BuildTools.exe 
The entry point method could not be loaded

Вы удивлены? Мои мечты разбиты. Нам нужны окна для разработки некоторых окон (спойлер: становится лучше).

Давайте запустим виртуальную машину. Если вы хотите продолжить, я рекомендую вам использовать новую или клонированную виртуальную машину Windows 10. Мы собираемся установить много странных вещей, и убрать за собой будет практически невозможно. Впоследствии вы можете избавиться от ВМ.

Как только это будет сделано, мы сможем загрузить инструменты сборки VS.



Прокрутите вниз, пока не дойдете до запястного канала. Инструменты сборки - предпоследний элемент. Загрузите это.

У меня было несколько проблем с запуском установщика. Я думаю, они пытаются связаться с сервером, которому удалось попасть в список рекламных серверов, поэтому мой DNS заблокировал его. Не спрашивай.

Установщики с загрузочными экранами, это нормально. Как только это будет сделано, он загружает основной пользовательский интерфейс, медленно и мучительно, но затем мы должны установить флажки. Я в восторге.

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

Нам нужен набор инструментов C ++ - то, что все называют набором инструментов. Я не знаю, что новее: v141 или 15.4 v14.11. Использовать кубик?

Нам также нужна среда выполнения C, это удобно. Я не уверен, нужен ли нам CRT или URT, поэтому мы просто установим оба. Хотя URT / CRT хорош. До того, как он появился, все было намного, намного сложнее.

Наконец, нам, вероятно, потребуется использовать некоторые функции Windows, поэтому мы должны получить Windows SDK. По-видимому, это зависит от некоторых компонентов C #. И несколько JS-библиотек, очевидно. Чтобы быть ясным, вы не можете делать что-либо удаленно полезное без Windows SDK, лучше получить его сейчас.

Пора выпить чашку кофе, пока Visual Studio проникает в каждую нишу на жестком диске. Но в какой-то момент это делается, чтобы вы могли покататься на велосипеде с бабочками. Отлично.

Одной бабочки недостаточно, чтобы заставить меня отказаться от Linux, поэтому давайте посмотрим, можно ли использовать то, что мы только что установили, без Windows.

Скопируйте следующее за пределами вашей виртуальной машины:

  • C:\Program Files (x86)\Windows Kits\10\Include
  • C:\Program Files (x86)\Windows Kits\10\Lib
  • C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC

Первые два пути - это Windows SDK, последний - это набор инструментов, содержащий компилятор, компоновщик, библиотеки времени выполнения STL и VC для всех архитектур.

В моей установке у меня есть файлы URT повсюду, поэтому я предполагаю, что если вы установите Windows 10 SDK, вы действительно получите CRT, поэтому вам не нужно активировать его отдельно при выборе компонентов для установки. По сравнению с тем, что было всего несколько лет назад, ситуация намного лучше. Microsoft была занята.

Я помещаю все в папку с именем windows, у меня есть компилятор msvc со средой выполнения, STL и распространяемые файлы с одной стороны, а Windows 10 SDK в отдельной папке. Я не сохранил никакой информации о том, какую версию SDK или набор инструментов я использовал, возможно, вы захотите сделать это более правильно.

В Windows Sdk есть несколько полезных двоичных файлов и подобных dllrc.exe. Поместите их рядом с msvc2017/bin/Hostx64/x64, где расположены двоичные файлы инструментальной цепочки, включая cl.exe.

Если вы не знакомы с разработкой для Windows:

  • cl.exe - компилятор
  • link.exe - компоновщик
  • rc.exe - это инструмент для работы с файлами ресурсов, включая значки и манифесты.

Вам могут понадобиться различные другие инструменты, если вам нужно иметь дело с драйверами, CAB-файлами, установщиками MSI и т. Д.

Все дело в 2,9 ГБ. Примерно половину того, что нам пришлось установить на виртуальную машину Windows.

Давай снова выпьем вина 🍷. Посетите https://wiki.winehq.org/Ubuntu и https://github.com/Winetricks/winetricks, чтобы убедиться, что у вас установлена ​​последняя версия Wine. Я буду использовать wine-3.0.

Затем установите распространяемую версию для VC 2017. Процесс в основном автоматический. Мы будем использовать специальный винный префикс, чтобы все оставалось кошерным. Это означает, что на самом деле проще иметь несколько установок msvc под вином, чем под windows.

WINEPREFIX=windows/vs-buildtools2017-wine64 WINEARCH=win64 winetricks vcrun2017

Затем в папке Windows создайте папку bin64, в которой вы можете написать небольшой сценарий bash со следующим содержимым.

Этот скрипт сначала настроит вино для использования нашего префикса. Затем мы выполняем Linux - ›перевод разделителя путей Windows (с / на \) перед пересылкой аргументов в фактический двоичный файл Windows PE, работающий в Wine.

Мы будем использовать инструмент под названием shc, чтобы преобразовать эту оболочку в правильный elf исполняемый файл. В противном случае у нас могут возникнуть проблемы в будущем. Другое решение - написать оболочку C ++ вместо bash. shc имеет несколько недостатков, начиная с необходимости жестко запрограммированного пути установки.

shc -f cl-wine.sh -o cl.exe
shc -f cl-wine.sh -o link.exe

Вы можете создать папку bin32 таким же образом, просто изменив последнюю строку на wine '$ DIR' /../ msvc2017 / bin / Hostx64 / x86 / $ PROGRAM.

Иметь целевой компилятор x86. Я не уверен, зачем вам нужны два набора отдельных двоичных файлов для поддержки другой архитектуры, но у нас они есть. Наконец, компоновщик x86 может пожаловаться на недостающие библиотеки, поэтому мы создадим несколько символических ссылок.

cd windows/msvc2017/bin/Hostx64/x86/
for x in $(ls ../x64/ms*.dll); do ln -s $x .; done

И последнее, прежде чем мы сможем заняться серьезной работой. Нам нужно удалить vctip.exe, так как он не работает. Это инструмент телеметрии, поэтому он нам не нужен. Он находится в windows/msvc2017/bin/Hostx*/**. Если вы не выполните этот шаг, вы столкнетесь со странными следами стека.

Пришло время создать приложение Hello World! На самом деле это просто

Мы создаем исполняемый файл, который зависит от заголовков компилятора (включая STL), среды выполнения C и некоторых библиотек Windows, таких как kernel32.lib.

Для полноты, вот сборка x86

По правде говоря, все это достаточно просто, возможно, даже больше, чем использование окон как таковых. Не нужно возиться с vcvarsall.bat, и все ваши любимые инструменты, такие как perl, git, python, sed, the terminal, zsh…, есть и работают правильно.

🔨 Система сборки

У нас cl.exe работает на linux, ага! Прежде чем мы пойдем дальше, мы должны добавить этот инопланетный инструментарий в красивую современную систему сборки. Поскольку я не в настроении иметь дело с cmake, мы будем использовать QBS, мою любимую систему сборки.

Настройка qbs для использования нашего компилятора wine / msvc должна быть простой ...

QBS может автоматически обнаруживать цепочки инструментов, однако есть несколько проблем. Сначала инструменты предполагают, что MSVC существует только в Windows, поэтому некоторые пути кода отключены. Я думаю, что это можно исправить за несколько часов, для этого просто потребуется реализовать функцию CommandLineToArgv переносимым способом.

Однако есть что сказать о слишком умных инструментах. QBS пытается проанализировать vcvars.bat в предполагаемом месте. Это единственный файл, от которого мы с радостью избавились.

Проверка реальности, мы не получим никакого автоматического обнаружения. На самом деле нам это не нужно. Мы можем настроить цепочку инструментов вручную и рассматривать ее как отдельную вещь от собственно msvc-on-windows. Обнаружение на самом деле не проблема, поскольку все, что у нас есть, - это пара подключаемых каталогов и путей к библиотекам.

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



Таким образом, мы должны проделать всю работу по настройке профиля вручную. Но если наши усилия что-то доказали, так это то, что даже такую ​​сложную цепочку инструментов, как VC ++, можно свести к горстке переменных (компилятор, компоновщик, путь к инструментам, включает, определяет, пути к библиотекам). Итак, вот моя конфигурация профиля QBS.

И наконец, мы можем написать небольшой qbs скрипт сборки

Затем мы можем запустить его и Voilà!

runner.sh - это небольшой скрипт, который устанавливает префикс Wine перед запуском только что созданного исполняемого файла Windows. Ничего особенного.

Итак, вот оно. Компилятор Microsoft, заключенный в сценарий bash, скомпилированный в ELF, создает 64-битные исполняемые файлы PE, управляемые современной системой сборки, работающей в Linux. Это очень приятно.

Наш гипотетический Босс стучится в дверь. Увидимся во второй части.