为Windows构建VirtualBox


前言


对于Windows版本的VirtualBox(从现在开始, VB ;不要与Visual Basic混淆)的许多用户来说,众所周知的事实是,从4.3.14开始,开发人员添加了所谓的“强化”功能,旨在防止对VB的恶意注入。 尽管用意良好,但实施时却与完全合法的产品(如防病毒软件,加密模块,甚至Windows本身的某些更新)发生了许多冲突,当发生此类冲突时,VB便停止工作。 用户必须等待至少一个月,直到发布新的VB版本并添加适当的排除项。 最坏的情况是,必须卸载有冲突的应用程序或更新,或者必须将VB本身降级为版本4.3.12,这是未经加固的最新版本。 添加用户控制的排除列表或禁用强化选项的许多请求都没有得到答复。 来自开发人员的唯一答复听起来像是“如果您不希望它自己从源代码构建它”。 好吧,看来我们必须这样做。

尽管构建说明已在官方项目Wiki上进行了描述 ,但它们不完整且有些过时,而构建过程通常会因模糊的错误消息而失败。 因此,最后,当我开始使用它时,我认为值得在另一篇文章中进行详细记录。 该指令会不时更新,目前已适应于构建VB版本6.0.4。 但是,如果您需要有关构建早期版本的VB或辅助库的信息,则始终可以从更改历史中获取。

目录

» 问题陈述
» 警告语
» 搭建环境准备
» 应用程序安装怪癖
» 最后润色
» 构建VirtualBox
» 结语
» 修正案

问题陈述


首先,我想通过简化二进制组件并将它们复制到官方发行版安装的版本之上来使其简单。 但是,这远非易事,因为安装依赖于一些晦涩的系统API,并且需要安装驱动程序和COM组件注册。 我想知道学习所有工作原理并编写脚本来自动执行这些任务是否可行,但是经过一番考虑,我决定扩大规模并建立一个尽可能接近官方的完整发行版,只是没有硬化。

我不得不说,事实证明这项任务非常艰巨,我未能100%完成。 我偶然发现的是为Windows(32位和64位),OS / 2,Linux和其他一些* NIX系统提供的Guest Additions。 相应的Makefile中的注释提到它们都是在不同的远程计算机上构建的,我绝对不希望管理这样的构建工厂。 因此,我的最终解决方案是从源代码构建除Additions之外的所有内容,但将它们与官方ISO映像一起使用并按原样放入我的发行版中。 我还没有检查“添加”是否具有相同的强化机制,但是即使它们确实存在,我也从未听说过对此有任何抱怨。

一句警告


•安全注意事项

并不是一时兴起添加强化功能,它是解决VB中漏洞的一种解决方案。 不幸的是,即使Oracle已在多年前修复,但Oracle拒绝提供该问题的详细描述。 通常,它与Windows中的DLL注入机制有关,在VB中,DLL注入机制可能导致主机上未经授权的特权提升,并且存在针对此漏洞的有效利用。 因此,如果您决定仍使用无加固版本,请当心。

•司机签名

从Vista开始,在64位Windows版本中,用户无法再加载任意驱动程序。 驱动程序必须由带有到Microsoft根CA的交叉证书链的证书签名(在启用了安全启动的Windows 10中,驱动程序必须由Microsoft自己签名)。 在开始构建VB之前,您需要确定如何解决此问题。 您可以花一些钱并购买自己的证书,或者尝试与一些为开源项目提供签名服务的第三方公司联系(如果他们同意对易受攻击的驱动程序进行签名),或者将Windows设置为允许加载驱动程序的测试模式使用本地生成的测试证书签名。

在本文中,我将主要隐含后一种情况,但是我将提到如果您拥有“已成年的”商业证书,则程序将如何更改。

建立环境准备


官方指南建议使用Windows 7至10作为构建系统。 我在Windows 7 SP1 x64中完成了所有工作,并且我认为OS版本对程序的影响不大。 请记住,要用于构建VB的计算机(真实或虚拟)必须具有Internet连接。

构建环境需要大量工具。 如果某些程序具有可移植版本,则我更喜欢使用该版本,而不是使用安装程序。

现在,以下程序只能作为可安装的发行版获得(至少是正式发行)。 对于Visual Studio和SDK / WDK,务必遵循以下指定的安装顺序。 完成它们的安装后,我强烈建议运行Windows Update并获取所有Microsoft产品的最新更新。

其他程序作为便携式归档文件或源代码下载:

您还将需要以下档案:

你要这一切做什么?
如果您不想构建与我完全相同的软件包,则可以摆脱某些上述工具。 因此,在此我将详细介绍它们在构建过程中的用途。

  • SDK 8.1
    实际的构建是使用SDK 7.1执行的,但是您将需要使用8.1版的SignTool程序,因为7.1版中的那个无法执行SHA-1 / SHA-256双签名。 如果在其他地方安装了SDK 8.1,则可以从那里复制signtool.exe及其所有依赖项,然后在文件LocalConfig.kmk指定其路径(请参见下文 )。
  • 威克斯
    这是用于创建MSI包的框架。 尽管最终的VB发行版是EXE,但其中包含两个MSI文件,因此您需要WiX来构建它们。 但是,如果仅打算构建VB二进制文件而不打包它们,则可以在没有WiX的情况下进行。
  • Sdl
    该库用于附加的简化的前端VBoxSDL.exe ,可以代替VirtualBox.exe来使用。 从理论上讲,如果您不需要该组件,则无需SDL就可以运行构建,但是我没有尝试过。
  • SOAP
    该库用于构建VBoxWebSrv.exe ,VB远程管理服务。 如果您没有gSOAP,则在构建过程中将静默跳过此组件。
  • libvpx
    这些是用于记录VM屏幕的视频和音频编解码器。 如果没有它们,则构建仍将成功完成,并且VB仍将具有视频捕获的所有选项,但是这些选项将被忽略(即使将播放捕获的动画,也不会保存任何实际的记录) 。
  • 西格温
    构建libvpx所需。
  • MiKTeX
    MiKTeX用于编译PDF文档( doc\UserManual.pdf )。 没有该程序,PDF将在构建和打包时被忽略。
  • 美国宇航局
    构建OpenSSL时使用的汇编程序。 您也可以不使用汇编程序来构建它,但是我仍然建议使用它来生成更优化的代码。

这是我正在使用的所有工具和库的摘要,包括它们的确切版本(如果可能)以及在构建系统上选择的安装路径。 名称“ {x32|x64} ”用于单独的32位和64位版本安装位置。
程序/工具版本号安装路径
视觉工作室2010专业C:\Program Files (x86)\Microsoft Visual Studio 10.0\
开发包7.1C:\Program Files\Microsoft SDKs\Windows\v7.1\
开发包8.1C:\Programs\DevKits\8.1\
Wdk7.1.0C:\WinDDK\7600.16385.1\
Activeperl5.26.1内部版本2601 x64C:\Programs\Perl\
ActivePython的2.7.14.2717 x64C:\Programs\Python\
威克斯3.11.1.2318C:\Programs\WiX\
t5.6.3C:\Programs\Qt\5.6.3-{x32|x64}\
MinGW-324.5.4C:\Programs\mingw32\
MinGW-644.5.4C:\Programs\mingw64\
西格温--C:\Programs\cygwin64\
Sdl1.2.15C:\Programs\SDL\{x32|x64}\
网址7.64.1C:\Programs\curl\{x32|x64}\
Openssl1.1.1bC:\Programs\OpenSSL\{x32|x64}\
SOAP2.8.82C:\Programs\gSOAP\
libvpx1.7.0C:\Programs\libvpx\
天秤座1.3C:\Programs\libopus\
MiKTeX便携式2.9.6942C:\Programs\MiKTeX\
美国宇航局2.14.02 x64C:\Programs\nasm\
DocBook XML DTD4.5C:\Programs\DocBook\xml\
DocBook XSL样式表1.69.1C:\Programs\DocBook\xsl\

应用程序安装怪癖


在这里,我提供了一些上述工具的安装说明,其中该过程不明显或需要采取其他措施。

