Собираем VirtualBox под Windows

122274f2b4098fd3b2d5eb703ce60fd3.png


9f850549b13e79dc47d23f5f9e994379.png Введение


Как известно большинству пользователей Windows-версии VirtualBox (далее — VB, не путать с Visual Basic), в релизе 4.3.14 разработчики этой программы добавили дополнительный механизм защиты, называемый «hardening» (что можно перевести как «упрочнение»), который привёл к многочисленным проблемам совместимости VB с антивирусами, драйверами крипто-модулей и даже отдельными обновлениями самой Windows, в результате чего виртуальные машины попросту отказываются запускаться. В лучшем случае пользователю приходится ждать около месяца, пока проблемная программа, о которой он сообщит разработчикам, окажется учтена в следующем релизе VB. В худшем случае придётся либо удалять конфликтующую программу (или системное обновление), либо откатывать VB до версии 4.3.12 — последней, в которой не было этой защиты. Многочисленные предложения к разработчикам о добавлении пользовательского списка исключений или опции, отключающей защиту целиком, остаются без внимания. Единственный внятный ответ с их стороны звучит так: «не хотите защиту — компилируйте из исходников сами». Что ж, придётся этим заняться.

Несмотря на то, что процедура сборки описана на официальной вики, она неполна и кое в чём устарела, а сама сборка так и норовит выдать странные ошибки. Поэтому когда я всё-таки пробился до конца сей процедуры, я решил, что её описание заслуживает отдельной статьи. Инструкция изначально составлялась для VB 5.0.12 и проверялась также на версии 5.0.14.

9f850549b13e79dc47d23f5f9e994379.png Содержание

» Постановка задачи
» Пара предупреждений
» Готовим окружение
» Особенности установки программ
» Последние штрихи
» Собираем VirtualBox
» Послесловие


9f850549b13e79dc47d23f5f9e994379.png Постановка задачи


Изначально я планировал упростить себе задачу и обойтись минимальной пересборкой, чтобы устанавливать официальный дистрибутив и просто подменять в нём бинарные файлы. Однако оказалось, что такой подход не сработает, поскольку не учитывает использование системных механизмов установки и регистрации драйверов и COM-компонентов. Можно было бы попытаться разобраться в деталях и написать автоматизирующий скрипт, но я решил замахнуться на более крупную дичь: самостоятельно собрать полноценный дистрибутив, максимально близкий к официальному и отличающийся от него только отсутствием hardening’а.

Сразу скажу, что на 100% задачу решить не удалось. Слабым звеном оказались гостевые дополнения, которые в официальном пакете собраны под Windows (32- и 64-битную), Linux, Solaris и OS/2. В комментариях соответствующего Makefile указано, что сборка осуществляется удалённо на разных машинах, а настраивать такой комплект виртуалок мне не улыбалось. В итоге я решил собирать из исходных кодов всё, кроме дополнений, ISO-образ которых буду просто скачивать с сервера Oracle. Я пока не исследовал вопрос наличия hardening’а в дополнениях, но даже если он там есть, сообщений о вызванных им проблемах мне до сих пор не попадалось.

9f850549b13e79dc47d23f5f9e994379.png Пара предупреждений


• Проблемы безопасности
Про hardening известно, что добавили его не просто так, а для закрытия некой уязвимости VB. Внятно рассказать о сути уязвимости Oracle категорически отказывается, несмотря на то, что с момента фикса прошло почти полтора года. Ограничиваются лишь намёками на «очень уязвимую архитектуру Windows, разрешающую загрузку сторонних модулей в чужие процессы». Вопрос о том, как же без подобных ухищрений умудряются работать другие системы виртуализации (да и вообще все программы), также остаётся без ответа. Из отдельных скупых фраз на официальном форуме удалось выудить информацию, что проблема связана с повышением привилегий на хостовой машине, и что для этой уязвимости VB есть реально использующиеся эксплойты. Если это вас не пугает, можете продолжать чтение, но я вас предупредил.• Подписывание драйверов
Как известно, 64-битная Windows в обычном режиме запрещает загрузку драйверов, не подписанных сертификатом с цепочкой доверия, ведущей до корневого сертификата Microsoft (а в Windows 10 предпринимаются шаги к запрету вообще всех драйверов, подписанных не в Microsoft). Поэтому прежде чем компилировать VB даже для личного использования, необходимо продумать решение этой проблемы: либо купить сертификат, либо попробовать воспользоваться сервисами подписывания драйверов для разработчиков Open Source (если они, конечно, согласятся подписать заведомо уязвимый драйвер), либо перевести свою Windows в тестовый режим и использовать самоподписанный тестовый сертификат.

