Build Instructions

Blend2D uses CMake to create native platform (or IDE) projects and to build them. Consult cmake-generators page to see which generators are supported on your target platform. You don't have to use CMake if you prefer other tools, but then you would have to set some compile flags and definitions manually, which is covered by Building Without CMake section. At the moment Blend2D only depends on AsmJit library, which is part of Blend2D source releases, but it's not part of blend2d git repository. Git users have to clone AsmJit library separately.

Note

This page documents the process of building Blend2D. If you are more intersted in using Blend2D within your own project you may be more interested in Getting Started page that shows how to integrate Blend2D in a custom CMake project.

Build Requirements

Operating systems supported:

  • POSIX compatible operating systems including Linux, BSDs, and OSX.
  • Windows 7+ (Windows XP or less is not supported).
  • Others operating systems may require some minor support (Haiku reported to work).

CPU architectures supported:

  • X86 - Both 32-bit and 64-bit targets are supported
  • ARM - Reference pipeline only (reference pipeline is currently limited to solid fills only and doesn't provide NEON acceleration)
  • Other architectures will be supported through reference pipeline that is written in C++

C++ compilers supported:

  • Clang - Any version with C++11 support
  • GCC 4.9+ - Minor issues with GCC 4.8, so 4.9+ is required at the moment
  • MSVC 2017+
  • Intel compiler should work, but it's not tested by our continuous integration

Important

It's strongly advised to use Clang to compile Blend2D on all platforms to achieve maximum performance. Clang can optimize Blend2D C++ code very well and can vectorize many floating point computations that are used during geometry processing. A C++ Compilers page provides a summary of compiler optimizations that Blend2D benefits from and will be extended in the future to cover more constructs relevant to Blend2D.

Unsafe Optimizations

Never use unsafe math optimizations like -ffast-math, -ffinite-math-only, or /fp:fast as Blend2D relies on existence of NaN and Infinity. Additionally, C++ compiler should never reorder any floating point expressions as some expressions are very sensitive to such reordering. The only optimization that is allowed is using fused-multiply-add (FMA) instructions if they are available.

Build Configuration

By default only blend2d target is built. The following build options are available:

Option Default Description
CMAKE_BUILD_TYPE (unset) Highly depends on CMake generator used.
  • If you use IDE that supports multiple configurations like Visual Studio or Xcode then leave it empty and use your IDE to select the build type you want
  • If you use a makefile based generator or ninja then you should set it to Release as Debug builds are order of magnitude slower than release builds
ASMJIT_DIR (unset) Where to find AsmJit library. Should be unset to let Blend2D autodetect the location:
  • <blend2d>/3rdparty/asmjit - Third party directory used by source releases
  • <blend2d>/../asmjit - Git users usually clone AsmJit at the same level as Blend2D
BLEND2D_BUILD_TEST false Whether to build tests.
BLEND2D_BUILD_EMBED false Whether to embed Blend2D library.
  • Embedding allows to include Blend2D source files into your own project and build it together without creating a static library target
  • When enabled BL_BUILD_EMBED is defined during the build and must be defined as well by any code that includes Blend2D so appropriate function decorators may be set by Blend2D for function exports
BLEND2D_BUILD_STATIC false Whether to build Blend2D statically.
  • This would create Blend2D::Blend2D target that you can use from CMake
  • When enabled BL_BUILD_STATIC is defined during the build and must be defined as well by any code that includes Blend2D. If you use Blend2D::Blend2D target then you don't have to worry about anything all the necessary stuff is populated by the target
BLEND2D_BUILD_SANITIZE false Whether to build Blend2D with sanitizers enabled.
  • This option is only useful for Blend2D developers or for people that are facing runtime problems
  • Sanitizer-enabled builds are slower, but can discover issues that would not be discovered by normal debug builds

Building From Source

The following steps can be used to clone and build Blend2D directly from git:

# Get both Blend2D and AsmJit [next-wip].
$ git clone --depth=1 https://github.com/blend2d/blend2d
$ git clone --depth=1 https://github.com/asmjit/asmjit --branch=next-wip

# Create build directory.
$ mkdir blend2d/build
$ cd blend2d/build

# Configure the project. This would create either makefiles or
# IDE specific project files that are required to compile the
# project. Use BLEND2D_BUILD_TEST to build tests.
#
# NOTE: Leave build type empty if you use Visual Studio or Xcode
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DBLEND2D_BUILD_TEST=TRUE

# Build the project. The build command depends on cmake-generator
# used to configure the project. If you use makefiles then `make`
# would be the command, otherwise it could be `ninja` or other IDE
# specific command.
$ cmake --build .

# Alternatively, if you use IDE such as Visual Studio or Xcode you
# may need to select the build type, which would default to Debug
# by default.
$ cmake -- build . --config Release

# DONE: You should have either blend2d.dll or libblend2d.so library.

The following steps can be used to build Blend2D source release:

# Get source release directly from blend2d.com.
$ wget https://blend2d.com/download/blend2d-${VERSION}.zip
$ unzip blend2d-beta.zip

# Create build directory.
$ mkdir blend2d/build
$ cd blend2d/build

# Configure and build (see the previous section for more details).
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DBLEND2D_BUILD_TEST=TRUE
$ cmake --build .

# DONE: You should have either blend2d.dll or libblend2d.so library.

Building Sample Applications

The same approach can be used to build sample applications. The following example shows how to clone everything from Blend2D git repositories, but it would work with source as well:

# Get both Blend2D and AsmJit [next-wip].
$ git clone --depth=1 https://github.com/blend2d/blend2d
$ git clone --depth=1 https://github.com/asmjit/asmjit --branch=next-wip

# Get Blend2D samples and benchmarking tool.
$ git clone --depth=1 https://github.com/blend2d/blend2d-bench
$ git clone --depth=1 https://github.com/blend2d/blend2d-samples

# Build blend2d-bench, will try to autodetect Cairo and Qt.
$ mkdir blend2d-bench/build
$ cd blend2d-bench/build
$ cmake .. -DCMAKE_BUILD_TYPE=Release
$ cmake --build .
$ cd ..

# Build blend2d-samples (use a category you are interested in).
$ cd blend2d-samples/<category>
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Release
$ cmake --build .

# DONE: Your samples are compiled...

Building Without CMake

This page documents the process of building Blend2D without any help of CMake build scripts. It can be used as a reference of what CMake scripts are doing and as a recommendation of building Blend2D with other build tools or no build tools at all. Blend2D exports C API, but it's still a library written in C++ and requires at least C++11 capable compiler.

Compiler Independent Setup

  • Add the following source files to your target:
    • All source files in Blend2D src directory
    • All source files in AsmJit src directory. If you downloaded a source release of Blend2D then AsmJit will be at 3rdparty/asmjit directory within Blend2D project
  • Setup the C++ compiler in the following way:
    • Enable at least C++11 through -std=c++11 or /std:c++latest. C++17 is preferred though
    • Add ${ASMJIT_DIR}/src to your include path through -I... or /I... option
    • Define ASMJIT_BUILD_EMBED to tell asmjit that it will be embedded
  • Define the following compile-time definitions to select a build type:
    • NDEBUG - should be always defined for release builds (standard C way)
    • BL_BUILD_DEBUG - force debug build, overrides autodetection based on NDEBUG (optional).
    • BL_BUILD_RELEASE - force release build, overrides autodetection based on NDEBUG (optional)
  • Define the following compile-time definitions to enable architecture-specific optimizations:
    • BL_BUILD_OPT_SSE2 - enables SSE2 optimizations (should be always enabled)
    • BL_BUILD_OPT_SSE3 - enables SSE3 optimizations
    • BL_BUILD_OPT_SSSE3 - enables SSSE3 optimizations
    • BL_BUILD_OPT_SSE4_1 - enables SSE4.1 optimizations
    • BL_BUILD_OPT_SSE4_2 - enables SSE4.2 optimizations
    • BL_BUILD_OPT_AVX - enables AVX optimizations
    • BL_BUILD_OPT_AVX2 - enables AVX2 optimizations

Compiler Specific Setup [GCC & Clang]

  • Use the following [optional] compiler flags to make the resulting binaries better:
    • -fvisibility=hidden - Blend2D API uses explicit public visibility so everything else should be hidden by default. Alternatively -fvisibility-inlines-hidden can be specified
    • -fno-exceptions - Blend2D doesn't use exceptions so you can turn them off
    • -fno-rtti - Blend2D doesn't use runtime type information or dynamic casts so you can turn this feature off
    • -fno-math-errno - Blend2D doesn't check errno after calling math functions, this option may help the C++ compiler to inline some intrinsic functions like sqrt
    • -fmerge-all-constants - Blend2D doesn't compare pointers of constants so it's perfectly fine to merge constants having the same values
    • -ftree-vectorize - some compilers need this option to vectorize some constructs that Blend2D uses, however, this option would be probably set automatically at certain optimization levels by the compiler
    • -O2 or -O3 - it should be enough to use -O2 as -O3 often only increases code-size without increasing its performance
  • Each file with a certain suffix requires to be compiled with extra flags that enable architecture specific optimizations:
    • -msse2 must be used to compile *_sse2.cpp files if BL_BUILD_OPT_SSE2 was enabled
    • -msse3 must be used to compile *_sse3.cpp files if BL_BUILD_OPT_SSE3 was enabled
    • -mssse3 must be used to compile *_ssse3.cpp files if BL_BUILD_OPT_SSSE3 was enabled
    • -msse4.1 must be used to compile *_sse4_1.cpp files if BL_BUILD_OPT_SSE4_1 was enabled
    • -msse4.2 must be used to compile *_sse4_2.cpp files if BL_BUILD_OPT_SSE4_2 was enabled
    • -mavx must be used to compile *_avx.cpp files if BL_BUILD_OPT_AVX was enabled
    • -mavx2 must be used to compile *_avx2.cpp files if BL_BUILD_OPT_AVX2 was enabled

Compiler Specific Setup [MSVC]

  • Use the following [optional] compiler flags to make the resulting binaries better:
    • -O2 - favor performance over size
  • Each file with a certain suffix requires to be compiled with extra flags that enable architecture specific optimizations:
    • -arch:SSE2 and -D__SSE2__ must be used to compile *_sse2.cpp files if BL_BUILD_OPT_SSE2 was enabled
    • -arch:SSE2 and -D__SSE3__ must be used to compile *_sse3.cpp files if BL_BUILD_OPT_SSE3 was enabled
    • -arch:SSE2 and -D__SSSE3__ must be used to compile *_ssse3.cpp files if BL_BUILD_OPT_SSSE3 was enabled
    • -arch:SSE2 and -D__SSE4_1__ must be used to compile *_sse4_1.cpp files if BL_BUILD_OPT_SSE4_1 was enabled
    • -arch:SSE2 and -D__SSE4_2__ must be used to compile *_sse4_2.cpp files if BL_BUILD_OPT_SSE4_2 was enabled
    • -arch:AVX must be used to compile *_avx.cpp files if BL_BUILD_OPT_AVX was enabled
    • -arch:AVX2 must be used to compile *_avx2.cpp files if BL_BUILD_OPT_AVX2 was enabled
  • If you use LLVM toolchain, which meas that a clang-cl compiler is used instead of stock cl it's important to explicitly enable SSE3, SSSE3, SSE4.1, and SSE4.2 optimizations together with -arch:SSE2, otherwise the compilation would fail as Clang is not fully compatible with MS stock compiler:
    • -arch:SSE2 and -msse3 must be used to compile *_sse3.cpp files if BL_BUILD_OPT_SSE3 was enabled
    • -arch:SSE2 and -mssse3 must be used to compile *_ssse3.cpp files if BL_BUILD_OPT_SSSE3 was enabled
    • -arch:SSE2 and -msse4.1 must be used to compile *_sse4_1.cpp files if BL_BUILD_OPT_SSE4_1 was enabled
    • -arch:SSE2 and -msse4.2 must be used to compile *_sse4_2.cpp files if BL_BUILD_OPT_SSE4_2 was enabled

Linker Options

  • The following libraries are required on Windows:
    • (to be documented)
  • The following libraries are required on Linux, BSDs, and others:
    • libc (standard C library)
    • libm (if not part of standard C library)
    • libpthread (required to support multithreading)
    • librt (Required on Linux by clock_gettime() function)