•Windows SDK v7.1
此SDK的安装可能会失败,因为它包含编译器和运行时库的过时版本。 安装VS 2010之后,系统中会存在这些版本的较新版本,因此较旧的版本将无法安装,因此主安装程序将其视为严重错误。 要解决此问题,您需要取消选中相应的复选框,或者在安装SDK之前,先卸载名为“ Microsoft Visual C ++ 2010 <arch>可再发行组件”“ Microsoft Visual C ++ 2010 <arch>运行时”“ Microsoft Visual C ++编译器...” 让SDK安装旧版本的SDK,然后运行Windows Update以获得最新的可用版本。

安装SDK时,请确保检查程序示例(Windows本机代码开发->示例):它们包含VB构建规则使用的一些脚本。 没有它们,您将无法构建MSI软件包。

•Windows SDK v8.1
您只需要安装组件“ Windows Software Development Kit”。

•WDK v7.1
您只需要安装组件“ Build Environments”。

•Qt 5.6.3
从Qt 5.7.0开始,要构建它,您需要Visual Studio 2012或更高版本,因此我们只能使用5.6.x。
由于没有用于Visual Studio 2010的正式版本,因此我们必须根据源代码自行构建Qt。

  1. 将Qt源代码归档文件解压缩到C:\Programs\Qt\ ,并将目录qt-everywhere-opensource-src-5.6.3重命名为5.6.3-src
  2. 在它旁边创建一个目录build-x32 ,将在其中进行构建。
  3. 打开控制台并运行以下命令以准备环境:
     cd /d C:\Programs\Qt\build-x32 SET QTVER=5.6.3 "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7 COLOR 07 SET QTDIR=C:\Programs\Qt\%QTVER%-x32 SET PATH=%QTDIR%\bin;%PATH% SET QMAKESPEC=win32-msvc2010 
    color命令是可选的,它摆脱了由脚本SetEnv.Cmd设置的绿色。
  4. 现在,我们需要从5.6.3-src运行configure.bat脚本。 VB不使用Qt包含的大部分内容,因此我们可以通过禁用各种组件来显着减少构建时间,但是请注意,某些选项对于VB至关重要。 特别是,我发现:
    • 不支持OpenGL ES 2(在构建VB时,编译器无法找到某些头文件)。
    • 必须启用FreeType支持(否则将不会构建插件qoffscreen ,而VB则需要此插件)。
    这是我最终得到的完整命令行:
     ..\5.6.3-src\configure.bat -prefix c:\Programs\Qt\5.6.3-x32 -mp -opensource -confirm-license -nomake tests -nomake examples -no-compile-examples -release -shared -pch -no-ltcg -accessibility -no-sql-sqlite -opengl desktop -no-openvg -no-nis -no-iconv -no-evdev -no-mtdev -no-inotify -no-eventfd -largefile -no-system-proxies -qt-zlib -qt-pcre -no-icu -qt-libpng -qt-libjpeg -qt-freetype -no-fontconfig -qt-harfbuzz -no-angle -incredibuild-xge -no-plugin-manifests -qmake -qreal double -rtti -strip -no-ssl -no-openssl -no-libproxy -no-dbus -no-audio-backend -no-wmf-backend -no-qml-debug -no-direct2d -directwrite -no-style-fusion -native-gestures -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcanvas3d -skip qtconnectivity -skip qtdeclarative -skip qtdoc -skip qtenginio -skip qtgraphicaleffects -skip qtlocation -skip qtmacextras -skip qtmultimedia -skip qtquickcontrols -skip qtquickcontrols2 -skip qtscript -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtx11extras -skip qtxmlpatterns 
  5. 此处指定的Qt安装路径(在-prefix选项中)由configure脚本硬编码到中间源代码文件中,因此二进制文件也将记住它。 使用此库构建的任何基于Qt的应用程序都将首先在该路径中搜索所需的插件,并且只有在找不到它们的情况下,它才会使用其自己的当前位置。 在大多数情况下,这是可以的,但是假设在安装我们的VB的计算机上,还有另一个Qt版本位于c:\Programs\Qt\5.6.3-x32 ,但是使用不同的选项或由不同的编译器进行编译? 然后,VB将尝试加载那些(不兼容的)插件并崩溃。
    有两种可能的方法来避免此问题。 首先是在安装中添加一个名为qt.conf的附加文件,其内容如下:
     [Paths] Plugins=. 
    另一种是在构建Qt之前修复保存的安装路径,以便它指向应用程序的目录。 我决定采用后一种方式,我不喜欢在Oracle VB发行版本中增加文件的想法。 您需要打开由配置脚本创建的文件C:\Programs\Qt\build-x32\qtbase\src\corelib\global\qconfig.cpp ,找到以下行:
     static const char qt_configure_prefix_path_str [512 + 12] = "qt_prfxpath=c:/Programs/Qt/5.6.3-x32"; 
    并用单个点替换路径,因此该行如下所示:
     static const char qt_configure_prefix_path_str [512 + 12] = "qt_prfxpath=."; 
    此更改将仅影响VB的运行时行为。 Qt本身的安装步骤将使用原始路径,因为它现在存储在我们不修改的Makefile中。
  6. 接下来,使用命令nmake运行构建
  7. 并使用nmake install内置库

现在打开一个新的控制台窗口,并对64位版本执行相同的操作。 您需要在所有路径中将“ x32”替换为“ x64”,环境准备命令将如下所示:
 md C:\Programs\Qt\build-x64 cd /d C:\Programs\Qt\build-x64 SET QTVER=5.6.3 "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7 COLOR 07 SET QTDIR=C:\Programs\Qt\%QTVER%-x64 SET PATH=%QTDIR%\bin;%PATH% SET QMAKESPEC=win32-msvc2010 

安装完成后,可以删除目录build-x32build-x645.6.3-src

•MinGW
只需将32位和64位归档文件解压缩到各自的安装目录中。

•Cygwin
在安装期间,您需要选择软件包makeyasm

•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\x86x64
  3. 对32位版本执行相同的操作:将内容从C:\Programs\SDL\x32\lib\x86\移至C:\Programs\SDL\x32\lib\ ,然后删除C:\Programs\SDL\x64\lib\x86x64

•NASM
将档案nasm-2.14.02-win64.zip解压缩到C:\Programs\ ,然后将结果目录nasm-2.14.02重命名为nasm

•OpenSSL
  1. 两次将OpenSSL存档解压缩到C:\Programs\OpenSSL\ ,将目录openssl-1.1.1b的副本重命名为openssl-1.1.1b-x32openssl-1.1.1b-x64
  2. 打开控制台,运行以下命令来构建并安装32位版本:
     "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7 COLOR 07 set PATH=%PATH%;C:\Programs\nasm cd /d C:\Programs\OpenSSL\openssl-1.1.1b-x32\ perl Configure VC-WIN32 no-shared --prefix=C:\Programs\OpenSSL\x32 --openssldir=C:\Programs\OpenSSL\x32\ssl nmake nmake test nmake install 
    如果configure步骤输出有关缺少编译器的可怕警告,请忽略此消息,它是在撒谎。
    如果您不想使用NASM,只需跳过修改PATH的命令,并为Configure脚本指定其他参数no-asm
  3. 现在打开一个新的控制台窗口,并对64位版本执行相同的操作:
     "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7 COLOR 07 set PATH=%PATH%;C:\Programs\nasm cd /d C:\Programs\OpenSSL\openssl-1.1.1b-x64\ perl Configure VC-WIN64A no-shared --prefix=C:\Programs\OpenSSL\x64 --openssldir=C:\Programs\OpenSSL\x64\ssl nmake nmake test nmake install 
    禁用NASM与在32位中相同。
  4. 现在您可以删除目录C:\Programs\OpenSSL\openssl-1.1.1b-x32openssl-1.1.1b-x64