Далее я буду ориентироваться на этот последний вариант, но в нужных местах укажу, как поменяется процедура при наличии полноценного сертификата.

9f850549b13e79dc47d23f5f9e994379.png Готовим окружение


Официально в качестве сборочной системы рекомендуется Windows версии от XP SP3 до 7. Всю работу я проводил в Windows 7 SP1×64, но, думаю, что с более современными версиями проблем возникнуть не должно. Если вы выделяете для сборки отдельную машину (реальную или виртуальную), имейте в виду, что ей необходим доступ в Интернет.

Для создания сборочного окружения потребуется немаленький набор программ. Если для программы присутствует портабельная версия, я использую её, а не инсталлятор.

Следующий набор программ поставляется только в виде инсталляторов (по крайней мере, официально). Для Visual Studio и SDK/WDK важно соблюдать порядок установки, как указано ниже. После установки крайне желательно установить обновления через Windows Update с включённой опцией поддержки всех продуктов Microsoft.


Остальные программы скачиваются в виде архивов или исходных кодов:

  • Qt 4.8.7 (исходные коды)
  • MinGW 3.3.3 (32-битная версия):
  • MinGW-w64 4.5.4 (64-битная версия):
  • SDL v1.2.x (development-пакет для Visual C++)
  • cURL (исходные коды)
  • OpenSSL 1.0.2 (исходные коды)
  • gSOAP 2.7.x
  • MiKTeX Portable
  • wget
    Требуются два архива: Binaries и Dependencies.


Зачем оно всё?
Если вы не планируете собирать такой же пакет, как я, то некоторые из перечисленных инструментов могут вам не потребоваться. Здесь я вкратце перечислю, какую роль они выполняют.
  • WiX
    Это инструмент для создания MSI-инсталляторов. Хоть финальный вариант инсталлятора и является EXE-файлом, внутри он содержит два MSI, так что WiX тут необходим. Если вам достаточно простой компиляции бинарников, то этот пакет не понадобится.
  • SDL
    На этой библиотеке основан фронт-энд VBoxSDL.exe — минималистичная альтернатива стандартной оболочке VirtualBox.exe. Если вам не требуется VBoxSDL, то, может быть, удастся обойтись без библиотеки SDL, но я это не проверял.
  • gSOAP
    Этот компонент необходим для сборки сервиса удалённого управления VB: VBoxWebSrv.exe. Отсутствие gSOAP не является критической ошибкой, VB успешно соберётся без этого сервиса.
  • MiKTeX
    При помощи MiKTeX компилируется справочник в формате PDF (doc\UserManual.pdf). Отсутствие MiKTeX не является критической ошибкой, VB успешно соберётся без PDF-документации.
  • wget
    wget или его альтернатива будет использоваться для скачивания ISO-образа гостевых дополнений. Этих команд изначально нет в проекте VB, они добавляются вручную в kmk-файл (см. ниже). Если вам не нужны гостевые дополнения в дистрибутиве, можно обойтись без wget, но тогда нужно будет учесть это при модификации сборочных правил. Альтернативой может работать cURL, исходники которого уже участвуют в процессе сборки. Но в текущем варианте сам curl.exe не собирается, только библиотека libcurl, так что для использования curl потребуется сначала его самостоятельно собрать (или скачать уже скомпилированный кем-то вариант).


Чтобы легче было отслеживать потенциальные источники проблем сборки, привожу здесь сводную таблицу всех инструментов с их версиями и путями установки в созданном мной окружении. Обозначение »{x32|x64}» указывает, что пакет устанавливается в два разных каталога для 32- и 64-битной версии.

Программа Версия Путь установки
Visual Studio 2010 Professional C:\Program Files (x86)\Microsoft Visual Studio 10.0\
SDK 7.1 C:\Program Files\Microsoft SDKs\Windows\v7.1\
WDK 7.1.0 C:\WinDDK\7600.16385.1\
ActivePerl 5.22.0 Build 2200×64 C:\Programs\Perl\
ActivePython 2.7.10.12×64 C:\Programs\Python\
WiX 3.10.1.2213 C:\Program Files (x86)\WiX Toolset v3.10\
Qt 4.8.7 C:\Programs\Qt\4.8.7-{x32|x64}\
MinGW 3.3.3–20040217–1 C:\Programs\mingw32\
MinGW Runtime 3.8 C:\Programs\mingw32\
MinGW W32API 3.5 C:\Programs\mingw32\
MinGW Binutils 2.13.90–20021006–2 C:\Programs\mingw32\
MinGW-w64 4.5.4 C:\Programs\mingw64\
SDL 1.2.15 C:\Programs\SDL\{x32|x64}\
cURL 7.46.0 C:\Programs\curl\{x32|x64}\
OpenSSL 1.0.2e C:\Programs\OpenSSL\{x32|x64}\
gSOAP 2.7.16 C:\Programs\gSOAP\
MiKTeX Portable 2.9.5719 C:\Programs\MiKTeX\
wget 1.11.4.1 C:\Programs\wget\

