Blend2D
2D Vector Graphics Engine
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.
This page documents the process of building Blend2D. If you are more interested in using Blend2D within your own project the Getting Started page is much easier and provides all the information to use Blend2D in a CMake project.
Operating systems supported:
CPU architectures supported:
C++ compilers recommended:
It's strongly advised to use latest compilers to compile Blend2D on all platforms to achieve maximum performance. Many floating point computations that are implemented in C++ can be auto-vectorized, so a capable compiler can make a significant difference.
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.
By default only dynamically linked blend2d
library is built. The following CMake build options are available:
Option | Default | Description |
---|---|---|
CMAKE_BUILD_TYPE |
(unset) | Highly depends on CMake generator used:
|
ASMJIT_DIR |
(unset) | Where to find AsmJit library for static inclusion. Should be unset to let Blend2D auto-detect the location:
|
BLEND2D_TEST |
false | Whether to build tests. |
BLEND2D_EMBED |
false | Whether to embed Blend2D library, which enables:
|
BLEND2D_STATIC |
false | Whether to build Blend2D statically:
|
BLEND2D_SANITIZE |
(unset) | Sanitizers to use to build Blend2D, possible options are address (ASAN), memory (MSAN), thread (TSAN), undefined (UBSAN):
|
BLEND2D_SANITIZE_OPTS |
(unset) | Additional sanitizer options to pass to the C++ compiler |
BLEND2D_NO_FUTEX |
false | Disables using futexes (this is only useful for testing or as a workaround to disable Futexes in case that there is a bug in Blend2D) |
BLEND2D_NO_INTRINSICS |
false | Disables the use of non-SIMD intrinsics in Blend2D (there is no reason to explicitly turn on this option, it's only useful for testing) |
BLEND2D_NO_INSTALL |
false | If true Blend2D won't install blend2d library and public header files. Useful in cases in which Blend2D is compiled statically as a part of another project, which has install targets, but installing Blend2D is unwanted |
BLEND2D_NO_JIT |
false (auto-detected) | Disables JIT compiler and AsmJit dependency (experimental, not recommended for production as portable pipelines are slower than JIT pipelines) |
BLEND2D_NO_JIT_LOGGING |
false | Disables JIT compiler logging feature. This option can be used to make Blend2D a little bit smaller as it would compile AsmJit without logging feature and Blend2D would have this feature disabled as well. We do not recommend using this option as it doesn't save that much space and sometimes JIT logging can be beneficial when solving problems. Note that JIT logging must be explicitly turned on by the application that uses Blend2D, it's never enabled by default |
BLEND2D_NO_NATVIS |
false | Disables embedding blend2d.natvis file in Blend2D binary |
BLEND2D_NO_STDCXX |
(auto-detected) | Disables linking to a C++ standard library. This option is auto-detected - dynamically linked Blend2D library would not link to a standard C++ library by default |
BLEND2D_NO_TLS |
false | Disables the use of thread-local storage (there is no reason to explicitly turn on this option unless you are having issues with TLS or your target is operating system that has a very limited size of TLS) |
The following steps can be used to clone and build Blend2D directly from git:
The following steps can be used to build Blend2D source release:
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:
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 to build.
Add the following source files to your target:
src
directorysrc
directory. If you downloaded a source release of Blend2D then AsmJit will be at 3rdparty/asmjit
directory within Blend2D projectSetup the C++ compiler in the following way:
-std=c++11
or /std:c++latest
. C++17 is preferred though${ASMJIT_DIR}/src
to your include path through -I...
optionASMJIT_STATIC
to tell asmjit that it will be built staticallyDefine the following compile-time definitions to select a build type:
Compile-Time Definition | Description |
---|---|
NDEBUG | Should be always defined for release builds (standard C/C++ macro) |
BL_BUILD_DEBUG | Forces debug build, overrides auto-detection based on NDEBUG (optional) |
BL_BUILD_RELEASE | Force release build, overrides auto-detection based on NDEBUG (optional) |
Define the following compile-time definitions to enable architecture-specific optimizations:
Compile-Time Definition | Description |
---|---|
BL_BUILD_OPT_SSE2 | Enables SSE2 optimizations (always enabled on X86 targets) |
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 |
BL_BUILD_OPT_AVX512 | Enables AVX512_[F|BW|DQ|CD] optimizations |
Please note that BL_BUILD_OPT_XXX
compile-time definitions just tell Blend2D to build support for the optimizations, but to not rely on the presence of the extensions. Blend2D would use these optimizations if the CPU extension(s) required to use them were detected at run-time.
Use the following [optional] compiler flags to make the resulting binaries better:
Compiler flag | Description |
---|---|
-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() |
-fno-semantic-interposition |
Better code generated as the compiler doesn't have to assume semantic interposition (GCC documentation); clang uses this option by default |
-fno-threadsafe-statics |
Blend2D has its own initialization step, which initializes everything required to make the library functional, thus thread-safe statics are not needed to guard initialization of static variables |
-fmerge-all-constants |
Blend2D doesn't compare pointers of constants so it's perfectly fine to merge constants having the same values |
-ftree-vectorize |
Blend2D may benefit from auto-vectorization, if not done automatically by the C++ compiler. Recent GCC and Clang enable it automatically at -O2 level |
-O2 or -O3 |
It should be enough to use -O2 as -O3 often only increases code-size without increasing its performance |
Additionally, each file with a certain suffix requires to be compiled with extra flags that enable architecture specific optimizations:
Compile Flag(s) | File Suffix | Description |
---|---|---|
-msse2 |
*_sse2.cpp |
Must be used if BL_BUILD_OPT_SSE2 was enabled |
-msse3 |
*_sse3.cpp |
Must be used if BL_BUILD_OPT_SSE3 was enabled |
-mssse3 |
*_ssse3.cpp |
Must be used if BL_BUILD_OPT_SSSE3 was enabled |
-msse4.1 |
*_sse4_1.cpp |
Must be used if BL_BUILD_OPT_SSE4_1 was enabled |
-msse4.2 |
*_sse4_2.cpp |
Must be used if BL_BUILD_OPT_SSE4_2 was enabled |
-mavx |
*_avx.cpp |
Must be used if BL_BUILD_OPT_AVX was enabled |
-mavx2 |
*_avx2.cpp |
Must be used if BL_BUILD_OPT_AVX2 was enabled |
-mavx512f
-mavx512bw
-mavx512dq
-mavx512cd
-mavx512vl
|
*_avx512.cpp |
Must be used if BL_BUILD_OPT_AVX512 was enabled |
Use the following [optional] compiler flags to make the resulting binaries better:
Compile Flag(s) | Description |
---|---|
-O2 |
Favor performance over size |
Each file with a certain suffix requires to be compiled with extra flags that enable architecture specific optimizations:
Compile Flag(s) | File Suffix | Description |
---|---|---|
-arch:SSE2 -D__SSE2__ |
*_sse2.cpp |
Must be used if BL_BUILD_OPT_SSE2 was enabled |
-arch:SSE2 -D__SSE3__ |
*_sse3.cpp |
Must be used if BL_BUILD_OPT_SSE3 was enabled |
-arch:SSE2 -D__SSSE3__ |
*_ssse3.cpp |
Must be used if BL_BUILD_OPT_SSSE3 was enabled |
-arch:SSE2 -D__SSE4_1__ |
*_sse4_1.cpp |
Must be used if BL_BUILD_OPT_SSE4_1 was enabled |
-arch:SSE2 -D__SSE4_2__ |
*_sse4_2.cpp |
Must be used if BL_BUILD_OPT_SSE4_2 was enabled |
-arch:AVX |
*_avx.cpp |
Must be used if BL_BUILD_OPT_AVX was enabled |
-arch:AVX2 |
*_avx2.cpp |
Must be used if BL_BUILD_OPT_AVX2 was enabled |
-arch:AVX512 |
*_avx512.cpp |
Must be used if BL_BUILD_OPT_AVX512 was enabled |
If you use LLVM toolchain, which meas that a clang-cl
compiler is used instead of the 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 100% compatible with MS stock compiler in this area:
Compile Flag(s) | File Suffix | Description |
---|---|---|
-arch:SSE2 |
*_sse2.cpp |
Must be used if BL_BUILD_OPT_SSE2 was enabled |
-arch:SSE2 -msse3 |
*_sse3.cpp |
Must be used if BL_BUILD_OPT_SSE3 was enabled |
-arch:SSE2 -mssse3 |
*_ssse3.cpp |
Must be used if BL_BUILD_OPT_SSSE3 was enabled |
-arch:SSE2 -msse4.1 |
*_sse4_1.cpp |
Must be used if BL_BUILD_OPT_SSE4_1 was enabled |
-arch:SSE2 -msse4.2 |
*_sse4_2.cpp |
Must be used if BL_BUILD_OPT_SSE4_2 was enabled |
The following libraries are required on Windows:
The following libraries are required on Linux, BSDs, and others:
libc
(standard C library)libm
(if not part of standard C library)libpthread
(if not part of standard C library)librt
(Required on Linux by clock_gettime()
function)