•cURL
  1. 将cURL归档文件解压缩到C:\Programs\curl\ ,并将结果子目录curl-7.64.1重命名为curl-7.64.1-x32
  2. 在文本编辑器中打开文件C:\Programs\curl\curl-7.64.1-x32\winbuild\MakefileBuild.vc ,然后查找以下代码块(第61–69行):
     !IF "$(VC)"=="6" CC_NODEBUG = $(CC) /O2 /DNDEBUG CC_DEBUG = $(CC) /Od /Gm /Zi /D_DEBUG /GZ CFLAGS = /I. /I../lib /I../include /nologo /W4 /wd4127 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL !ELSE CC_NODEBUG = $(CC) /O2 /DNDEBUG CC_DEBUG = $(CC) /Od /D_DEBUG /RTC1 /Z7 /LDd CFLAGS = /I. /I ../lib /I../include /nologo /W4 /wd4127 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL !ENDIF 
    在这些行之后添加新指令:
     CFLAGS = $(CFLAGS) /DCURL_DISABLE_LDAP 
    如果您不这样做,则VB的构建将因链接错误而失败。
  3. 现在打开文件C:\Programs\curl\curl-7.64.1-x32\winbuild\gen_resp_file.bat ,然后在第一行( @echo OFF )之后插入以下命令:
     cd . 
    它不执行任何操作,除了重置ERRORLEVEL代码。 该脚本非常简单,可以在不运行任何会更改错误代码的命令的情况下完成该脚本。 因此,如果在启动脚本之前该代码非零,它将在脚本出口处保留其值,而nmake认为是脚本返回了此错误代码,并以失败终止了构建。 添加该伪造的cd可解决此问题。
  4. 现在,以curl-7.64.1-x64的名称制作curl-7.64.1-x32的完整副本。
  5. 打开控制台,构建32位版本并复制我们需要的文件:
     "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7 COLOR 07 cd /d C:\Programs\curl\curl-7.64.1-x32\winbuild md C:\Programs\curl\x32 nmake /f Makefile.vc mode=static WITH_SSL=static DEBUG=no MACHINE=x86 SSL_PATH=C:\Programs\OpenSSL\x32 ENABLE_SSPI=no ENABLE_WINSSL=no ENABLE_IDN=no copy ..\builds\libcurl-vc-x86-release-static-ssl-static-ipv6\lib\libcurl_a.lib ..\..\x32\libcurl.lib xcopy /E ..\builds\libcurl-vc-x86-release-static-ssl-static-ipv6\include\curl ..\..\x32\include\curl\ 
  6. 打开另一个控制台窗口并构建64位版本:
     "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7 COLOR 07 cd /d C:\Programs\curl\curl-7.64.1-x64\winbuild md C:\Programs\curl\x64 nmake /f Makefile.vc mode=static WITH_SSL=static DEBUG=no MACHINE=x64 SSL_PATH=C:\Programs\OpenSSL\x64 ENABLE_SSPI=no ENABLE_WINSSL=no ENABLE_IDN=no copy ..\builds\libcurl-vc-x64-release-static-ssl-static-ipv6\lib\libcurl_a.lib ..\..\x64\libcurl.lib xcopy /E ..\builds\libcurl-vc-x64-release-static-ssl-static-ipv6\include\curl ..\..\x64\include\curl\ copy ..\builds\libcurl-vc-x64-release-static-ssl-static-ipv6\bin\curl.exe ..\..\x64\curl.exe 
    请注意,除了对32位版本执行的操作之外,这里还复制了curl.exe文件。 稍后我们将使用它来下载来宾添加图像。
  7. 目录C:\Programs\curl\curl-7.64.1-x32curl-7.64.1-x64不再需要,可以删除。

•libvpx
  1. 将libvpx存档解压缩到C:\Programs\libvpx-build\
  2. 启动Cygwin终端,将在此处执行构建。 我们的目标平台是Visual Studio 2010。 构建系统仅部分支持它:它将尝试使用msbuild.exe运行实际的构建,但由于某些原因而无法运行; 我没找到原因。 相反,我们可以简单地运行Visual Studio本身并将其用于构建项目。 幸运的是,可以从命令行使用它,因此不必启动实际的IDE(尽管您可以,但是在这种情况下,您必须修改PATH变量并添加路径C:\Programs\cygwin64\bin ,或以其他任何方式允许VS查找位于此处并为构建所需的yasm.exe )。 因此,要执行这两种体系结构的构建,请在Cygwin终端中运行以下命令:
     mkdir -p /cygdrive/c/Programs/libvpx-build/build32 cd /cygdrive/c/Programs/libvpx-build/build32 ../libvpx-1.7.0/configure --target=x86-win32-vs10 --disable-install-bins --disable-examples --disable-tools --disable-docs --prefix=../../libvpx make "/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 10.0/Common7/IDE/devenv.com" vpx.sln /Project vpx.vcxproj /Rebuild "Release|Win32" make install mkdir -p /cygdrive/c/Programs/libvpx-build/build64 cd /cygdrive/c/Programs/libvpx-build/build64 ../libvpx-1.7.0/configure --target=x86_64-win64-vs10 --disable-install-bins --disable-examples --disable-tools --disable-docs --prefix=../../libvpx make "/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 10.0/Common7/IDE/devenv.com" vpx.sln /Project vpx.vcxproj /Rebuild "Release|x64" make install 
  3. 关闭Cygwin,我们将不再需要它。 可以删除目录C:\Programs\libvpx-build

•天秤座
  1. 将opus归档文件解压缩到C:\Programs\libopus-build\ ,进入子目录opus-1.3\win32\VS2015
  2. 该项目是为较新的Visual Studio版本设计的,因此我们需要对其进行修改以使其在我们的版本2010中进行构建。您可以使用IDE或纯文本编辑器来进行此操作。 我选择了后者。 打开文件opus.vcxproj并执行以下操作:
    1. 查找包含文本的所有行
       <PlatformToolset>v140</PlatformToolset> 
      并将v140替换为v100 。 如果使用的是IDE,这是配置选项“ Platrofm Toolset”,位于“配置属性”->“常规”页面上。 不要忘记对话框顶部的“配置”和“平台”选择器。
    2. 接下来,查找以下代码块:
        <ItemDefinitionGroup> <ClCompile> 
      并在其中添加一个新标签:
        <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> 
      在IDE中,您可以打开页面“配置属性”->“ C / C ++”->“常规”,然后将“调试信息格式”设置为“ ProgramDatabase(/ Zi)”。 实际上,您可以将其设置为任何其他有效值,我们根本不需要调试数据库,但是如果使用无效值,则该项目将无法构建。
  3. 现在,我们为两个平台构建发布版本(使用VS IDE或命令行),然后将库opus.lib和子目录include\复制到我们的目标路径中:
     cd /d C:\Programs\libopus-build\opus-1.3\win32\VS2015 md C:\Programs\libopus\lib\x64 md C:\Programs\libopus\lib\Win32 xcopy /EC:\Programs\libopus-build\opus-1.3\include C:\Programs\libopus\include\ "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com" opus.sln /Project opus.vcxproj /Rebuild "Release|x64" copy x64\Release\opus.lib C:\Programs\libopus\lib\x64\ "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com" opus.sln /Project opus.vcxproj /Rebuild "Release|Win32" copy Win32\Release\opus.lib C:\Programs\libopus\lib\Win32\ 
  4. 可以删除目录C:\Programs\libopus-build

•gSOAP
打开档案,进入子目录gsoap-2.8\gsoap并将其内容解压缩到C:\Programs\gSOAP\ 。 OpenSSL 1.1.x要求使用gSOAP 2.8.41或更高版本。 如果出于某些原因要使用旧版本,则需要应用Mattias Ellert创建的补丁 。 修补程序可以手动完成(格式很简单:打开提到的文件,删除标有减号的行,添加标有加号的行;其余为上下文),或者将patch工具移植到Windows并使用。

•MiKTeX
  1. 将档案解压缩到C:\Programs\MiKTeX\
  2. 打开控制台并安装其他模块:
     "C:\Programs\MiKTeX\texmfs\install\miktex\bin\mpm.exe" --verbose --install=koma-script --install=ucs --install=tabulary --install=url --install=fancybox --install=fancyvrb --install=bera --install=charter --install=mptopdf 

•DocBook
对于XML DTD,您需要创建目录并在其中解压缩存档内容。 对于XSL样式表,所有内容已经在一个目录中,因此您需要提取该目录并随后对其进行重命名。

最后的润色


构建环境几乎已准备就绪,仅需要执行几个步骤。 下载VirtualBox源代码存档(如果尚未完成),然后将其解压缩到您要使用的位置。 为此,我选择了C:\Devel\ ,将解压后的源代码放入其中,并将子目录重命名为VirtualBox-src

•添加证书