9f850549b13e79dc47d23f5f9e994379.png Особенности установки программ


В этом разделе я привожу указания или инструкции для отдельных пакетов, где процедура неочевидна или требует дополнительных шагов.• Windows Platform SDK v7.1 При установке могут возникнуть проблемы из-за устаревших версий компиляторов и рантайма: они не могут установиться поверх более новых версий, установленных с VS 2010, и инсталлятор считает это критической ошибкой. Необходимо либо отключить соответствующие галочки, либо предварительно удалить из системы пакеты с именами вида «Microsoft Visual C++ 2010 Redistributable», «Microsoft Visual C++ 2010 Runtime», «Microsoft Visual C++ Compilers…» (SDK установит старые версии пакетов, а Windows Update потом обновит их до актуальных).

Также обратите внимание, что для финальной сборки MSI-пакетов потребуется установить примеры программ (Windows Native Code Development → Samples): в их составе идут скрипты, использующиеся сборочными правилами.

• WDK v7.1 Достаточно установить только сборочные окружения (Build Environments).• Qt Поскольку официальных сборок Qt для 64-битной Windows нет, то собирать её придётся вручную. Также я рекомендую собрать из исходников и 32-битную версию: для удобства и единства интерфейса.

  1. Распаковываем архив с исходным кодом Qt в каталог C:\Programs\Qt\ и переименовываем полученный подкаталог qt-everywhere-opensource-src-4.8.7 в 4.8.7-src (для красоты и краткости).
  2. Рядом создаём два каталога: build-x32 (в нём будет происходить сборка) и 4.8.7-x32 (сюда будут установлены итоговые бинарники).
  3. Копируем подкаталог 4.8.7-src\mkspecs со всем содержимым в 4.8.7-x32\.
  4. Открываем консоль, выполняем следующие команды:
    SET QTVER=4.8.7
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7
    SET QTDIR=C:\Programs\Qt\%QTVER%-x32
    SET PATH=%QTDIR%\bin;%PATH%
    SET QMAKESPEC=win32-msvc2010
    
    Если не нравится зелёный цвет шрифта, установленный командой SetEnv.Cmd, можно сбросить его командой color без параметров.
  5. Теперь запускаем configure.exe из каталога 4.8.7-src. Можно конфигурировать по умолчанию, но я предпочитаю бо́льшую часть опций указывать явным образом, а ненужные модули отключать совсем, чтобы ускорить компиляцию. Вот команда, которую я использовал у себя:
    ..\4.8.7-src\configure.exe -prefix C:\Programs\Qt\4.8.7-x32 -opensource -confirm-license -release -shared -no-ltcg -no-fast -exceptions -no-dsp -accessibility -stl -no-sql-sqlite -no-qt3support -opengl desktop -no-nis -no-inotify -largefile -little-endian -no-fontconfig -no-system-proxies -graphicssystem raster -qt-zlib -qt-libpng -qt-libmng -qt-libtiff -qt-libjpeg -no-openssl -no-dbus -no-phonon -no-phonon-backend -no-multimedia -no-audio-backend -no-webkit -no-script -no-scripttools -no-declarative -no-declarative-debug -no-directwrite -no-style-plastique -no-style-motif -no-style-cde -no-style-windowsce -no-style-windowsmobile -no-style-s60 -native-gestures -mp -nomake examples -nomake demos -nomake tests
    
  6. Когда программа отработает, запускаем сборку командой nmake
  7. Ну и, наконец, устанавливаем скомпилированную библиотеку командой nmake install


Теперь открываем новую консоль и аналогичным образом компилируем и устанавливаем 64-битную версию, только в именах каталогов необходимо заменить «x32» на «x64», а команды создания окружения будут выглядеть так:

SET QTVER=4.8.7
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7
SET QTDIR=C:\Programs\Qt\%QTVER%-x64
SET PATH=%QTDIR%\bin;%PATH%
SET QMAKESPEC=win32-msvc2010


