This post documents a guide to building VirtualBox on OSX 10.9. This document should be read in conjunction with the official Mac OS X build instructions [1]. Its intended audience are people relatively new to VirtualBox and/or OSX development who might find that the official instructions don't provide quite enough guidance to navigate the obstacles introduced by the need to use an older version of Xcode to successfully execute the build.

Most of the information documented here was originally provided by Klaus Espenlaub and Vadim Galitsyn in a thread "Sketch of how to build on OSX 10.9?" in the Virtual Box developers mailing list.[2] [3]

The reason these additional instructions may be helpful for novices is that the VirtualBox source tree doesn't support building against XCode 5.1 which is the current set of development tools that a OSX 10.9 user is likely to have installed. To build VirtualBox successfully, the 10.9 user needs to obtain an earlier version of XCode (I chose 4.1) and manually unpack parts of it to obtain the necessary SDKs and gcc compiler required by the VirtualBox source tree. Later versions of XCode symlink gcc to clang/LLVM which does not support all the gcc and g++ options used by the VirtualBox build scripts.

Unlike the official instructions, these instructions also assume that other dependencies (such as openssl and Qt) are installed with homebrew rather than MacPorts.

The build process, in overview:

  1. ensure you have enough disk space
  2. checkout the SVN source tree
  3. download the XCode 4.1 installer from Apple
  4. unpack and extract a portion of the XCode 4.1 installation
  5. build openssl from source (using brew)
  6. configure the build
  7. run the build
  8. fixup the permissions on the build results
  9. load the kernel extensions
  10. start VirtualBox
  11. (optionally) switch back to the official distribution.

Ensure you have enough disk space

To successfully build the VirtualBox tree you are going to need around 10GB of diskspace. 3GB for the XCode 4.1 image, 1.2GB for the partial XCode 4.1 extract and 2.2 GB for the VirtualBox source tree and build output plus some head room required during extraction from the XCode 4.1 disk image.

Checkout the SVN source tree

Run this command to checkout the source code from SVN.

svn co http://www.virtualbox.org/svn/vbox/trunk vbox
cd vbox

The source tree I built was http://www.virtualbox.org/svn/vbox/trunk@51648

The following instructions may need to be adapted if you want to build from a commit earlier than 51645 because that commit introduces support for the --with-xcode-dir option that these instructions use.

Download the XCode 4.1 installer from Apple

On an OSX 10.9 system, Apple wants you to use XCode 5.1. Unfortunately, XCode 5.1 currently can't be used to build the VirtualBox source tree because of two reasons: the source tree doesn't recognize the 10.9 SDK and Xcode 5.1 doesn't provide a true implementation of gcc 4.2 which contains support for compiler options that the Virtual Box build scripts rely on (for example, -fcheck-new).

Fortunately, you can still download earlier versions of XCode from Apple's developer site [4] [registration required].

The file you are looking for is called "Xcode 4.1 for Lion" and should download as a file called "installxcode_41_lion.dmg".

Unpack and extract a portion of the XCode 4.1 installation

Unfortunately the installer in the disk image prevents you from installing this version of XCode on an OSX 10.9 system. Instead, it is necessary to manually (or, at least, semi-automatically) unpack just the parts of XCode 4.1 that are actually needed to compile the VirtualBox source tree.

I've written a script called extract-xcode41.sh [5] that sequences the xar and cpio commands necessary to extract just those dependencies required to build the VirtualBox source tree.

Assuming you have downloaded installxcode_41_lion.dmg and extract-xcode41.sh script into the root of your VirtualBox source tree, then the following command will create a subdirectory called xcode41-partial containing just the necessary dependencies.

./extract-xcode41.sh

For the record, the following is a list of packages that are extracted from the XCode 4.1 installer.

  • DevSDK.pkg
  • MacOSX10.6.pkg
  • MacOSX10.7.pkg
  • XcodeTools.pkg
  • llvm-gcc4.2.pkg
  • gcc4.2.pkg
  • DeveloperTools.pkg

Build openssl from source (using brew)

VirtualBox needs a copy of the openssl source tree. The easiest way to obtain this on a system which uses homebrew is to run the brew installer with the --build-from-source option. So:

brew install openssl --build-from-source

By default, brew puts the openssl source tree into /usr/local/opt/openssl.

I didn't explicitly install Qt myself as part of this build but it appears that the configure script successfully located a copy of qt that had previously be installed by brew. If this doesn't apply to you, you might try:

brew install qt

Configure the build

This step uses a recently introduced option --with-xcode-dir to tell VirtualBox how to find the Xcode SDKs and tools it should use for the build. Per the official guide, I will also use the --disable-hardening option but note the warning in the official build notes against using this option with a build that you intend to distribute to others.

 ./configure --disable-hardening \
      --with-xcode-dir=$(pwd)/xcode41-partial \
      --with-openssl=/usr/local/opt/openssl

Run the build

The build should now be ready to run. You can build it with:

source env.sh
kmk

I found that the build took about 20 minutes to run on my Mac Book Air.

Fixup the permissions

For full functionality, some components of VirtualBox need to run as setuid root. In particular, the host-only network interface will only work correctly if these permissions are set correctly.

So, fixup the permissions as follows:

pushd out/darwin.amd64/release/dist/VirtualBox.app/Contents/MacOS/
for b in VBoxHeadless VBoxNetAdpCtl VBoxNetDHCP VBoxNetNAT VirtualBoxVM; 
do 
    sudo chown root $b; 
    sudo chmod u+s $b; 
done
popd

Load the kernel extensions

VirtualBox needs some kernel extensions to operate correctly. To load these, run the loadall.sh script provided for the purpose.

pushd out/darwin.amd64/release/dist
./loadall.sh
popd

If the load completes successfully, you should see messages like this:

...
load.sh: Successfully unloaded org.virtualbox.kext.VBoxDrv
load.sh: loading /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext...
.sh: loading /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext... (kextutil -t "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext")
Diagnostics for /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext:
Code Signing Failure: not code signed
WARNING - Invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext"
  144    0 0xffffff7f82259000 0x46000    0x46000    org.virtualbox.kext.VBoxDrv (4.3.53) <7 5 4 3 1>
loadusb.sh: loading /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxUSB.kext... (kextutil -t -d "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext" "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxUSB.kext")
Diagnostics for /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxUSB.kext:
Code Signing Failure: not code signed
WARNING - Invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxUSB.kext"
  144    1 0xffffff7f82259000 0x46000    0x46000    org.virtualbox.kext.VBoxDrv (4.3.53) <7 5 4 3 1>
  146    0 0xffffff7f822a7000 0x8000     0x8000     org.virtualbox.kext.VBoxUSB (4.3.53) <144 54 34 7 5 4 3 1>
loadnetflt.sh: loading /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetFlt.kext... (kextutil -t -d "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext" "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetFlt.kext")
Diagnostics for /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetFlt.kext:
Code Signing Failure: not code signed
WARNING - Invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetFlt.kext"
  144    2 0xffffff7f82259000 0x46000    0x46000    org.virtualbox.kext.VBoxDrv (4.3.53) <7 5 4 3 1>
  146    0 0xffffff7f822a7000 0x8000     0x8000     org.virtualbox.kext.VBoxUSB (4.3.53) <144 54 34 7 5 4 3 1>
  147    0 0xffffff7f822af000 0x5000     0x5000     org.virtualbox.kext.VBoxNetFlt (4.3.53) <144 7 5 4 3 1>
loadnetadp.sh: loading /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetAdp.kext... (kextutil -t -d "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxDrv.kext" "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetAdp.kext")
Diagnostics for /Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetAdp.kext:
Code Signing Failure: not code signed
WARNING - Invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext "/Users/jonseymour/svn/vbox/out/darwin.amd64/release/dist/VBoxNetAdp.kext"
  144    3 0xffffff7f82259000 0x46000    0x46000    org.virtualbox.kext.VBoxDrv (4.3.53) <7 5 4 3 1>
  146    0 0xffffff7f822a7000 0x8000     0x8000     org.virtualbox.kext.VBoxUSB (4.3.53) <144 54 34 7 5 4 3 1>
  147    0 0xffffff7f822af000 0x5000     0x5000     org.virtualbox.kext.VBoxNetFlt (4.3.53) <144 7 5 4 3 1>
  148    0 0xffffff7f82327000 0x6000     0x6000     org.virtualbox.kext.VBoxNetAdp (4.3.53) <144 5 4 1>

The warnings about invalid signatures are expected and not indicative of a problem that should prevent local testing.

Start VirtualBox

To start VirtualBox, change into the directory containing the VirtualBox binary, and run it:

pushd out/darwin.amd64/release/dist/\
VirtualBox.app/Contents/MacOS/
./VirtualBox
popd

Switching back to the official distribution

The following instructions will help you unload the privately built version of VirtualBox (and its kernel extensions) and restore the official distribution.

Copy the following script [6] into a file called 'reload-vbox.sh' somewhere on your path.

#!/usr/bin/env bash
# based on https://gist.github.com/rtgibbons/2024307 with updates from comments of that gist for OSX 10.9

EXTDIR="/Library/Application Support/VirtualBox"

unload() {
    kextstat | grep "org.virtualbox.kext.VBoxUSB" > /dev/null 2>&1 && sudo kextunload -b org.virtualbox.kext.VBoxUSB
    kextstat | grep "org.virtualbox.kext.VBoxNetFlt" > /dev/null 2>&1 && sudo kextunload -b org.virtualbox.kext.VBoxNetFlt
    kextstat | grep "org.virtualbox.kext.VBoxNetAdp" > /dev/null 2>&1 && sudo kextunload -b org.virtualbox.kext.VBoxNetAdp
    kextstat | grep "org.virtualbox.kext.VBoxDrv" > /dev/null 2>&1 && sudo kextunload -b org.virtualbox.kext.VBoxDrv
}

load() {
    sudo kextload "$EXTDIR/VBoxDrv.kext" -r "$EXTDIR"
    sudo kextload "$EXTDIR/VBoxNetFlt.kext" -r "$EXTDIR"
    sudo kextload "$EXTDIR/VBoxNetAdp.kext" -r "$EXTDIR"
    sudo kextload "$EXTDIR/VBoxUSB.kext" -r "$EXTDIR"
}

case "$1" in
    unload|remove)
        unload
    ;;
    load)
        load
    ;;
    *|reload)
        unload
        load
    ;;
esac

Then run:

reload-vbox.sh reload

References