如果您没有付费证书,建议您至少创建一个自签名的个人证书:与未签名的驱动程序相比,使Windows加载自签名的驱动程序更容易。 为此,请以提升的特权打开控制台,然后运行以下命令,这将添加两个证书(SHA-1和SHA-256)并将其导入您的个人存储中:
 "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7 COLOR 07 makecert.exe -a sha1 -r -pe -ss my -n "CN=Roga and Kopyta Ltd" C:\Devel\testcert_1.cer makecert.exe -a sha256 -r -pe -ss my -n "CN=Roga and Kopyta Ltd" C:\Devel\testcert_256.cer certmgr.exe -add C:\Devel\testcert_1.cer -s -r localMachine root certmgr.exe -add C:\Devel\testcert_256.cer -s -r localMachine root 
当然,您可以选择自己的证书名称,而不是“ Roga and Kopyta Ltd”,以及存储文件的路径。 现在,我们需要获取生成的证书的指纹。 打开证书管理控制台(通过运行certmgr.msc )并导航到个人存储。 您将在此处看到两个名为“ Roga and Kopyta Ltd”的新证书。 双击第一个; 在出现的对话框中,转到“ 详细信息”选项卡。 “签名算法”字段包含算法名称:sha256RSA或sha1RSA。 向下滚动到“缩略图”字段,其中包含十六进制数字的序列。 复制此完整值并将其写下来。 对第二个证书执行相同的操作; 不要忘记标记哪个指纹适用于SHA-1,哪个指纹适用于SHA-256。

•构建xmllint

构建步骤之一将需要xmllint程序。 我没有将其放入构建要求列表中,因为它的源代码捆绑在VirtualBox存档中。 但是您仍然必须自己构建它,因为VB的构建规则不会这样做。 我选择C:\Programs\xmllint作为目标目录。
  1. 将目录C:\Devel\VirtualBox-src\src\libs\libxml2-2.9.4复制到C:\Programs\ ,以确保其构建不会以任何方式影响VB。
  2. 打开控制台并运行以下命令:
     "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7 COLOR 07 cd /d C:\Programs\libxml2-2.9.4\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.4

•VB文件的修改

在开始构建之前,我们还需要对VB源代码进行一些更改。 它们的完整集合在此处显示为可下载的补丁文件,可以手动应用,也可以使用patch工具(需要单独下载)来应用它们:

» Vbox_build.patch