После установки обеих версий Qt можно удалять каталоги build-x32, build-x64 и 4.8.7-src, чтобы не занимали место: они нам больше не понадобятся.• MinGW Для установки 32-битной MinGW просто последовательно распакуйте все пять архивов в целевой каталог. Совпадающие файлы перезаписываются.

MinGW-w64 состоит из одного архива и распаковывается в отдельный каталог.

• SDL

  1. Распаковываем SDL два раза в отдельные каталоги: C:\Programs\SDL\x32\ и C:\Programs\SDL\x64\.
  2. Перемещаем всё содержимое C:\Programs\SDL\x64\lib\x64\ на уровень выше (в C:\Programs\SDL\x64\lib\), каталоги C:\Programs\SDL\x64\lib\x86 и x64 удаляем.
  3. Аналогично для 32-битной версии: перемещаем содержимое C:\Programs\SDL\x32\lib\x86\ на уровень выше, каталоги C:\Programs\SDL\x32\lib\x86 и x64 удаляем.


• cURL

  1. Распаковываем архив cURL в каталог: C:\Programs\curl\, переименовываем получившийся подкаталог из curl-7.46.0 в curl-7.46.0-x32.
  2. Открываем в редакторе файл C:\Programs\curl\curl-7.46.0-x32\lib\Makefile.vc10, находим там в районе строки 121 следующий код:
    CFLAGS       = $(CFLAGS)
    
    и добавляем после него:
    CFLAGS = $(CFLAGS) /DCURL_DISABLE_LDAP
    
    Если этого не сделать, то при сборке VB полезут ошибки линковки.
  3. Делаем копию каталога curl-7.46.0-x32 под именем curl-7.46.0-x64.
  4. Открываем консоль, собираем 32-битную версию библиотеки (сам curl не потребуется) и копируем необходимые файлы в целевой каталог:
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7
    cd /d C:\Programs\curl\curl-7.46.0-x32\lib
    md C:\Programs\curl\x32
    nmake /f Makefile.vc10 cfg=release-dll
    nmake /f Makefile.vc10 cfg=release
    copy *.dll ..\..\x32
    copy *.lib ..\..\x32
    xcopy /E ..\include ..\..\x32
    
  5. Собираем 64-битную версию, открыв новую консоль и выполнив команды:
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7
    cd /d C:\Programs\curl\curl-7.46.0-x64\lib
    md C:\Programs\curl\x64
    nmake /f Makefile.vc10 MACHINE=x64 cfg=release-dll
    nmake /f Makefile.vc10 MACHINE=x64 cfg=release
    copy *.dll ..\..\x64
    copy *.lib ..\..\x64
    xcopy /E ..\include ..\..\x64
    
  6. Каталоги C:\Programs\curl\curl-7.46.0-x32 и curl-7.46.0-x64 можно удалять.


• OpenSSL

  1. Распаковываем архив OpenSSL два раза в каталог C:\Programs\OpenSSL\, переименовывая полученный подкаталог из openssl-1.0.2e, соответственно, в openssl-1.0.2e-x32 и openssl-1.0.2e-x64.
  2. Открываем консоль, собираем и устанавливаем 32-битную версию:
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7
    cd /d C:\Programs\OpenSSL\openssl-1.0.2e-x32\
    perl Configure VC-WIN32 no-asm --prefix=C:\Programs\OpenSSL\x32
    ms\do_ms
    nmake -f ms\ntdll.mak
    nmake -f ms\ntdll.mak install
    
  3. Открываем новую консоль, собираем и устанавливаем 64-битную версию:
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7
    cd /d C:\Programs\OpenSSL\openssl-1.0.2e-x64\
    perl Configure VC-WIN64A --prefix=C:\Programs\OpenSSL\x64
    ms\do_win64a
    nmake -f ms\ntdll.mak
    nmake -f ms\ntdll.mak install
    
  4. Каталоги C:\Programs\OpenSSL\openssl-1.0.2e-x32 и openssl-1.0.2e-x64 можно удалять.


