DynamoRIO
Building from Source

Quick Start

If you don't need to modify DR and just need a recent build, you can download weekly package builds.

Linux

To build DynamoRIO on Linux, use the following commands as a guide. This builds 64-bit DynamoRIO in release mode:

# Install dependencies for Ubuntu 15+. Adjust this command as appropriate for
# other distributions (in particular, use "cmake3" for Ubuntu Trusty).
$ sudo apt-get install cmake g++ g++-multilib doxygen git zlib1g-dev libunwind-dev libsnappy-dev liblz4-dev
# Get sources and initialize the submodules.
$ git clone --recurse-submodules -j4 https://github.com/DynamoRIO/dynamorio.git
# Make a separate build directory. Building in the source directory is not
# supported.
$ cd dynamorio && mkdir build && cd build
# Generate makefiles with CMake. Pass in the path to your source directory.
$ cmake ..
# Build.
$ make -j
# Run echo under DR to see if it works. If you configured for a debug or 32-bit
# build, your path will be different. For example, a 32-bit debug build would
# put drrun in ./bin32/ and need -debug flag to run debug build.
$ ./bin64/drrun echo hello world
hello world

Windows

To build DynamoRIO on Windows, first install the following software.

  • Visual Studio 2019. Other versions are not officially supported as our automated tests use VS 2019.
  • CMake. 3.7+ is required. When prompted, we recommend adding it to your PATH.
  • Git. Any flavor should do, including Git on Windows or Cygwin git.
  • Perl. We recommend either Strawberry Perl or Cygwin perl.
  • (optional) Cygwin. Only needed for building documentation. Select the doxygen package if you do install it. (You can also select Cygwin's perl and git as alternatives to the links above.)

Once these dependencies are installed, you need to generate your project and solution files for Visual Studio using CMake. The easiest way to do this is to launch a cmd prompt with the right environment from the Visual Studio folder in the Start menu.

To build 64-bit DynamoRIO in release mode, launch the Visual Studio 2019 > x64 Native Tools Command Prompt for VS 2019 and run the following commands:

# Get sources.
$ git clone --recurse-submodules -j4 https://github.com/DynamoRIO/dynamorio.git
# Make a separate build directory. Building in the source directory is not
# supported.
$ cd dynamorio && mkdir build && cd build
# Configure using cmake. Pass in the path to your source directory.
$ cmake -G"Visual Studio 16" -A x64 ..
# Build from the command line. Alternatively, open ALL_BUILD.vcproj in Visual
# Studio and build from there. You must pass --config to work around a cmake
# bug. (http://www.cmake.org/Bug/view.php?id=11830)
$ cmake --build . --config RelWithDebInfo
# Run notepad under DR to see whether it worked.
$ bin32\drrun.exe notepad.exe

If you need a 32-bit build, choose x86 Native Tools Command Prompt and pass -G"Visual Studio 16 2019" -A Win32 to cmake.

An alternative to the command prompt is to execute the appropriate vcvars.bat command for your compiler in your shell of choice.

For developers who plan to modify the DynamoRIO sources and build on a regular basis, we recommend using Ninja.

Debug Build

If you plan to make changes to the source code, or for debugging problems in clients, you may wish to configure DynamoRIO in debug mode. Turn on the DEBUG flag when configuring, like this on Linux:

$ cmake -DDEBUG=ON ..
$ make -j

or on Windows:

$ cmake -G"Visual Studio 16" -A Win32 .. -DDEBUG=ON
$ cmake --build . --config Debug

Passing -DCMAKE_BUILD_TYPE=Debug to cmake does not produce a debug build currently.

For 64-bit build on Windows:

$ cmake -G"Visual Studio 16" -A x64 .. -DDEBUG=ON
$ cmake --build . --config Debug

For 32-bit build on 64-bit Linux

$ CFLAGS=-m32 CXXFLAGS=-m32 cmake -DDEBUG=ON ..
$ make -j

Installing from a Local Build

To mirror the layout and functionality of an official released package, build the install target. The CMAKE_INSTALL_PREFIX cmake variable controls the destination of the installation.

Once you've installed locally, you can now point at the installation just like you'd point at a release package for the purposes of building separate clients.


Details for Building on Linux

In order to build you'll need the following packages:

  • gcc
  • binutils
  • cmake (at least version 3.7)
  • perl

In order to build the documentation, you will additionally need:

  • doxygen

To see which versions of these packages we have tested, look up the versions for the Github Actions runner images that execute our continuous integration tests at https://github.com/actions/runner-images. You can find the images we are currently using in our workflow files.

If your machine does not have support for running 32-bit applications and its version of binutils is older than 2.18.50 then you'll need to set the CMAKE_ASM_COMPILER CMake cache variable to point at a GNU assembler of at least version 2.18.50.

Setup for Simultaneous 64-bit and 32-bit Building

In order to build both 32-bit and 64-bit on the same platform you'll need compiler support for targeting both architectures. Then install these packages:

sudo apt-get install cmake g++ g++-multilib doxygen zlib1g-dev libunwind-dev libunwind-dev:i386 libsnappy-dev liblz4-dev

For older distributions, the ia32-libs package is needed.

For 64-bit Fedora, you'll need this package to build the samples:

yum -y install glibc-devel.i?86

Building 32-bit DynamoRIO on 64-bit Linux

To build a 32-bit version of DynamoRIO on a 64-bit platform, add -m32 to CFLAGS and CXXFLAGS in your environment when you first generate your Makefiles with CMake. Adding -m32 to the environment and re-running CMake in an existing build directory will not re-configure the makefiles to produce a 32-bit build, so you will need to create a separate build directory.

CXXFLAGS=-m32 CFLAGS=-m32 cmake ..

Useful Configuration Options

By default we build with -Werror on Linux, so if your build fails due to compiler warnings that we have not encountered, you should enable the DISABLE_WARNINGS option to allow the build to proceed.

If you wish to run the test suite, you should enable BUILD_TESTS.


Cross-Compiling for 64-bit ARM (AArch64) on Linux

Install the cross compiler for the gnueabihf target:

$ sudo apt-get install g++-aarch64-linux-gnu

Check out the sources as normal, and point at our toolchain CMake file:

$ git clone --recurse-submodules -j4 https://github.com/DynamoRIO/dynamorio.git
$ mkdir build_aarch64
$ cd build_aarch64
$ cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-arm64.cmake ../dynamorio
$ make -j

To build a client, again use the toolchain file, as well as pointing at a DynamoRIO installation using -DDynamoRIO_DIR=<path> as described in the package documentation.


Cross-Compiling for 32-bit ARM (AArch32) on Linux

Install the cross compiler for the gnueabihf target:

$ sudo apt-get install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf g++-arm-linux-gnueabihf

Check out the sources as normal, and point at our toolchain CMake file:

$ git clone --recurse-submodules -j4 https://github.com/DynamoRIO/dynamorio.git
$ mkdir build_arm
$ cd build_arm
$ cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-arm32.cmake ../dynamorio
$ make -j

To build a client, again use the toolchain file, as well as pointing at a DynamoRIO installation using -DDynamoRIO_DIR=<path> as described in the package documentation.


Cross-Compiling for ARM Android

Install the Android NDK (Note: currently only version r10e can be used to build DynamoRIO, later versions do not work, see #1927, #2556)and configure it for the androideabi standalone toolchain. Something like this:

wget https://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip
unzip android-ndk-r10e-linux-x86_64.zip
android-ndk-r10e/build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --install-dir=/mytooldir/android-ndk-21 --toolchain=arm-linux-androideabi-4.9

Switch from the gold linker to bfd:

ln -sf arm-linux-androideabi-ld.bfd /mytooldir/android-ndk-21/bin/arm-linux-androideabi-ld
ln -sf ld.bfd /mytooldir/android-ndk-21/arm-linux-androideabi/bin/ld

Now check out the sources as normal, and point at our toolchain CMake file. If you have an attached Android device and the adb utility on your PATH, set the DR_COPY_TO_DEVICE variable to get the binaries needed for running tests automatically copied over via adb push.

$ git clone --recurse-submodules -j4 https://github.com/DynamoRIO/dynamorio.git
$ mkdir build_android
$ cd build_android
$ cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-android.cmake -DANDROID_TOOLCHAIN=/mytooldir/android-ndk-21 -DDR_COPY_TO_DEVICE=ON ../dynamorio
$ make -j

If your Android system does not have a writable /data/local/tmp directory, you will need to either set DYNAMORIO_CONFIGDIR to a writable location or always run from a writable current directory.

After building, check that libdynamorio.so does not contain an INTERP segment:

readelf -l lib32/debug/libdynamorio.so | grep INTERP

If it does, then you have probably used the gold linker instead of the bfd linker; see above.

If you have an Android device set up for access through the adb shell utility, the Android build is capable of automatically copying binaries to the device and running tests. First, ensure that adb is on your PATH, and that adb status indicates an attached device. Next, set the cmake variable DR_COPY_TO_DEVICE. This sets up post-build steps for each target needed by the tests to copy binaries over to the device. Now ctest should work when run from the host machine.


Building AArchXX Tooling to Execute on x86

DR has support for executing on x86/amd64 while decoding and encoding for AArch64 or ARM. This is mostly used for standalone decoding and for analyzing on an x86 machine drcachesim memory address traces gathered on an AArch64 machine.

To build, set the TARGET_ARCH CMake variable:

$ uname -m
x86_64
$ cmake -GNinja -DTARGET_ARCH=aarch64 ../src
$ ninja drdisas
$ clients/bin64/drdisas 12345678
12345678 and %w19 $0xfffff003 $0x0d15 -> %w24

Support for aarch64-on-x86 on Windows is not yet finished; nor is support for other target-host combinations.


Details for Building on Windows

Compiler

First, you need the compiler, linker, and associated tools. Install Visual Studio 2019 which is the version used by our automated tests.

You need to use a shell with command line support for using your compiler. For example, this could be the cmd shell or a Cygwin shell. You need to set the environment variables INCLUDE, LIB, LIBPATH, and PATH to point at the proper directories for your compiler. You can use the vcvarsall.bat script that comes with the compiler (in the VC directory) to set these variables for the cmd shell. For 64-bit, be sure to use vcvarsall.bat amd64, or directly run vcvarsamd64.bat. Do NOT use vcvarsall.bat x86_amd64 or vcvarsx86_amd64.bat.

To build a 32-bit version of DynamoRIO on a 64-bit platform, set up your environment to use the x64 tools. As mentioned above, you can launch the command prompt from the Visual Studio Start menu folder, or run the "vcvarsall.bat amd64" script.

CMake

You need CMake (version 3.7+) for Windows (not for Cygwin, as we need to pass paths with drive letters to our compiler). You can download a binary installation here:

http://www.cmake.org/cmake/resources/software.html

Install CMake and put its bin directory on the path for your shell.

Other Tools

In order to build you must have a version of perl. It can be either a Cygwin perl or a native Windows perl.

In order to build the documentation, you will additionally need:

  • doxygen

These can be either Cygwin packages or native Windows. TH`.

Using Cygwin

If you wish to run your build commands in a Cygwin bash shell, you will need to set up your environment the way that Visual Studio sets up the environment. Below is an example that supports multiple versions of Visual Studio installed simultaneously. It assumes that /cygdrive/c has been mounted as /c. Note the use of mixed paths (i.e., using a drive letter but forward slashes) for all variables except for PATH:

  # save PATH so we can swap between VS versions below
  export PRE_VS_PATH=$PATH

  # pass 0 to not use 8.x, and 0 in 2nd arg to not use 7.1
  function set_SDKROOT2 {
      # VS2008 puts rc and mc in 64-bit ProgFiles/MS SDKs
      export SDK2_SFX_INC=""
      export SDK2_SFX_LIB_X86=""
      export SDK2_SFX_LIB_X64="/x64"
      if [ "$1" != "0" ] && test -e /c/Program\ Files\ \(x86\)/Windows\ Kits/8.1; then
          export SDKROOT2=`cygpath -d /c/Program\ Files\ \(x86\)/Windows\ Kits/8.1`
          export SDK2_SFX_INC="/um"
          export SDK2_SFX_LIB_X86="/winv6.3/um/x86"
          export SDK2_SFX_LIB_X64="/winv6.3/um/x64"
      elif [ "$1" != "0" ] && test -e /c/Program\ Files\ \(x86\)/Windows\ Kits/8.0; then
          export SDKROOT2=`cygpath -d /c/Program\ Files\ \(x86\)/Windows\ Kits/8.0`
          export SDK2_SFX_INC="/um"
          export SDK2_SFX_LIB_X86="/win8/um/x86"
          export SDK2_SFX_LIB_X64="/win8/um/x64"
      elif [ "$2" != "0" ] && test -e /c/Program\ Files/Microsoft\ SDKs/Windows/v7.1; then
          export SDKROOT2=`cygpath -d /c/Program\ Files/Microsoft\ SDKs/Windows/v7.1`
      elif test -e /c/Program\ Files/Microsoft\ SDKs/Windows/v7.0; then
          export SDKROOT2=`cygpath -d /c/Program\ Files/Microsoft\ SDKs/Windows/v7.0`
      elif test -e /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A; then
          export SDKROOT2=`cygpath -d /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A`
      else
          export SDKROOT2=""
      fi
  }

  function compilerVS2013_32 {
      set_SDKROOT2 1 1
      export CMAKEGEN="Visual Studio 12"
      export CMAKEGEN64="Visual Studio 12 Win64"
      export SDKROOT=`cygpath -d /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0`
      ninja_x86
      export INCLUDE="${SDKROOT}/VC/INCLUDE"\;"${SDKROOT}/VC/ATLMFC/INCLUDE"\;"${SDKROOT}/Include"\;"${SDKROOT2}/Include${SDK2_SFX_INC}"\;"${SDKROOT2}/Include/shared"\;"${SDKROOT2}/Include/winrt"
      export LIB="${SDKROOT2}/Lib${SDK2_SFX_LIB_X86}"\;"${SDKROOT}/VC/LIB"\;"${SDKROOT}/Lib"\;"${SDKROOT}/VC/PlatformSDK/Lib"\;"${SDKROOT}/VC/atlmfc/lib"
      # cmake bails if don't have LIBPATH set, though we don't need it
      export LIBPATH="${SDKROOT}/VC/atlmfc/lib"
      # put prior to /usr/bin for link.exe to beat out cygwin link.exe
      # VS2013 puts rc and mc in 32-bit ProgFiles/Windows Kits
      export PATH=`cygpath -u ${SDKROOT}/VC/Bin`:`cygpath -u ${SDKROOT2}/bin/x86`:`cygpath -u $SDKROOT/Common7/IDE`:${PRE_VS_PATH}
  }

  function compilerVS2013_64 {
      set_SDKROOT2 1 1
      export CMAKEGEN="Visual Studio 12"
      export CMAKEGEN64="Visual Studio 12 Win64"
      export SDKROOT=`cygpath -d /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0`
      ninja_x64
      export INCLUDE="${SDKROOT}/VC/INCLUDE"\;"${SDKROOT}/VC/ATLMFC/INCLUDE"\;"${SDKROOT}/Include"\;"${SDKROOT2}/Include${SDK2_SFX_INC}"\;"${SDKROOT2}/Include/shared"\;"${SDKROOT2}/Include/winrt"
      export LIB="${SDKROOT2}/Lib${SDK2_SFX_LIB_X64}"\;"${SDKROOT}/VC/LIB/amd64"\;"${SDKROOT}/Lib"\;"${SDKROOT}/VC/PlatformSDK/Lib/AMD64"\;"${SDKROOT}/VC/atlmfc/lib/amd64"
      export LIBPATH="${SDKROOT}/VC/atlmfc/lib/amd64"
      # We need the base VC/Bin/ for 32-bit mspdb*.dll for cross-compiler used by cmake
      export PATH=`cygpath -u ${SDKROOT}/VC/Bin/amd64`:`cygpath -u ${SDKROOT2}/bin/x64`:`cygpath -u ${SDKROOT}/VC/Bin`:${PRE_VS_PATH}
  }

  function compilerVS2019_32 {
      export CMAKEGEN="Visual Studio 16"
      export VSVER=$(ls -1t /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2019/Professional/VC/Tools/MSVC | head -1)
      export VSBASE=$(cygpath -d /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2019/Professional)
      export VSROOT=$(cygpath -d ${VSBASE}/VC/Tools/MSVC/$VSVER)
      # We assume SDK 10
      export KITROOT=$(cygpath -d /c/Program\ Files\ \(x86\)/Windows\ Kits/10)
      export KITVER=$(ls -1t /c/Program\ Files\ \(x86\)/Windows\ Kits/10/Include | head -1)
      ninja_x86
      export INCLUDE="${VSROOT}/include"\;"${VSROOT}/atlmfc/include"\;"${KITROOT}/Include/${KITVER}/um"\;"${KITROOT}/Include/${KITVER}/ucrt"\;"${KITROOT}/Include/${KITVER}/shared"\;"${KITROOT}/Include/${KITVER}/winrt"\;
      export LIB="${VSROOT}/lib/x86"\;"${VSROOT}/atlmfc/lib/x86"\;"${KITROOT}/lib/${KITVER}/ucrt/x86"\;"${KITROOT}/lib/${KITVER}/um/x86"
      # cmake bails if don't have LIBPATH set, though we don't need it
      export LIBPATH="${VSROOT}/lib/x86"
      # put prior to /usr/bin for link.exe to beat out cygwin link.exe
      # VS2015 puts rc and mc in 32-bit ProgFiles/Windows Kits
      export PATH=`cygpath -u ${VSROOT}/bin/HostX86/x86`:`cygpath -u ${KITROOT}/bin/x86`:`cygpath -u ${KITROOT}/bin/${KITVER}/x86`:`cygpath -u ${VSBASE}/Common7/IDE`:${PRE_VS_PATH}
  }

  function compilerVS2019_64 {
      export CMAKEGEN="Visual Studio 16 Win64"
      export VSVER=$(ls -1t /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2019/Professional/VC/Tools/MSVC | head -1)
      export VSBASE=$(cygpath -d /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2019/Professional)
      export VSROOT=$(cygpath -d ${VSBASE}/VC/Tools/MSVC/$VSVER)
      # We assume SDK 10
      export KITROOT=$(cygpath -d /c/Program\ Files\ \(x86\)/Windows\ Kits/10)
      export KITVER=$(ls -1t /c/Program\ Files\ \(x86\)/Windows\ Kits/10/Include | head -1)
      ninja_x64
      export INCLUDE="${VSROOT}/include"\;"${VSROOT}/atlmfc/include"\;"${KITROOT}/Include/${KITVER}/um"\;"${KITROOT}/Include/${KITVER}/ucrt"\;"${KITROOT}/Include/${KITVER}/shared"\;"${KITROOT}/Include/${KITVER}/winrt"\;
      export LIB="${VSROOT}/lib/x64"\;"${VSROOT}/atlmfc/lib/x64"\;"${KITROOT}/lib/${KITVER}/ucrt/x64"\;"${KITROOT}/lib/${KITVER}/um/x64"
      # cmake bails if don't have LIBPATH set, though we don't need it
      export LIBPATH="${VSROOT}/lib/x64"
      # put prior to /usr/bin for link.exe to beat out cygwin link.exe
      # VS2015 puts rc and mc in 32-bit ProgFiles/Windows Kits
      export PATH=`cygpath -u ${VSROOT}/bin/HostX64/x64`:`cygpath -u ${KITROOT}/bin/x64`:`cygpath -u ${KITROOT}/bin/${KITVER}/x64`:`cygpath -u ${VSBASE}/Common7/IDE`:${PRE_VS_PATH}
  }

  if test -e /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2019; then
      compilerVS2019_32
  elif test -e /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0; then
      compilerVS2013_32
  fi

However, if you get errors about mspdb80.dll or windows.h, this probably means that the environment isn't set up correctly. Open a cmd prompt with the correct Visual C++ environment variables and compare the INCLUDE, LIB, LIBPATH, and PATH environment variables in the two shells.

Note that you need Visual Studio's bin directories on your PATH before Cygwin's as there are conflicts: both have mc.exe and link.exe.


Details of Building with CMake

Components

DynamoRIO contains several distinct components:

  • core/ = the core tool engine shared library
  • api/ = the documentation and sample clients
  • tools/ = various tools, including for deployment (drdeploy.in and drdeploy.c) and statistics viewing (DRstats)
  • libutil/ = library used by drdeploy.c and DRstats
  • suite/ = tests

All components are combined into a single CMake project.

Configuring Your Build

First, configure your compiler. On Windows this means setting up the environment variables (including PATH). On Linux, if your compiler supports both 64-bit and 32-bit targets, you can select the non-default type by setting the CFLAGS and CXXFLAGS environment variables to the flags used to change your compiler's target. For example, for gcc:

export CXXFLAGS=-m32
export CFLAGS=-m32

Next, in your shell (which you have set up for building with your compiler), create a build directory. You cannot build DynamoRIO from source code directory directly! Invoke the CMake GUI from the build directory, pointing at the source directory. For example, if your current directory is the base of the DynamoRIO tree, on either Windows or Linux, run:

mkdir build
cd build
cmake-gui ..

Press Configure. On Windows, select Visual Studio 16 2019. On Linux, select Unix Makefiles.

If you are on Linux, ccmake, a curses-based GUI, can be used instead of cmake-gui; it generates Unix Makefiles by default. In ccmake, press c to configure.

On Windows, if you are building an old version of DynamoRIO (prior to r577), you will need to use NMake Makefiles instead of a Visual Studio generator. If you are in Cygwin, you can use Unix Makefiles, but the resulting build will be slower than using a Visual Studio generator.

Now you can select the parameters to configure your build. The main parameters are as follows (some may not be present if the configure process determined they do not apply: e.g., if you do not have doxygen installed you cannot selected BUILD_DOCS):

  • BUILD_CORE = whether to build the core
  • BUILD_DOCS = whether to build the documentation
  • BUILD_DRSTATS = whether to build the DRstats viewer (Windows-only). Note that DRstats is currently 32-bit only (issue 62), so when building a 64-bit Windows core you will need a separate build directory and configuration for 32-bit in order to build DRstats.
  • BUILD_TOOLS = whether to build the tools (primarily Windows)
  • BUILD_SAMPLES = whether to build the client samples
  • BUILD_TESTS = whether to build the tests
  • INSTALL_PREFIX = where to install the results after building
  • NTDLL_LIBPATH = where ntdll.lib is located (Windows-only)
  • DEBUG = whether to enable asserts and logging
  • INTERNAL = for DynamoRIO developer use
  • DISABLE_WARNINGS = useful if your version of gcc produces warnings we have not seen (we compile with warnings-are-errors)

Press Configure and then OK (or c and then g) to complete the configuration step and generate the Makefiles. It is normal to see messages like this for various types (uint, ushort, bool, byte, sbyte, uint32, uint64, int32, int64):

-- Check size of bool
-- Check size of bool - failed

This is really a check for the existence of a typedef and it is normal for some such checks to print a "failure" message.

On Windows, if you have both cl and gcc on your path, you can ensure that CMake selects cl by setting the CC and CXX environment variables. For example:

CC=cl CXX=cl cmake ..

To improve compilation speed on Windows, if you are using a makefile-based generator (i.e., not Visual Studio), you can turn off the progress and status messages with this CMake define:

-DCMAKE_RULE_MESSAGES:BOOL=OFF

On Windows, if you use Cygwin and hit CMake bug#13131, you may need to kill all running MSBuild instances and unset the TMP and TEMP environment variables.

Building

After the configuration step is complete, for release build, type

cmake --build . --config RelWithDebInfo

or if you turned on DEBUG, type

cmake --build .

or if you are using NMake Makefiles, type

nmake

or on Linux, type

make

An Example of Building DynamoRIO in Windows-XP 64bit in cmd

  • step 1: set INCLUDE, LIB, LIBPATH, and PATH by running the Visual Studio Command Prompt, under the Visual Studio Tools in the Visual Studio start menu entry. Alternatively, from a plain cmd window:
    E:\>"c:\Program Files (x86)\Microsoft Visual Studio 8\VC\vcvarsall.bat"

or for 64-bit build

E:\>"c:\Program Files (x86)\Microsoft Visual Studio 8\VC\vcvarsall.bat" amd64
  • step 2: get dynamorio source to e:\dynamorio via svn
  • step 3: in e:\dynamorio, create a directory for building
    mkdir build
    cd build
  • step 4: configure using cmake
    E:\dynamorio\build\>"c:\Program Files (x86)\CMake 3.7\bin\cmake-gui.exe" ..\
    
    • step 4.1: click "Configure" button
    • step 4.2: select "Visual studio 16"
    • step 4.3: generate configuration file
  • step 5: build and install
    E:\dynamorio\build\>cmake --build . --config Release
    

Configuring in Batch Mode

Instead of interactive configuration you can pass all your parameter changes to CMake on the command line. For example:

On Windows:

mkdir build
cd build
cmake -G"Visual studio 16" -DBUILD_DOCS:BOOL=OFF ..
cmake --build . --config Release

On Linux:

mkdir build
cd build
cmake -DBUILD_DOCS:BOOL=OFF ..
make

Developers may wish to pass -DCMAKE_VERBOSE_MAKEFILE=1 to CMake in order to see the compilation command lines. They can alternatively be seen for any individual build with make VERBOSE=1.

Re-Configuring

You can re-run the configure step, using the same parameters that you originally used, in two ways:

make rebuild_cache

Or:

cmake .

With the latter command you can also change the configuration, but be sure to do a make clean prior to building as CMake does not perform dependence checking on this type of modification. As an example:

cmake -DDEBUG=ON -DINTERNAL=ON .
make clean

Building a Distributable Package

If you've been working with DynamoRIO's packaged binaries, you may find it easiest to install all of the dependencies listed above for your platform and then run the packaging script:

cd dynamorio
mkdir package
cd package
ctest -V -S ../make/package.cmake,build=1

Details of CMake Visual Studio Generators

As of version 577, DynamoRIO supports building from Visual Studio. The /MP flag is set by default for not only parallel project builds but parallel file builds. The fastest DynamoRIO build is a Visual Studio build from the command line.

First, DynamoRIO requires CMake version 3.7 or higher.

Then you can generate the Visual Studio project files with something like this:

cmake -G"Visual studio 16" -DDEBUG=ON -DCMAKE_RULE_MESSAGES:BOOL=OFF ../src

You can build from the command line (actually for any generator) with this:

cmake --build .

Due to a cmake bug (http://www.cmake.org/Bug/view.php?id=11830), for a release build you need to explicitly say you want release:

cmake --build . --config Release

To request a particular target:

cmake --build . --target dynamorio

or

cmake --build . --target install

Using Ninja For Better Error Messages, Faster Builds, and Proper Incremental Builds

Ninja is a new build system designed to work with automated build system generators like CMake:

https://github.com/martine/ninja

Ninja has much more readable build output, resulting in better error messages. It builds faster, and it automatically re-runs CMake when necessary, resulting in proper incremental builds. It's all-around a superior build experience from the command line.

In addition to having ninja.exe on your PATH, you need to set the environment variable ASM to "ml" for a 32-bit build and to "ml64" for a 64-bit build (otherwise Ninja tries to assemble using cl). If you have other compilers installed (such as Cygwin or MinGW), you should also set the CC and CXX environment variables. Here are sample bash functions:

function ninja_x86 {
export CC=cl
export CXX=cl
export ASM=ml
}
function ninja_x64 {
export CC=cl
export CXX=cl
export ASM=ml64
}

To configure, from a shell that has the Visual Studio environment set up, ninja.exe on the PATH, and the ASM environment variable set, run:

cmake -G"Ninja" ../src

From a Cygwin bash shell you could alternatively set the environment variables in the same command:

CC=cl CXX=cl ASM=ml cmake -G"Ninja" ../src

To build:

ninja

Ninja builds in parallel by default.

To build a specific target:

ninja dynamorio

One downside of the current CMake Ninja generator is that one must change the environment in order to switch to a 64-bit build directory (both the Visual Studio toolchain environment and the ASM environment variable mentioned above), whereas with the Visual Studio generator one can switch build directories without any environment changes (once the build directories are configured using the right environment).

The test suite supports using Ninja by passing the use_ninja parameter:

ctest -V -S c:/mycheckout/suite/runsuite.cmake,use_ninja

Using Ninja With Pre-7.0 SDK

If you end up using the (no longer officially supported) Visual Studio 2008, it's best to pair it with a pre-7.0 SDK, but Ninja runs into a problem there running rc.exe:

fatal error RC1106: invalid option: -ologo

A workaround is to copy rc.exe and rcdll.dll from a post-7.0 SDK into the pre-7.0 SDK Bin directory, with admin privileges:

mv /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Bin/RC.Exe /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Bin/RC-ORIG.Exe
mv /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Bin/RcDll.Dll /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Bin/RcDll-ORIG.Dll
cp /c/Program\ Files/Microsoft\ SDKs/Windows/v7.1/Bin/RC.Exe /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Bin/
cp /c/Program\ Files/Microsoft\ SDKs/Windows/v7.1/Bin/RcDll.Dll /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Bin/

Using MSBuild For Slightly Better Error Messages And Faster Builds

We recommend Ninja (see above) over MSBuild, but we're leaving the information on MSBuild here as it is recommended over devenv.

By default, CMake will use devenv when building for Visual Studio generators.

cmake --build . --target Release -- /m

The /m (full name "/maxcpucount") option is only supported with .NET 3.5 or later. In practice this means Visual Studio 2010 or later. With no numeric argument (as shown in the command line above), it requests a concurrent number of jobs equal to the number of processors on the system.

MSBuild summarizes all build warnings and errors at the end of the run, unlike devenv. It is also a little faster than devenv (when parallel building is enabled). There are some general outstanding issues with MSBuild, but it seems to work well for DynamoRIO with Visual Studio 2010 and 2012. To request MSBuild set the CMAKE_MAKE_PROGRAM variable at configuration time. In a Visual Studio Command Prompt, MSBuild is on the PATH, so the absolute path is not needed:

cmake -G"Visual studio 16" -DCMAKE_MAKE_PROGRAM:FILEPATH=MSBuild ../src

Don't forget to pass the "/m" flag (after "--") as shown above when building.

To request verbose build information, use the "/v:diag" flag:

cmake --build . --target Release -- /m /v:diag

Here is a sample bash function to make building easier within Cygwin:

function build {
config=$(grep ^CMAKE_CONFIGURATION_TYPES:S CMakeCache.txt | sed 's/^.*=//')
/usr/bin/time cmake --build . --config $config -- /m
}

Using Unix Makefiles On Windows For Parallel Builds

On Windows you can target Unix Makefiles in order to use GNU make and build in parallel (NMake does not support parallel builds; see also issue 71). However, note that Visual Studio generators support parallel builds and are faster than using Cygwin make. The instructions here are relatively old and are kept just for completeness.

If you have gcc installed you will have to explicitly tell the CMake generator to prefer cl:

cmake -G"Unix Makefiles" -DCMAKE_GENERATOR_CC=cl -DCMAKE_GENERATOR_CXX=cl ..

If you see this error from cygwin make:

target pattern contains no `%'.

Or during cmake configuration:

Detecting C compiler ABI info - failed

That may not fail the configuration and you may see a later fatal failure:

if had incorrect arguments: ${sizeof_void} EQUAL 8 (Unknown arguments specified).

Then you need to switch to a version of make that supports colons in paths. One such version is 3.80. I recommend copying it into your /usr/local/bin directory and either putting /usr/local/bin ahead of /usr/bin on your PATH or passing it to CMake explicitly:

cmake -DCMAKE_MAKE_PROGRAM=$SYSTEMDRIVE/cygwin/usr/local/bin/make.exe

If you have a very recent cygwin installation you may need to put cygintl-2.dll directory into /usr/local/bin as well.

Now you can build in parallel, which reduces build time:

make -j6 install

Build time on Windows can be further improved by disabling progress and status messages (see issue 71). To do so, use -DCMAKE_RULE_MESSAGES=OFF.

See issue 71 for some representative performance numbers, and for instructions on building with Mingw and the MSYS shell, which is a little faster than building under Cygwin.

Note that with more recent Visual Studio versions and machines with more than two cores we have seen some strange build errors that may be pdb creation races. We recommend using the Visual Studio generator instead if you are hitting these problems.

Building the Qt DrGUI extension

Simply install Qt 5.x and ensure that the architecture and compiler match what you will be using to build DynamoRIO. E.g., on Fedora:

yum -y install qt5-qtbase.i686 qt5-qtbase-devel.i686

On Ubuntu, Qt 5 may not be in the standard repositories. You can install the 64-bit version with:

apt-add-repository ppa:ubuntu-sdk-team/ppa
apt-get install -y qtbase5-dev qtbase5-dbg

If Qt is installed in a non-standard location, set the Qt5Widgets_DIR cmake variable to point to the directory containing Qt5WidgetsConfig.cmake. E.g.:

cmake -DQt5Widgets_DIR=/opt/Qt5.0.2/5.0.2/gcc/lib/cmake/Qt5Widgets/