如果应用补丁程序没有问题,您可以跳到下一步 。 但是,如果您遇到一些问题并且需要有关特定更改的更多信息,或者只是想了解更改的内容和原因,欢迎继续阅读下面提供的详细信息。 请注意,与修补程序文件相比,此处更改的顺序不同。 文件的路径是相对于VB源代码目录C:\Devel\VirtualBox-src
  1. 文件configure.vbs
    • 代码行:
       if Shell(DosSlashes(strPathVC & "/bin/cl.exe"), True) <> 0 then 
      替换为:
       if Shell(DosSlashes(strPathVC & "/bin/cl.exe") & " /?", True) <> 0 then 
      该行执行编译器检查,但它会忽略没有任何参数的cl.exe返回错误,因此被视为无效的编译器。 添加“ /? “参数使它输出帮助,并以非错误代码0退出。
    • 现在,让我们跳到CheckForMinGW32Sub函数。 顾名思义,它检查32位MinGW的有效性。 但是,它是为版本3.3.3设计的,而我使用的是具有不同文件/目录结构的4.5.4,因此,我用以下代码替换了整个功能(基本上只是CheckForMinGWw64Sub的副本,适用于32位变体):
       function CheckForMinGW32Sub(strPathMingW32, strPathW32API) g_strSubOutput = "" if strPathW32API = "" then strPathW32API = strPathMingW32 LogPrint "trying: strPathMingW32=" &strPathMingW32 & " strPathW32API=" & strPathW32API if LogFileExists(strPathMingW32, "bin/gcc.exe") _ And LogFileExists(strPathMingW32, "bin/ld.exe") _ And LogFileExists(strPathMingW32, "bin/objdump.exe") _ And LogFileExists(strPathMingW32, "bin/dllwrap.exe") _ And LogFileExists(strPathMingW32, "bin/dlltool.exe") _ And LogFileExists(strPathMingW32, "bin/as.exe") _ And LogFileExists(strPathMingW32, "include/bfd.h") _ And LogFileExists(strPathMingW32, "lib32/libgcc_s.a") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/lib/dllcrt1.o") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/lib/dllcrt2.o") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/lib/libmsvcrt.a") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/lib/libmsvcr100.a") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/include/_mingw.h") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/include/stdint.h") _ And LogFileExists(strPathMingW32, "i686-w64-mingw32/include/windows.h") _ then if Shell(DosSlashes(strPathMingW32 & "/bin/gcc.exe") & " -dumpversion", True) = 0 then dim offVer, iMajor, iMinor, iPatch, strVer ' extract the version. strVer = Trim(Replace(Replace(g_strShellOutput, vbCr, ""), vbLf, "")) if (Mid(strVer, 2, 1) = ".") _ And (Mid(strVer, 4, 1) = ".") then iMajor = Int(Left(strVer, 1)) ' Is Int() the right thing here? I want atoi()!!! iMinor = Int(Mid(strVer, 3, 1)) iPatch = Int(Mid(strVer, 5)) else LogPrint "Malformed version: '" & strVer & "'" strVer = "" end if if strVer <> "" then if (iMajor = 4) And (iMinor >= 4) then CheckForMinGW32Sub = True g_strSubOutput = strVer else LogPrint "MinGW32 version '" & iMajor & "." & iMinor & "." & iPatch & "' is not supported (or configure.vbs failed to parse it correctly)." end if else LogPrint "Couldn't locate the GCC version in the output!" end if else LogPrint "Failed to run gcc.exe!" end if end if end function 
    • 我们的下一个函数是CheckForCurlSub ,要编辑的代码块是:
        if LogFileExists(strPathCurl, "include/curl/curl.h") _ And LogFindFile(strPathCurl, "libcurl.dll") <> "" _ And LogFindFile(strPathCurl, "libcurl.lib") <> "" _ 
      它检查libcurl的有效性,但是它需要动态链接的版本,并且如果找不到DLL文件,则会失败。 我们使用的是静态链接版本,因此可悲的是,必须对DLL进行检查:
        if LogFileExists(strPathCurl, "include/curl/curl.h") _ And LogFindFile(strPathCurl, "libcurl.lib") <> "" _ 
    • 现在进入CheckForPython函数,其中将生成变量VBOX_BLD_PYTHON
        CfgPrint "VBOX_BLD_PYTHON := " & strPathPython & "\python.exe" 
      python.exe前面的反斜杠应替换为正"/python.exe""/python.exe" (如果没有此修复,则在构建过程中进行的某些检查将失败;我没有注意到任何其他不良影响,但它更漂亮没有失败消息,并且在任何情况下都比后悔更安全)。
    • Windows版本的configure脚本不支持libvpx和libopus,因此我自己添加了它们。 当然,最简单的方法就是硬编码到库的路径,但是我更喜欢像所有其他组件一样实现它,并在命令行中传递路径并进行适当的有效性检查。 主要代码包括两个检查功能:
       '' ' Checks for libvpx sub CheckForVpx(strOptVpx) dim strPathVpx, str strVpx = "libvpx" PrintHdr strVpx if strOptVpx = "" then MsgError "Invalid path specified!" exit sub end if if g_strTargetArch = "amd64" then strVsBuildArch = "x64" else strVsBuildArch = "Win32" end if strLibPathVpx = "lib/" & strVsBuildArch & "/vpxmd.lib" strPathVpx = "" if LogFileExists(strOptVpx, "include/vpx/vpx_encoder.h") _ And LogFileExists(strOptVpx, strLibPathVpx) _ then strPathVpx = UnixSlashes(PathAbs(strOptVpx)) CfgPrint "SDK_VBOX_VPX_INCS := " & strPathVpx & "/include" CfgPrint "SDK_VBOX_VPX_LIBS := " & strPathVpx & "/" & strLibPathVpx else MsgError "Can't locate " & strVpx & ". " _ & "Please consult the configure.log and the build requirements." exit sub end if PrintResult strVpx, strPathVpx end sub '' ' Checks for libopus sub CheckForOpus(strOptOpus) dim strPathOpus, str strOpus = "libopus" PrintHdr strOpus if strOptOpus = "" then MsgError "Invalid path specified!" exit sub end if if g_strTargetArch = "amd64" then strVsBuildArch = "x64" else strVsBuildArch = "Win32" end if strLibPathOpus = "lib/" & strVsBuildArch & "/opus.lib" strPathOpus = "" if LogFileExists(strOptOpus, "include/opus.h") _ And LogFileExists(strOptOpus, strLibPathOpus) _ then strPathOpus = UnixSlashes(PathAbs(strOptOpus)) CfgPrint "SDK_VBOX_OPUS_INCS := " & strPathOpus & "/include" CfgPrint "SDK_VBOX_OPUS_LIBS := " & strPathOpus & "/" & strLibPathOpus else MsgError "Can't locate " & strOpus & ". " _ & "Please consult the configure.log and the build requirements." exit sub end if PrintResult strOpus, strPathOpus end sub 
      该函数usage用于打印命令行参数列表。 在此处附加我们的两个新参数:
        Print " --with-libvpx=PATH " Print " --with-libopus=PATH " 
      在函数的开头,定义了许多用于存储组件路径的变量,我们需要在其中添加两个新变量:
        strOptVpx = "" strOptOpus = "" 
      再往下一点, select-case块将处理参数并填充变量。 添加我们的贡献:
        case "--with-libvpx" strOptVpx = strPath case "--with-libopus" strOptOpus = strPath 
      最后,几乎在文件的最后,有所有这些check函数调用的链,这是我们在其中添加对两个新函数的调用的地方:
        CheckForVpx strOptVpx CheckForOpus strOptOpus 
  2. 下一个文件是src\VBox\Runtime\Makefile.kmk 。 我们需要找到变量VBoxRT_LIBS.winVBoxRT-x86_LIBS.win的定义,并向其中添加两个新库crypt32.libbcrypt.lib 。 所以下面的代码:
     VBoxRT_LIBS.win = \ $(PATH_SDK_$(VBOX_WINDDK)_LIB)/vccomsup.lib \ $(PATH_SDK_$(VBOX_WINDDK)_LIB)/wbemuuid.lib \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib 
    变成:
     VBoxRT_LIBS.win = \ $(PATH_SDK_$(VBOX_WINDDK)_LIB)/vccomsup.lib \ $(PATH_SDK_$(VBOX_WINDDK)_LIB)/wbemuuid.lib \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib \ $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/crypt32.lib \ $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/bcrypt.lib 
    (不要错过delayimp.lib之后的delayimp.lib !); 并且分别是:
     VBoxRT-x86_LIBS.win = \ $(PATH_SDK_$(VBOX_WINDDK)_LIB.x86)/vccomsup.lib \ $(PATH_SDK_$(VBOX_WINDDK)_LIB.x86)/wbemuuid.lib \ $(PATH_TOOL_$(VBOX_VCC_TOOL_STEM)X86_LIB)/delayimp.lib 
    变成:
     VBoxRT-x86_LIBS.win = \ $(PATH_SDK_$(VBOX_WINDDK)_LIB.x86)/vccomsup.lib \ $(PATH_SDK_$(VBOX_WINDDK)_LIB.x86)/wbemuuid.lib \ $(PATH_TOOL_$(VBOX_VCC_TOOL_STEM)X86_LIB)/delayimp.lib \ $(PATH_SDK_$(VBOX_WINPSDK)_LIB.x86)/crypt32.lib \ $(PATH_SDK_$(VBOX_WINPSDK)_LIB.x86)/bcrypt.lib 
    成功连接VBoxRT.dll需要此更改。 我不是100%知道为什么会这样,Oracle版本在crypt32.dll上没有加载时依赖性,它是在运行时加载的,因此不需要LIB文件。 但是,如果没有链接器,链接器将无法找到某些功能,并且会失败。 我怀疑它可能与OpenSSL构建选项有关,但是我没有检查过,添加依赖项比较容易。 第二个依赖性bcrypt.dll是新的OpenSSL 1.1.1的要求。
  3. 如果您具有gSOAP 2.8.79或更高版本,则必须编辑文件src\VBox\Runtime\r3\win\VBoxRT-openssl-1.1plus.def并将以下行添加到导出列表中:
      OpenSSL_version_num DH_generate_parameters_ex DH_new ASN1_STRING_get0_data 
    此列表定义了库VBoxRT.dll (其中包含OpenSSL)导出的功能。 当链接VBoxWebSrv.exe工具时,根据gSOAP版本的不同,它可能需要其他OpenSSL功能。 由于它们在导出列表中丢失,因此链接器会添加OpenSSL本身,并立即抱怨该外部OpenSSL与自己已内置在VBoxRT的副本之间存在大量冲突。 添加上述出口解决了该问题。
  4. 正如我在一开始提到的那样,我没有构建来宾添加项,但是我确实需要将其ISO映像作为分发的一部分。 构建规则是为这种情况而设计的,但是他们希望可以在正确的时间在正确的位置神奇地显示准备好的ISO映像。 我已经将此魔术添加到文件src\VBox\Makefile.kmk 。 查找以下代码:
      ifdef VBOX_WITH_ADDITIONS include $(PATH_SUB_CURRENT)/Additions/Makefile.kmk endif 
    在其正下方的是自动下载图像文件的规则:
      ifndef VBOX_WITHOUT_ADDITIONS_ISO $(VBOX_PATH_ADDITIONS_ISO)/VBoxGuestAdditions.iso: $(QUIET)$(MKDIR) -p $(@D) $(VBOX_RETRY) $(TOOL_CURL_FETCH) http://download.virtualbox.org/virtualbox/$(VBOX_VERSION_STRING_RAW)/VBoxGuestAdditions_$(VBOX_VERSION_STRING_RAW).iso -o $@ endif 
    如果您手动编辑文件而不是应用补丁,请注意,规则命令必须以制表符开头。
  5. 在6.0版之前,文档是无需进行任何更改即可成功构建的子系统之一。 我不知道这有什么问题,但是对它进行了重大的重新设计,以使其不再适用于我的构建系统。 我不知道Oracle自己如何构建文档(也许是在* NIX系统上),但是对我而言,构建规则使路径中的斜杠丢失,或者添加了过多的斜杠,结果,它们无法找到目标文件。由于目录文件不匹配。 我终于设法合并了一些更改,这些更改允许构建文档而不会出错。 首先,缺少目标目录之一,因此无法创建某些中间文件。 此问题已在以下代码块内的文件doc\manual\Makefile.kmk修复:
     define def_vbox_refentry_to_user_sect1 $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/user_$(2): $(3) \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-sect1.xsl \ $$(VBOX_XML_CATALOG) $$(VBOX_XML_CATALOG_DOCBOOK) $$(VBOX_XML_CATALOG_MANUAL) \ $$(VBOX_VERSION_STAMP) | $$(dir $$@) $$(call MSG_TOOL,xsltproc $$(notdir $$(filter %.xsl,$$^)),,$$(filter %.xml,$$^),$$@) $$(QUIET)$$(RM) -f "$$@" $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) --output $$@ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-sect1.xsl $$< endef 
    $$(RM)之后,我添加了一个用于创建缺少的目录的命令:
      $$(QUIET)$$(MKDIR) -p "$$(@D)" 

    至于斜线,修复程序位于doc\manual\Config.kmk文件中。 我无法为此找到“正常”的解决方案,但是有一种可行的解决方法足以满足实际用途,这意味着为错误的路径复制路径替换规则。 首先,在该行下方:
      VBOX_FILE_URL_MAYBE_SLASH = $(if $(eq $(KBUILD_HOST),win),/,) 
    I've created two new variables which basically contain the same paths as their origins, but with triple slash after the disk letter instead of a single slash:
      VBOX_PATH_MANUAL_SRC_SLASHED = $(subst :/,:///,$(VBOX_PATH_MANUAL_SRC)) VBOX_PATH_MANUAL_OUTBASE_SLASHED = $(subst :/,:///,$(VBOX_PATH_MANUAL_OUTBASE)) 
    A little bit below that, there is a rule for creating the catalog file:
      $(VBOX_XML_CATALOG): $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_L1,Creating catalog $@) $(QUIET)$(APPEND) -tn "$@" \ '<?xml version="1.0"?>' \ '<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">' \ '<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">' \ ' <delegatePublic publicIdStartString="-//OASIS/ENTITIES DocBook XML" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegatePublic publicIdStartString="-//OASIS/DTD DocBook XML" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegateSystem systemIdStartString="http://www.oasis-open.org/docbook/" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegateURI uriStartString="http://www.oasis-open.org/docbook/" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegateSystem systemIdStartString="$(VBOX_PATH_MANUAL_SRC)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="$(VBOX_PATH_MANUAL_SRC)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_PATH_MANUAL_SRC)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="$(VBOX_PATH_MANUAL_OUTBASE)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ '</catalog>' 
    For each line which contains the variable VBOX_PATH_MANUAL_SRC or VBOX_PATH_MANUAL_OUTBASE (except for the line with the file:// prefix), I've appended the copy of the whole line, but with the variable replaced with its triple-slash counterpart. The result looks like this:
      $(VBOX_XML_CATALOG): $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_L1,Creating catalog $@) $(QUIET)$(APPEND) -tn "$@" \ '<?xml version="1.0"?>' \ '<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">' \ '<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">' \ ' <delegatePublic publicIdStartString="-//OASIS/ENTITIES DocBook XML" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegatePublic publicIdStartString="-//OASIS/DTD DocBook XML" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegateSystem systemIdStartString="http://www.oasis-open.org/docbook/" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegateURI uriStartString="http://www.oasis-open.org/docbook/" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_DOCBOOK)"/>' \ ' <delegateSystem systemIdStartString="$(VBOX_PATH_MANUAL_SRC)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateSystem systemIdStartString="$(VBOX_PATH_MANUAL_SRC_SLASHED)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="$(VBOX_PATH_MANUAL_SRC)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="$(VBOX_PATH_MANUAL_SRC_SLASHED)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_PATH_MANUAL_SRC)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="$(VBOX_PATH_MANUAL_OUTBASE)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ ' <delegateURI uriStartString="$(VBOX_PATH_MANUAL_OUTBASE_SLASHED)" catalog="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_XML_CATALOG_MANUAL)"/>' \ '</catalog>' 
    Even further down, there is another rule for creating an auxiliary catalog file; the starting line is:
      $(VBOX_XML_CATALOG_MANUAL): $(MAKEFILE_CURRENT) | $$(dir $$@) 
    Here I'm doing the same operation as above. In addition, in the beginning of the generated file there are several lines defining the entries in the common/ subdirectory:
      ' <system systemId="$(VBOX_PATH_MANUAL_SRC)/common/oracle-accessibility-en.xml" uri="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_PATH_MANUAL_SRC)/en_US/oracle-accessibility-en.xml"/>' \ ' <system systemId="$(VBOX_PATH_MANUAL_SRC)/common/oracle-support-en.xml" uri="file://$(VBOX_FILE_URL_MAYBE_SLASH)$(VBOX_PATH_MANUAL_SRC)/en_US/oracle-support-en.xml"/>' \ 
    With these we have the opposite problem: triple slash after the file is replaced with a single slash. I worked this around by getting rid of the file protocol altogether and replacing those URIs with direct file system paths in the target address (the uri attribute). The result for these lines looks like this (including the aforementioned fix):
      ' <system systemId="$(VBOX_PATH_MANUAL_SRC)/common/oracle-accessibility-en.xml" uri="$(VBOX_PATH_MANUAL_SRC)/en_US/oracle-accessibility-en.xml"/>' \ ' <system systemId="$(VBOX_PATH_MANUAL_SRC_SLASHED)/common/oracle-accessibility-en.xml" uri="$(VBOX_PATH_MANUAL_SRC)/en_US/oracle-accessibility-en.xml"/>' \ ' <system systemId="$(VBOX_PATH_MANUAL_SRC)/common/oracle-support-en.xml" uri="$(VBOX_PATH_MANUAL_SRC)/en_US/oracle-support-en.xml"/>' \ ' <system systemId="$(VBOX_PATH_MANUAL_SRC_SLASHED)/common/oracle-support-en.xml" uri="$(VBOX_PATH_MANUAL_SRC)/en_US/oracle-support-en.xml"/>' \ 
  6. When VB is built with signing, most of its binaries receive the integrity check flag (the linker option /IntegrityCheck ) which forces Windows to check digital signatures and forbids launching applications which are signed incorrectly. If you have a valid paid certificate that's not a problem; however with a self-signed certificate VB will refuse to start, even if Windows is booted in the test mode. I've modified the file Config.kmk in such a way that this flag is only added when you have a full-grown certificate (the criterion of that is presence of a cross-certificate in LocalConfig.kmk ; see below ). The changes look like this:
    • A new variable VBOX_INTEGRITY_CHECK is added, which contains the desired value of the option:
       if defined(VBOX_SIGNING_MODE) && defined(VBOX_CROSS_CERTIFICATE_FILE) VBOX_INTEGRITY_CHECK := /IntegrityCheck else VBOX_INTEGRITY_CHECK := /IntegrityCheck:NO endif 
    • Below that there is the editbin call:
        $(VBOX_VCC_EDITBIN) /LargeAddressAware /DynamicBase /NxCompat /Release /IntegrityCheck \ /Version:$(VBOX_VERSION_MAJOR)0$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) \ "$@" 
      Here I've replaced the unconditional /IntegrityCheck with the new variable $(VBOX_INTEGRITY_CHECK) .
    • Next, look for the blocks of the following kinds:
       ifdef VBOX_SIGNING_MODE TEMPLATE_XXXXXX_LDFLAGS += -IntegrityCheck endif 
      or
       if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_HARDENING) TEMPLATE_XXXXXX_LDFLAGS += -IntegrityCheck endif 
      where « XXXXXX » stands for various component names. There are 6 such blocks in total, 3 of each kind. Here I've modified the condition by adding a check for cross-certificate. The first line then turns into, respectively:
       if defined(VBOX_SIGNING_MODE) && defined(VBOX_CROSS_CERTIFICATE_FILE) 
      or
       if defined(VBOX_SIGNING_MODE) && defined(VBOX_CROSS_CERTIFICATE_FILE) && defined(VBOX_WITH_HARDENING) 
  7. Two more files modified by me do not take immediate part in building of VB: src\VBox\Installer\win\Scripts\PackDriversForSubmission.cmd and UnpackBlessedDrivers.cmd . These auxiliary scripts can be used if you intend to send the drivers into Microsoft for Windows 10 signing. The first script prepares a CAB archive for sending; the second one unpacks the resultant ZIP archive with the signed drivers and verifies the signatures. In the packing script all I did was just fixing several typos. In the unpacking script I added ability to specify path to the signtool program, and got rid of the unzip tool by replacing it with a small Perl script. The signing procedure is described below. If you don't plan to get the Microsoft signature you can simply ignore all these changes in the scripts.