• gSOAP

  1. Открываем архив, заходим в подкаталог gsoap-2.7\gsoap и распаковываем содержимое этого подкаталога в C:\Programs\gSOAP\.
  2. Открываем на редактирование файл C:\Programs\gSOAP\stdsoap2.cpp, ищем там следующий код (строка 4001):
                { X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
    
    и добавляем к определению переменной const, чтобы получилось так:
                { const X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
    
    X509V3_EXT_get() — это функция из OpenSSL, она возвращает константный указатель, так что без этой правки сборка завершится ошибкой приведения типа.


• MiKTeX

  1. Распаковываем архив в C:\Programs\MiKTeX\
  2. Открываем консоль и запускаем установку дополнительных модулей:
    "C:\Programs\MiKTeX\miktex\bin\mpm.exe" --verbose --install=koma-script --install=ucs --install=tabulary --install=url --install=fancybox --install=fancyvrb --install=bera --install=charter --install=mptopdf
    


• wget Просто распаковываем архивы wget-1.11.4-1-bin.zip и wget-1.11.4-1-dep.zip в C:\Programs\wget\

9f850549b13e79dc47d23f5f9e994379.png Последние штрихи


Подготовка к сборке почти завершена, остались несколько шагов. Если вы этого ещё не сделали, нужно скачать архив с исходными кодами VirtualBox нужной версии и распаковать его в удобное место. В качестве рабочего каталога я выбрал C:\Devel\VirtualBox-5.0.14\ (повторюсь, данная инструкция проверена только на 5.0.12 и 5.0.14).• Добавление сертификата Если у вас нет полноценного сертификата, то рекомендуется создать хотя бы персональный (с ним проще загружать драйверы, чем совсем без подписи). Для этого нужно открыть консоль с повышенными привилегиями и выполнить в ней следующие команды:

"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7
makecert.exe -r -pe -ss my -n "CN=Roga and Kopyta Ltd" C:\Devel\testcert.cer
certmgr.exe -add C:\Devel\testcert.cer -s -r localMachine root

Название сертификата («Roga and Kopyta Ltd») и путь к файлу сертификата можно выбирать по своему усмотрению.• Сборка xmllint На одном из этапов потребуется также программа xmllint. Я не указывал её в списке требований, потому что необходимые исходники уже присутствуют в архиве VB. Сборочные правила не рассчитаны на автоматическую сборку этой утилиты, поэтому её придётся собрать отдельно. В качестве целевого каталога я выбрал C:\Programs\xmllint.

  1. Копируем содержимое каталога C:\Devel\VirtualBox-5.0.14\src\libs\libxml2-2.9.2 в C:\Programs\libxml2-2.9.2\ (это необходимо, чтобы промежуточные объектные файлы не мешали сборке самого VB).
  2. Открываем консоль и выполняем команды:
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7
    cd /d C:\Programs\libxml2-2.9.2\win32
    cscript.exe configure.js cruntime=/MT prefix=C:\Programs\xmllint iconv=no
    nmake /f Makefile.msvc
    nmake /f Makefile.msvc install
    
  3. Удаляем каталог C:\Programs\libxml2-2.9.2.


• Различные правки VB Прежде чем приступать к сборке, нам ещё потребуется внести кое-какие правки в исходные коды самого VirtualBox. Так что переходим в каталог C:\Devel\VirtualBox-5.0.14 и начинаем:

  1. Открываем файл configure.vbs, находим код (строка 1062):
    if Shell(DosSlashes(strPathVC & "/bin/cl.exe"), True) <> 0 then
    
    и заменяем на следующий:
    if Shell(DosSlashes(strPathVC & "/bin/cl.exe") & " /?", True) <> 0 then
    
    Этот кусок отвечает за поиск и проверку компилятора, но не учитывает, что вызов cl.exe без аргументов возвращает ошибку (что трактуется как неподходящий компилятор). Добавление параметра »/?» запрашивает вывод справки, и код возврата перестаёт быть ошибочным.
  2. Открываем файл Makefile.kmk и где-нибудь за пределами условных блоков добавляем следующий код (я добавил в строке 142, перед комментарием «Install our Qt DLLs…»):
    # OpenSSL DLLs
    ifeq ($(KBUILD_TARGET),win)
     SDK_VBOX_OPENSSL_DLLS ?= $(subst .lib,.dll,$(subst /lib/,/bin/,$(SDK_VBOX_OPENSSL_LIBS)))
     InstallExternalLibs_SOURCES += \
            $(foreach sslmod,$(SDK_VBOX_OPENSSL_DLLS),$(call VBOX_RE_SIGN_DLL_FN,InstallExternalLibs,$(sslmod)))
    endif
    
    При сборке VB производится копирование библиотек-зависимостей (таких как Qt, SDL) в целевой каталог. OpenSSL, видимо, в Oracle компилируется статически, а у нас он — динамический, поэтому здесь мы добавили копирование и подписывание соответствующих библиотек. (Я пробовал также собирать OpenSSL статически, но подход «в лоб» не сработал, полезли конфликты на стадии линковки.)
  3. Открываем файл src\recompiler\Makefile.kmk, в строке 120 находим следующий код:
    VBoxRemPrimary_SOURCES.win = $(VBoxREMImp_0_OUTDIR)/VBoxREMRes.o
    
    и заменяем на:
    VBoxRemPrimary_SOURCES.win =
    VBoxRemPrimary_SOURCES.win.amd64 = $(VBoxREMImp_0_OUTDIR)/VBoxREMRes.o
    
    Здесь используется MinGW, а при сборке 32-битной версии VB, как вы помните, у нас работает MinGW 3.3.3. Её компилятор ресурсов неправильно трактует переданные ему параметры, так что сборка падает. Этой заменой я отключаю использование (и, следовательно, и компиляцию) ресурсного объектника для 32-битной версии. На работоспособность итоговых файлов это не влияет.
  4. Открываем файл src\VBox\Installer\win\VBoxMergeApp.wxi, в строке 278 находим следующий код:
            
            
    
    и удаляем из имён файлов подстроку «VBox», чтобы получилось:
            
            
    
    Чуть ниже делаем аналогичную замену:
            
    
    на:
            
    
    Здесь задаются правила для инсталлятора. Библиотека Qt для оригинального VB собирается с брэндированным суффиксом, так что итоговые библиотеки имеют имена вида QtCoreVBox4.dll. Мы же собирали библиотеку без таких суффиксов.

    В том же файле добавляем инструкции по упаковке OpenSSL-библиотек в дистрибутив, в любое место вне условных блоков (я добавил в строку 308, перед комментарием «EFI firmware»):

            
            
            
    
  5. Открываем файл doc\manual\Makefile.kmk и удаляем оттуда все подстроки вида » --nonet». Этот аргумент у утилит обработки XML-файлов запрещает автоматическое скачивание DTD-схем, поэтому для успешной обработки требуется либо самостоятельно скачать все шаблоны, разместить их на локальном диске и прописать пути к ним в специальных переменных, либо отказаться от этого запрета, удалив параметр. Я пошёл по второму пути.
  6. Открываем файл src\VBox\Additions\Makefile.kmk, находим там правило для сборки ISO-образа гостевых дополнений (строки 303–340), начинающееся с объявления:
    $(VBOX_PATH_ADDITIONS_ISO)/VBoxGuestAdditions.iso: \
    
    Удаляем весь этот блок, вместо него вставляем единственную команду для загрузки официального образа:
    $(VBOX_PATH_ADDITIONS_ISO)/VBoxGuestAdditions.iso:
            $(TOOL_WGET_FETCH) http://download.virtualbox.org/virtualbox/$(VBOX_VERSION_STRING_RAW)/VBoxGuestAdditions_$(VBOX_VERSION_STRING_RAW).iso -O $@
    
  7. По умолчанию собранный VB получает суффикс «OSE» в номере версии (»5.0.14_OSE»). Если вас это не устраивает, можно поменять суффикс в файле Config.kmk в строке 1239, заменив код
     VBOX_BUILD_PUBLISHER = _OSE
    
    на:
     VBOX_BUILD_PUBLISHER =
    
    или на любую другую строку, которая вам подходит. Теоретически, этот параметр должен переопределяться локальным конфигом (см. следующий пункт), но что-то где-то оказалось не учтено, и для корректной сборки приходится менять именно здесь.
  8. Ну и, наконец, создаём в корне рабочего каталога файл с именем LocalConfig.kmk, в который прописываем следующее содержимое:
    VBOX_WITH_HARDENING :=
    SDK_VBOX_OPENSSL-x86_INCS := C:\Programs\OpenSSL\x32\include
    SDK_VBOX_OPENSSL-x86_LIBS := C:\Programs\OpenSSL\x32\lib\ssleay32.lib C:\Programs\OpenSSL\x32\lib\libeay32.lib
    SDK_VBOX_LIBCURL-x86_INCS := C:\Programs\curl\x32\include
    SDK_VBOX_LIBCURL-x86_LIBS := C:\Programs\curl\x32\libcurl.lib
    SDK_VBOX_LIBCURL-x86_LIBS.x86 := C:\Programs\curl\x32\libcurl.lib
    # 8.3 path for C:\Program Files (x86)\WiX Toolset v3.10\bin
    VBOX_PATH_WIX := C:\PROGRA~2\WIXTOO~1.10\bin
    VBOX_GSOAP_INSTALLED := 1
    VBOX_PATH_GSOAP := C:\Programs\gSOAP
    VBOX_WITH_COMBINED_PACKAGE := 1
    VBOX_WITH_QT4_PAYLOAD := 1
    VBOX_SIGNING_MODE := release
    VBOX_CERTIFICATE_SUBJECT_NAME := Roga and Kopyta Ltd
    VBOX_CROSS_CERTIFICATE_FILE_ARGS :=
    VBOX_SIGNTOOL := C:\WinDDK\7600.16385.1\bin\amd64\SignTool.exe
    VBOX_INF2CAT := C:\WinDDK\7600.16385.1\bin\selfsign\Inf2Cat.exe
    VBOX_PATH_WISUMINFO := "C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiSumInf.vbs"
    VBOX_WITH_DOCS := 1
    VBOX_WITH_DOCS_CHM := 1
    VBOX_WITH_DOCS_PACKING := 1
    VBOX_HAVE_XMLLINT := C:\Programs\xmllint\bin\xmllint.exe
    VBOX_PATH_DOCBOOK_DTD := http://www.oasis-open.org/docbook/xml/4.4/
    VBOX_PATH_HTML_HELP_WORKSHOP := "C:\Program Files (x86)\HTML Help Workshop"
    VBOX_PDFLATEX := C:\Programs\MiKTeX\miktex\bin\pdflatex.exe
    VBOX_PDFLATEX_CMD := $(VBOX_PDFLATEX) -halt-on-error -interaction batchmode
    TOOL_WGET_FETCH := C:\Programs\wget\bin\wget.exe
    
    Главная строка, ради которой всё и затевалось, идёт здесь первой: отключаем hardening. В переменной VBOX_CERTIFICATE_SUBJECT_NAME потребуется указать имя сертификата, который вы создавали ранее. Если у вас не самоподписанный сертификат, а покупной, то здесь указываете его имя, следующую строчку (переменную VBOX_CROSS_CERTIFICATE_FILE_ARGS) удаляете, а вместо неё добавляете новую строку, в которой переменной VBOX_CROSS_CERTIFICATE_FILE (без »_ARGS») присваиваете полный путь к файлу кросс-сертификата (без него драйверы не будут считаться подписанными). Его можно найти на сайте компании, выпустившей сертификат, или у Microsoft. Также имеются другие переменные, через которые можно поменять хранилище, адрес сервера для наложения временно́й метки или вообще задать произвольный дополнительный набор аргументов для утилиты signtool. В файле Config.kmk под комментарием «Code Signing» (начиная со строки 2712) можно посмотреть, каике там переменные определяются и как они используются.

    Остальное содержимое LocalConfig.kmk — это разнообразные параметры, включающие те или иные компоненты сборки, задающие пути к внешним инструментам и аргументы их запуска. Обратите внимание, что если путь установки WiX содержит пробелы, то необходимо преобразовать его в короткий. Обязательно проверьте, чему он равен на вашей системе (даже для одинаковых длинных имён он может оказаться различным). Для этого можно воспользоваться командой dir /x. Трюк со взятием в кавычки здесь, увы, не работает.


9f850549b13e79dc47d23f5f9e994379.png Собираем VirtualBox


Ну вот, теперь, наконец, можно и приступать к сборке собственно VirtualBox. Если вы любите параллельную сборку, то придётся от этой привычки временно отказаться (или собирать в двух копиях дерева исходных кодов): здесь используется общий файл конфигурации, который нужно перегенерировать перед началом сборки. И если во время 64-битной компиляции в нём неожиданно окажутся пути к 32-битным библиотекам, компилятору это очень не понравится.

  1. Начинаем со сборки 64-битной версии. Открываем консоль, выполняем команды:
    cd /d C:\Devel\VirtualBox-5.0.14
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7
    set BUILD_TARGET_ARCH=amd64
    set INCLUDE=C:\Programs\curl\x64\include;%INCLUDE%
    set LIB=C:\Programs\curl\x64;%LIB%
    set LIBPATH=C:\Programs\curl\x64;%LIBPATH%
    set PATH=C:\Programs\Qt\4.8.7-x64\bin;%PATH%
    set QMAKESPEC=win32-msvc2010
    cscript configure.vbs --with-DDK=C:\WinDDK\7600.16385.1 --with-MinGW-w64=C:\Programs\mingw64 --with-MinGW32=C:\Programs\mingw32 --with-libSDL=C:\Programs\SDL\x64 --with-openssl=C:\Programs\OpenSSL\x64 --with-libcurl=C:\Programs\curl\x64 --with-Qt4=C:\Programs\Qt\4.8.7-x64 --with-python=C:\Programs\Python
    env.bat
    kmk
    kmk C:/Devel/VirtualBox-5.0.14/out/win.x86/release/obj/Installer/VirtualBox-5.0.14_OSE-r105127-MultiArch_amd64.msi
    
    Скрипт configure.vbs проверяет окружение и создаёт файлы конфигурации (AutoConfig.kmk и env.bat). Первый запуск kmk выполняет сборку бинарных компонентов и помещает их в каталог out\win.amd64\bin\. Последняя команда собирает из этих компонентов промежуточный MSI-архив. Важные моменты:
    • Слэши в последней команде должны быть обязательно прямыми. С обратными kmk не найдёт сборочные правила.
    • Хоть мы собираем 64-битную версию, архив располагается в подкаталоге out\win.x86\…, потому что финальная сборка будет производиться из 32-битного окружения.
    • Если вы меняли суффикс версии, то »_OSE» в имени MSI-файла необходимо поправить на то, что вы задали в переменной VBOX_BUILD_PUBLISHER.
    • Ревизию в имени MSI-файла (105127) можно либо взять из имени файла официального дистрибутива, либо посмотреть в файле Config.kmk в переменной VBOX_SVN_REV_FALLBACK (строка 6170).
  2. Теперь собираем 32-битную версию и пакуем весь комплект в единый инсталлятор. Открываем новую консоль, выполняем команды:
    cd /d C:\Devel\VirtualBox-5.0.14
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7
    set BUILD_TARGET_ARCH=x86
    set INCLUDE=C:\Programs\curl\x32\include;%INCLUDE%
    set LIB=C:\Programs\curl\x32;%LIB%
    set LIBPATH=C:\Programs\curl\x32;%LIBPATH%
    set PATH=C:\Programs\Qt\4.8.7-x32\bin;%PATH%
    set QMAKESPEC=win32-msvc2010
    cscript configure.vbs --with-DDK=C:\WinDDK\7600.16385.1 --with-MinGW-w64=C:\Programs\mingw64 --with-MinGW32=C:\Programs\mingw32 --with-libSDL=C:\Programs\SDL\x32 --with-openssl=C:\Programs\OpenSSL\x32 --with-libcurl=C:\Programs\curl\x32 --with-Qt4=C:\Programs\Qt\4.8.7-x32 --with-python=C:\Programs\Python
    env.bat
    kmk
    kmk C:/Devel/VirtualBox-5.0.14/out/win.x86/release/bin/VirtualBox-5.0.14_OSE-r105127-MultiArch.exe
    
    Аналогично, суффикс »_OSE» в имени итогового файла надо поменять на свой.


Если ни я, ни вы ничего не перепутали, то после всех этих перипетий у вас должен получиться инсталлятор VirtualBox, отличающийся от Oracle-версии только значком исполняемого файла, картинкой в диалоге «О программе» и, конечно же, отключённым hardening’ом. При желании значок и картинку тоже можно поменять, но это тема отдельного разговора.

9f850549b13e79dc47d23f5f9e994379.png Послесловие


Размер статьи оказался неожиданностью для меня самого. Когда я начинал её писать, то намеревался подробно рассказывать, почему на каждом этапе было выбрано то или иное решение, какие конкретно ошибки выскакивают, если не применить очередную правку, и какие могут быть альтернативные подходы к решению этих ошибок. Но постепенно понял, что если бы я всё это описывал, статья получилась бы и вовсе неприподъёмной. Поэтому прошу прощения за встречающийся кое-где стиль «делай так, а почему — не скажу». Сам недолюбливаю такие инструкции, но тут не видел иного выхода. Впрочем, в отдельных местах я всё-таки постарался хотя бы вкратце пояснить суть происходящего.

Огромное количество аспектов сборочной системы VB осталось за кадром: как из-за нежелания раздувать текст, так и по причине моей лени, когда, найдя какой-то обходной путь для очередной проблемы, я не лез в глубины системы сборки, а поскорее переходил к следующему этапу. В конце концов, моей главной задачей было не найти оптимальный путь, а собрать, наконец, свой вариант актуального VirtualBox’а: сидеть на 4.3.12 уже поднадоело, но я не мог обновлять один из своих основных рабочих инструментов на нечто, что в любой момент может просто отказаться работать на неопределённый срок.

Надеюсь всё же, что, несмотря на недостатки, эта статья окажется кому-нибудь полезной. Для тех, кому лень поднимать всё вышеописанное нагромождение программ, но интересно расковырять получающийся в итоге дистрибутив, я выложил инсталлятор сюда. Все драйверы в нём (да и остальные файлы) подписаны недоверенным сертификатом, так что в 64-битной Windows этот вариант VB заработает только в тестовом режиме. Если имеются вопросы, пожелания, предложения — велкам в комментарии или в личку. И да пребудет с вами Open Source!

© Geektimes