• VB build configuration file

现在,我们需要LocalConfig.kmk在VB源代码目录中创建文件,并在其中写入所有路径和构建参数。您可以使用以下文本作为模板:
 VBOX_WITH_HARDENING := VBOX_PATH_WIX := C:\Programs\WiX VBOX_GSOAP_INSTALLED := 1 VBOX_PATH_GSOAP := C:\Programs\gSOAP VBOX_WITH_COMBINED_PACKAGE := 1 VBOX_WITH_QT_PAYLOAD := 1 VBOX_WITH_QTGUI_V5 := 1 VBOX_SIGNING_MODE := release VBOX_CERTIFICATE_SUBJECT_NAME := Roga and Kopyta Ltd VBOX_CERTIFICATE_FINGERPRINT := XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX VBOX_CERTIFICATE_SHA2_SUBJECT_NAME := Roga and Kopyta Ltd VBOX_CERTIFICATE_SHA2_FINGERPRINT := XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX VBOX_TSA_URL := http://timestamp.digicert.com VBOX_TSA_SHA2_URL := http://timestamp.digicert.com VBOX_TSA_URL_ARGS := /t "$(VBOX_TSA_URL)" VBOX_TSA_SHA2_URL_ARGS := /tr "$(VBOX_TSA_SHA2_URL)" /td sha256 VBOX_CROSS_CERTIFICATE_FILE := VBOX_CROSS_CERTIFICATE_FILE_ARGS := VBOX_CROSS_CERTIFICATE_SHA2_FILE := VBOX_CROSS_CERTIFICATE_SHA2_FILE_ARGS := VBOX_PATH_SIGN_TOOLS := C:\Programs\DevKits\8.1\bin\x64 VBOX_PATH_SELFSIGN := C:\WinDDK\7600.16385.1\bin\selfsign VBOX_PATH_WISUMINFO := "C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiSumInf.vbs" VBOX_PATH_WISUBSTG := "C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiSubStg.vbs" VBOX_WITH_DOCS := 1 VBOX_WITH_DOCS_CHM := 1 VBOX_WITH_DOCS_PACKING := 1 VBOX_WITH_ADDITIONS := VBOX_WITH_ADDITIONS_PACKING := 1 VBOX_HAVE_XMLLINT := 1 VBOX_XMLLINT := C:\Programs\xmllint\bin\xmllint.exe VBOX_PATH_DOCBOOK := C:/Programs/DocBook/xsl VBOX_PATH_DOCBOOK_DTD := C:/Programs/DocBook/xml VBOX_PATH_HTML_HELP_WORKSHOP := "C:\Program Files (x86)\HTML Help Workshop" VBOX_PDFLATEX := C:\Programs\MiKTeX\texmfs\install\miktex\bin\pdflatex.exe VBOX_PDFLATEX_CMD := $(VBOX_PDFLATEX) -halt-on-error -interaction batchmode TOOL_CURL_FETCH := C:\Programs\curl\x64\curl.exe PATH_TOOL_NASM := C:/Programs/nasm VBOX_INSTALLER_LANGUAGES := en_US VBOX_WITH_TESTCASES := VBOX_WITH_VALIDATIONKIT := VBOX_WITH_VBOX_IMG := 1 VBOX_WITH_RECORDING := 1 VBOX_WITH_AUDIO_RECORDING := 1 SDK_VBOX_VPX := 1 VBOX_WITH_LIBVPX := 1 SDK_VBOX_OPUS := 1 VBOX_WITH_LIBOPUS := 1 VBOX_BUILD_PUBLISHER := _OSE 
您需要编辑以下模板:
  • 变量VBOX_CERTIFICATE_SUBJECT_NAMEVBOX_CERTIFICATE_SHA2_SUBJECT_NAME应该分别包含SHA-1和SHA-256证书的名称。
  • 变量VBOX_CERTIFICATE_FINGERPRINTVBOX_CERTIFICATE_SHA2_FINGERPRINT应包含这些证书的指纹;您之前已从证书管理控制台复制了它们。
  • If you have a paid certificate you should delete the lines defining the variables VBOX_CROSS_CERTIFICATE_FILE_ARGS and VBOX_CROSS_CERTIFICATE_SHA2_FILE_ARGS , then in the variables VBOX_CROSS_CERTIFICATE_FILE and VBOX_CROSS_CERTIFICATE_SHA2_FILE (without « _ARGS ») put the full path to the cross-certificate (without it the drivers will not be accepted). You can download it from the web site of the company that issued the certificate, or from Microsoft .
  • You can fine-tune the signing process using various additional variables and macros to redefine the certificate storage, timestamp server, or even construct a full command line for the signtool program. You can take a look into the file Config.kmk below the comment «Code Signing», there you'll find which variables are defined and how they are used.
  • If you've installed some of the programs into paths different from mine, you need to fix those paths in the template. It's strongly recommended to keep the path style for each variable (forward/backward slashes), sometimes it's critical for successful build.
  • Fox WiX you need to specify the path to its binaries. With the portable version, it is just the directory where you unpacked it; if you used the installer, the binaries will be located in the subdirectory bin . Please, note, that the path must not contain spaces! If it does you have to convert it into the 8.3 format (you can use dir /x for that). Unfortunately, enclosing the path in quotes does not work with this variable.
  • 该变量VBOX_BUILD_PUBLISHER在版本号中指定商标后缀。默认情况下,它是“ _OSE”(即完整的产品版本是“ 6.0.4_OSE”)。您可以在此处指定任何其他后缀,或将其设置为空以完全摆脱后缀。但是,如果您完全删除该变量,它将使用默认的“ _OSE”。
其余变量主要用于声明要构建的组件。而且,当然,主要声明位于最顶层:关闭强化功能。

建立virtualbox


最后,我们现在可以开始构建VirtualBox本身。如果您通常希望针对不同的平台并行构建,那么您现在必须暂时不使用它,或者使用两个单独的源代码树副本,因为VB有一个公共的配置文件,该文件在构建之前生成,并包含与平台有关的数据。在编译过程中,将编译器突然将其从64位构建环境扔到32位环境中,对编译器不利。
如果需要Windows 10兼容的驱动程序签名,请参考主要过程描述后提供的信息。
  1. 让我们从64位版本开始。打开控制台并运行以下命令:
     cd /d C:\Devel\VirtualBox-src "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x64 /win7 COLOR 07 set BUILD_TARGET_ARCH=amd64 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-openssl32=C:\Programs\OpenSSL\x32 --with-libcurl=C:\Programs\curl\x64 --with-libcurl32=C:\Programs\curl\x32 --with-Qt5=C:\Programs\Qt\5.6.3-x64 --with-libvpx=C:\Programs\libvpx --with-libopus=C:\Programs\libopus --with-python=C:/Programs/Python env.bat kmk kmk C:/Devel/VirtualBox-src/out/win.x86/release/obj/Installer/VirtualBox-6.0.4_OSE-r128164-MultiArch_amd64.msi 
    The configure.vbs script verifies the environment and generates configuration files ( AutoConfig.kmk and env.bat ). The first kmk command builds the binaries and collect them into out\win.amd64\bin\ . And the last command packs them all into the intermediate MSI package. Important notes:
    • You must use forward slashes in the last command. With backslashes, kmk would fail to find the build rules.
    • Even though we are building the 64-bit version, the target package is located in out\win.x86\… , because the final stage of the build will be performed from the 32-bit build environment.
    • If you've changed the branding suffix you need to change the name of the target package by replacing the «_OSE» with what you specified in the variable VBOX_BUILD_PUBLISHER .
    • The revision number in the MSI package name (128164) can be found in the file Config.kmk inside the VBOX_SVN_REV_FALLBACK variable definition. Please, note, that this value may be different from revisions of the official distribution (for instance, the version 6.0.4 has release number 128413). Unfortunately, I have no idea why.
  2. Now we need to build the 32-bit version and pack everything together. For that, open a new console window, and run the following commands:
     cd /d C:\Devel\VirtualBox-src "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /Release /x86 /win7 COLOR 07 set BUILD_TARGET_ARCH=x86 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-Qt5=C:\Programs\Qt\5.6.3-x32 --with-libvpx=C:\Programs\libvpx --with-libopus=C:\Programs\libopus --with-python=C:/Programs/Python env.bat kmk kmk C:/Devel/VirtualBox-src/out/win.x86/release/bin/VirtualBox-6.0.4_OSE-r128164-MultiArch.exe 
    Same as with the 64-bit, you need to replace the «_OSE» suffix with what you have.
    Notice how in the last command we are building an EXE , and not an MSI . This is the final installer which will cause the 32-bit package to be built automatically, from dependencies.
  3. Even if you have a paid certificate you will find that you cannot install this distribution into Windows 10 booted with Secure Boot enabled. This OS has stricter requirements, and the drivers must be signed by none other than Microsoft themselves. The procedure is explained in details on various Internet resources and is unrelated to this article, so I'm not going to go deep into this topic. Instead I'll outline the main steps you need to take for integrating this task with the VB build procedure.
    • The main requirement here is that you must have not just a normal code signing certificate, but an EV one (Extended Validation). Also you need to register an account at Hardware Dev Center and add your certificate there.
    • Now, during building the 64-bit version of VB, just after you've got all binary components (that is, after the first kmk run which was without arguments), you need to create a CAB archive with the drivers. There is a batch script template for that; the build system modifies it according to the current task and puts it into out\win.amd64\release\repack\ . Go into this path and run the following command:
       PackDriversForSubmission.cmd -x 
      When the script finishes, the file VBoxDrivers-6.0.4r128164-amd64.cab will appear in the same directory.
    • You need to sign this CAB archive with your EV certificate. Then go to the Microsoft Hardware Dev Center, create a new submission, upload your signed archive, select the desired target OS version (make sure it's 64-bit) and send the submission.
    • It will take several minutes to process, after which you will have a ZIP archive where all the drivers have been signed by Microsoft in addition to your signature, and all the CAT files generated anew. Download this archive and place it somewhere so that the build system had access to it.
    • Unpack the archive and put all the files from the subdirectories directly into out\win.amd64\release\bin\ overwriting the existing files. You can do it either manually or using another script from the same path out\win.amd64\release\repack\ by running the following commands:
       set _MY_SIGNTOOL=C:\Programs\DevKits\8.1\bin\x64\signtool.exe UnpackBlessedDrivers.cmd -n -i path\to\signed.zip 
      Of course, you need to put here the correct paths to signtool.exe and the ZIP archive.
    • Now you can run the second kmk command which packs all the components into an MSI installer. If you were doing all this in the same console window, don't forget to switch back to the base directory of the VB project.
    • Finally, proceed with building of the 32-bit version of VB, and perform all the same additional steps: after the first kmk switch to out\win.x86\release\repack\ , create the CAB archive, sign it, send to Microsoft (now choosing the 32-bit OS version), replace the drivers with their counter-signed versions, and run the final kmk for building the complete VB distribution.

如果我们俩都没有搞砸,那么漫长的过程应该会带给您一个崭新的VirtualBox安装程序,该安装程序与Oracle的区别仅在于其图标,“关于”图片,以及当然缺乏强化功能。替换图标和图片也不难,但是在这里我不会涉及这个主题。

为了方便起见,我创建了一个批处理文件,该文件可以自动完成整个VB的构建。如果需要定期构建完整的安装程序,则可以使用它。

如果您使用的是自签名证书,则只需几句话就可以安装结果分发版。突然发现,在Windows 8/10中不足以启动进入测试模式,安装仍然无法声明驱动程序签名无效。您可以通过将证书添加到CA根存储中来解决此问题:
  1. 右键单击VB安装程序的“属性”对话框,然后选择“ 属性”,然后切换到“ 数字签名”选项卡。您会在此处找到两个签名,两个签名分别为“ Roga and Kopyta Ltd”,一个为sha1,另一个为sha256。选择第一个,单击详细信息
  2. 出现另一个对话框,您需要单击“ 查看证书”按钮。
  3. One more dialog, click Install Certificate .
  4. In the Import wizard, select the location «Local Machine», click Next . After UAC confirmation (if needed), there's the certificate store selection. Select «Place all certificates in the following store», then click Browse and choose the store named «Trusted Root Certification Authorities». Then Next , Finish . You're done, the certificate is installed.
  5. Close all the dialogs but the very first one, select the second signature (sha256) and repeat the steps 2 to 4 for it too.
  6. Close all the dialogs, run the installer. Now it should work fine.

Epilogue


当我写完这篇文章时,我为自己的文章量感到惊讶。最初,我计划就选择解决每种问题的方式的原因深入探讨许多细节,解释问题的确切含义以及可能适用的替代解决方案。但是很快就变得很清楚,如果载有所有这些细节,文本将是巨大的。那么,我不得不为看起来像“只要这样做就不问任何问题”的食谱道歉。我非常讨厌那些人,但是我找不到其他办法。有时我仍会尝试概述正在发生的事情,以减轻印象。

有关VB构建系统的大量细节必须保留在幕后。因为我俩都不愿膨胀文本,有时却懒得去寻找另一种更有效的解决问题的方法。毕竟,最初我的主要目标是让自己成为当前VirtualBox版本的有效版本。到那时4.3.12已经过时了,但是我可以冒险将我最常用的工具之一更新为强化版本,该版本可能随时会停止工作。尽管有时我确实会回过头来,并且发现了一些新东西,但是将其添加到本文中。

我确实希望本文能引起读者的注意。如果您有兴趣查看和分析最终结果,但又不想设置所有程序,则可以从这里获取我的发行版:版本6.0.4所有驱动程序(和其他文件)都使用不受信任的自签名证书进行了签名,因此,要在64位Windows版本中安装此驱动程序,必须重新引导至测试模式。如果您有任何问题,建议,建议,请随时在此处以评论或通过个人信息给我写信。愿开源与您同在!

修正案


封存
•俄语文章于2016年1月21日发布
  1. VirtualBox 5.0.12。

•2016年5月24日更新
  1. 本文针对VB 5.0.20更新,主要更改之一是SHA-1 / SHA-256双签名。
  2. 如果使用了自签名证书,则添加了禁用强制签名检查的功能。
  3. 添加了有关自签名发行版安装失败的解决方法的信息。
  4. 库版本已更新。
  5. Disabled some unused components for speeding up the build process.
  6. Minor fixes and improvements.

• Update of 29.07.2016
  1. The article is updated for VB 5.1.2; the most important change is upgrading to Qt5. The differences from VB 5.0.x procedure are specified where applicable.
  2. Library versions were updated.
  3. The full build batch was updated to check error codes after each operation.
  4. Minor fixes and improvements.

• Update of 15.09.2016
  1. The article is updated for VB 5.1.6.
  2. Library versions were updated.
  3. Added NASM for building OpenSSL.
  4. Added OpenSSL into cURL; this fixes the broken function of checking for updates and downloading the Extension Pack.
  5. The full build batch now reads the VB version automatically.
  6. Various minor fixes and improvements.

• Update of 30.11.2016
  1. The article is updated for VB 5.1.10.
  2. Library versions were updated; particularly OpenSSL was upgraded to version 1.1.x.
  3. Fixed some installation errors:
    • path to the Qt plugins now points to the installation directory;
    • added forgotten OpenSSL libraries to the 32-bit components of the 64-bit VB version.
  4. The article no longer contains information about building older VB versions. If needed, the previous versions of it are available in the GitHub project .

• Update of 2.12.2016
  1. Switched to using statically linked OpenSSL.

• Update of 20.06.2017
  1. The article is updated for VB 5.1.22.
  2. cURL, OpenSSL, and gSOAP were updated; adapted the build instructions for cURL, gSOAP and VB.

• Update of 1.12.2017
  1. The article is updated for VB 5.2.2.
  2. Switched from MinGW-32 3.3.3 to 4.5.4.
  3. Qt, cURL, OpenSSL, gSOAP, and some build tools were updated; adapted the build instructions for cURL, gSOAP and VB.
  4. Switched to using local archives of DocBook XML/XSL instead of online versions.
  5. Using cURL program instead of wget for downloading the Guest Additions ISO image.
  6. Various minor fixes and improvements.

• Update of 4.12.2017
  1. The libxml version was fixed in the build instructions.

• Update of 4.09.2018
  1. The article is updated for VB 5.2.18.
  2. cURL, OpenSSL, gSOAP and some build tools were updated; adapted the build instructions for cURL.

• Update of 12.12.2018
  1. The article is updated for VB 5.2.22.
  2. Enabled screen recording functionality which is disabled in OSE version by default; added libraries libopus and libvpx for encoding.
  3. cURL, OpenSSL, and gSOAP were updated.
  4. The full set of VirtualBox source code changes is now published as a single patch file for easier application.

•2019年1月25日更新
  1. 本文已针对VB 6.0.2更新。
  2. 改进了禁用访客添加构建。
  3. cURL和gSOAP已更新;DocBook XSL样式表已降级至版本1.69.1(文档更适合该版本)。
  4. 完整的构建批次已从文章文本拆分为可下载的文件。

•更新04/08/2019
  1. The article has been translated into English for the first time. Also numerous minor changes were introduced into the Russian version.
  2. Added information about drivers signing for Windows 10.
  3. The article is updated for VB 6.0.4.
  4. cURL, OpenSSL, gSOAP, and some tools were updated.
  5. The full build batch no longer has to be placed at the specific path. Also, it now contains the basic template for automated Windows 10 drivers signing.

Source: https://habr.com/ru/post/zh-CN447300/


All Articles