CMakeLists.txt (50935B)
1 # Blend2D 2 # ======= 3 4 # To consume blend2d as a dependency, use blend2d::blend2d alias. 5 6 cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 7 8 # Blend2D - Project & Configuration 9 # ================================= 10 11 project(blend2d 12 LANGUAGES C CXX 13 DESCRIPTION "High-performance 2D vector graphics engine with JIT compiler" 14 HOMEPAGE_URL "https://blend2d.com") 15 16 # BLEND2D_XXX are cmake variables whereas BL_XXX are build-time macros passed to compiler via flags. 17 set(BLEND2D_SANITIZE "" CACHE STRING "Sanitizers to use (development)") 18 set(BLEND2D_SANITIZE_OPTS "" CACHE STRING "Extra flags for sanitizers (development)") 19 option(BLEND2D_STATIC "Build 'blend2d' as a static library instead" OFF) 20 option(BLEND2D_TEST "Build 'blend2d' tests and samples (development)" OFF) 21 option(BLEND2D_DEMOS "Build 'blend2d' interactive demos that use Qt library (development)" OFF) 22 option(BLEND2D_NO_JIT "Disable 'blend2d' JIT pipelines generation support (not recommended)" OFF) 23 option(BLEND2D_NO_JIT_LOGGING "Disable 'blend2d' JIT pipelines logging support (deployment)" OFF) 24 option(BLEND2D_NO_NATVIS "Disable 'blend2d' natvis support (development)" OFF) 25 option(BLEND2D_NO_TLS "Disable 'blend2d' use of TLS (development)" OFF) 26 option(BLEND2D_NO_FUTEX "Disable 'blend2d' use of futexes (development)" OFF) 27 option(BLEND2D_NO_INSTALL "Disable 'blend2d' install support for cmake (development/deployment)" OFF) 28 option(BLEND2D_EXTERNAL_ASMJIT "Enable support for external asmjit library (not recommended)" OFF) 29 30 # Avoid linking to the C++ stdlib by default if blend2d is being built as a shared library with bundled asmjit. 31 if (NOT BLEND2D_STATIC AND NOT BLEND2D_EXTERNAL_ASMJIT) 32 option(BLEND2D_NO_STDCXX "Disable 'blend2d' linking to a standard C++ library (deployment)" ON) 33 else() 34 option(BLEND2D_NO_STDCXX "Disable 'blend2d' linking to a standard C++ library (deployment)" OFF) 35 endif() 36 37 # Blend2D - Build Definitions and Source Files 38 # ============================================ 39 40 set(BLEND2D_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/src") # Include directory is the same as source dir. 41 set(BLEND2D_DEPS "") # Blend2D dependencies (libraries) for the linker. 42 set(BLEND2D_CFLAGS "") # Public compiler flags. 43 set(BLEND2D_WARNING_CFLAGS "") # Flags that enable compiler warnings (we add them to various targets). 44 set(BLEND2D_PRIVATE_CFLAGS "") # Private compiler flags independent of build type. 45 set(BLEND2D_PRIVATE_CFLAGS_DBG "") # Private compiler flags used by debug builds. 46 set(BLEND2D_PRIVATE_CFLAGS_REL "") # Private compiler flags used by release builds. 47 set(BLEND2D_PRIVATE_LFLAGS "") # Private linker flags. 48 set(BLEND2D_SANITIZE_CFLAGS "${BLEND2D_SANITIZE_OPTS}") # Compiler flags required by currently enabled sanitizers. 49 set(BLEND2D_SANITIZE_LFLAGS "") # Linker flags required by currently enabled sanitizers. 50 set(BLEND2D_NO_STDCXX_CFLAGS "") # Private compiler flags to disable linking to a standard C++ library. 51 set(BLEND2D_NO_STDCXX_LFLAGS "") # Private linker flags to disable linking to a standard C++ library. 52 53 if (BLEND2D_STATIC) 54 message(STATUS "[blend2d] Building static library ('BLEND2D_STATIC=${BLEND2D_STATIC}' => 'BLEND2D_TARGET_TYPE=STATIC')") 55 set(BLEND2D_TARGET_TYPE "STATIC") 56 list(APPEND BLEND2D_CFLAGS -DBL_STATIC) 57 list(APPEND BLEND2D_PRIVATE_CFLAGS -DBL_STATIC) 58 else() 59 message(STATUS "[blend2d] Building shared library ('BLEND2D_STATIC=OFF' => 'BLEND2D_TARGET_TYPE=SHARED')") 60 set(BLEND2D_TARGET_TYPE "SHARED") 61 endif() 62 63 set(BLEND2D_SRC_LIST 64 blend2d.h 65 blend2d-debug.h 66 blend2d-impl.h 67 blend2d/api.h 68 blend2d/api-build_p.h 69 blend2d/api-build_test_p.h 70 blend2d/api-globals.cpp 71 blend2d/api-impl.h 72 blend2d/api-internal_p.h 73 blend2d/api-nocxx.cpp 74 blend2d/array.cpp 75 blend2d/array_test.cpp 76 blend2d/array.h 77 blend2d/array_p.h 78 blend2d/bitarray.cpp 79 blend2d/bitarray_test.cpp 80 blend2d/bitarray.h 81 blend2d/bitarray_p.h 82 blend2d/bitset.cpp 83 blend2d/bitset_test.cpp 84 blend2d/bitset.h 85 blend2d/bitset_p.h 86 blend2d/compop_p.h 87 blend2d/compopinfo_p.h 88 blend2d/compopinfo.cpp 89 blend2d/context.cpp 90 blend2d/context_test.cpp 91 blend2d/context.h 92 blend2d/context_p.h 93 blend2d/filesystem.cpp 94 blend2d/filesystem.h 95 blend2d/filesystem_p.h 96 blend2d/font.cpp 97 blend2d/font.h 98 blend2d/font_p.h 99 blend2d/font_test.cpp 100 blend2d/fontdata.cpp 101 blend2d/fontdata.h 102 blend2d/fontdata_p.h 103 blend2d/fontdefs.h 104 blend2d/fontface.cpp 105 blend2d/fontface.h 106 blend2d/fontface_p.h 107 blend2d/fontfeaturesettings.cpp 108 blend2d/fontfeaturesettings_test.cpp 109 blend2d/fontfeaturesettings.h 110 blend2d/fontfeaturesettings_p.h 111 blend2d/fontmanager.cpp 112 blend2d/fontmanager.h 113 blend2d/fontmanager_p.h 114 blend2d/fonttagdata_p.h 115 blend2d/fonttagdataids.cpp 116 blend2d/fonttagdataids_test.cpp 117 blend2d/fonttagdataids_p.h 118 blend2d/fonttagdatainfo.cpp 119 blend2d/fonttagdatainfo_test.cpp 120 blend2d/fonttagdatainfo_p.h 121 blend2d/fonttagset.cpp 122 blend2d/fonttagset_p.h 123 blend2d/fontvariationsettings.cpp 124 blend2d/fontvariationsettings_test.cpp 125 blend2d/fontvariationsettings.h 126 blend2d/fontvariationsettings_p.h 127 blend2d/format.cpp 128 blend2d/format.h 129 blend2d/format_p.h 130 blend2d/geometry.cpp 131 blend2d/geometry.h 132 blend2d/geometry_p.h 133 blend2d/glyphbuffer.cpp 134 blend2d/glyphbuffer.h 135 blend2d/glyphbuffer_p.h 136 blend2d/glyphrun.h 137 blend2d/gradient.cpp 138 blend2d/gradient_test.cpp 139 blend2d/gradient.h 140 blend2d/gradient_p.h 141 blend2d/image.cpp 142 blend2d/image_test.cpp 143 blend2d/image.h 144 blend2d/image_p.h 145 blend2d/imagecodec.cpp 146 blend2d/imagecodec_test.cpp 147 blend2d/imagecodec.h 148 blend2d/imagedecoder.cpp 149 blend2d/imagedecoder.h 150 blend2d/imageencoder.cpp 151 blend2d/imageencoder.h 152 blend2d/imagescale.cpp 153 blend2d/imagescale_p.h 154 blend2d/matrix.cpp 155 blend2d/matrix_avx.cpp 156 blend2d/matrix_sse2.cpp 157 blend2d/matrix_test.cpp 158 blend2d/matrix.h 159 blend2d/matrix_p.h 160 blend2d/object.cpp 161 blend2d/object.h 162 blend2d/object_p.h 163 blend2d/path.cpp 164 blend2d/path_test.cpp 165 blend2d/path.h 166 blend2d/path_p.h 167 blend2d/pathstroke.cpp 168 blend2d/pathstroke_p.h 169 blend2d/pattern.cpp 170 blend2d/pattern.h 171 blend2d/pattern_p.h 172 blend2d/pixelconverter.cpp 173 blend2d/pixelconverter_avx2.cpp 174 blend2d/pixelconverter_sse2.cpp 175 blend2d/pixelconverter_ssse3.cpp 176 blend2d/pixelconverter_test.cpp 177 blend2d/pixelconverter.h 178 blend2d/pixelconverter_p.h 179 blend2d/random.cpp 180 blend2d/random_test.cpp 181 blend2d/random.h 182 blend2d/random_p.h 183 blend2d/rgba_test.cpp 184 blend2d/rgba.h 185 blend2d/runtime.cpp 186 blend2d/runtime.h 187 blend2d/runtime_p.h 188 blend2d/runtimescope.cpp 189 blend2d/runtimescope.h 190 blend2d/string.cpp 191 blend2d/string_test.cpp 192 blend2d/string.h 193 blend2d/string_p.h 194 blend2d/trace.cpp 195 blend2d/trace_p.h 196 blend2d/var.cpp 197 blend2d/var_test.cpp 198 blend2d/var.h 199 blend2d/var_p.h 200 201 blend2d/codec/bmpcodec.cpp 202 blend2d/codec/bmpcodec_p.h 203 blend2d/codec/codec_test.cpp 204 blend2d/codec/jpegcodec.cpp 205 blend2d/codec/jpegcodec_p.h 206 blend2d/codec/jpeghuffman.cpp 207 blend2d/codec/jpeghuffman_p.h 208 blend2d/codec/jpegops.cpp 209 blend2d/codec/jpegops_sse2.cpp 210 blend2d/codec/jpegops_p.h 211 blend2d/codec/pngcodec.cpp 212 blend2d/codec/pngcodec_p.h 213 blend2d/codec/pngops.cpp 214 blend2d/codec/pngops_asimd.cpp 215 blend2d/codec/pngops_avx.cpp 216 blend2d/codec/pngops_sse2.cpp 217 blend2d/codec/pngops_p.h 218 blend2d/codec/pngopssimdimpl_p.h 219 blend2d/codec/pngopssimdimpl_test.cpp 220 blend2d/codec/qoicodec.cpp 221 blend2d/codec/qoicodec_p.h 222 223 blend2d/compression/checksum.cpp 224 blend2d/compression/checksum_asimd.cpp 225 blend2d/compression/checksum_asimd_crypto.cpp 226 blend2d/compression/checksum_sse2.cpp 227 blend2d/compression/checksum_sse4_2.cpp 228 blend2d/compression/checksum_test.cpp 229 blend2d/compression/checksum_p.h 230 blend2d/compression/checksumadler32simdimpl_p.h 231 blend2d/compression/checksumcrc32simdimpl_p.h 232 blend2d/compression/deflatedecoder.cpp 233 blend2d/compression/deflatedecoder_p.h 234 blend2d/compression/deflatedecoderfast.cpp 235 blend2d/compression/deflatedecoderfast_avx2.cpp 236 blend2d/compression/deflatedecoderfast_p.h 237 blend2d/compression/deflatedecoderfastimpl_p.h 238 blend2d/compression/deflatedecoderutils.cpp 239 blend2d/compression/deflatedecoderutils_p.h 240 blend2d/compression/deflatedefs_p.h 241 blend2d/compression/deflatedefs.cpp 242 blend2d/compression/deflateencoder.cpp 243 blend2d/compression/deflateencoder_p.h 244 blend2d/compression/deflateencoderutils_p.h 245 blend2d/compression/deflate_test.cpp 246 blend2d/compression/matchfinder_p.h 247 248 blend2d/opentype/otcff.cpp 249 blend2d/opentype/otcff_test.cpp 250 blend2d/opentype/otcff_p.h 251 blend2d/opentype/otcmap.cpp 252 blend2d/opentype/otcmap_p.h 253 blend2d/opentype/otcore.cpp 254 blend2d/opentype/otcore_p.h 255 blend2d/opentype/otdefs_p.h 256 blend2d/opentype/otface.cpp 257 blend2d/opentype/otface_p.h 258 blend2d/opentype/otglyf.cpp 259 blend2d/opentype/otglyf_asimd.cpp 260 blend2d/opentype/otglyf_avx2.cpp 261 blend2d/opentype/otglyf_sse4_2.cpp 262 blend2d/opentype/otglyf_p.h 263 blend2d/opentype/otglyfsimddata_p.h 264 blend2d/opentype/otglyfsimddata.cpp 265 blend2d/opentype/otglyfsimdimpl_p.h 266 blend2d/opentype/otkern.cpp 267 blend2d/opentype/otkern_p.h 268 blend2d/opentype/otlayout.cpp 269 blend2d/opentype/otlayout_p.h 270 blend2d/opentype/otlayoutcontext_p.h 271 blend2d/opentype/otlayouttables_p.h 272 blend2d/opentype/otmetrics.cpp 273 blend2d/opentype/otmetrics_p.h 274 blend2d/opentype/otname.cpp 275 blend2d/opentype/otname_p.h 276 blend2d/opentype/otplatform_p.h 277 278 blend2d/pipeline/pipedefs.cpp 279 blend2d/pipeline/pipedefs_p.h 280 blend2d/pipeline/piperuntime.cpp 281 blend2d/pipeline/piperuntime_p.h 282 283 blend2d/pipeline/jit/compoppart.cpp 284 blend2d/pipeline/jit/compoppart_p.h 285 blend2d/pipeline/jit/compoputils_p.h 286 blend2d/pipeline/jit/fetchgradientpart.cpp 287 blend2d/pipeline/jit/fetchgradientpart_p.h 288 blend2d/pipeline/jit/fetchpart.cpp 289 blend2d/pipeline/jit/fetchpart_p.h 290 blend2d/pipeline/jit/fetchpatternpart.cpp 291 blend2d/pipeline/jit/fetchpatternpart_p.h 292 blend2d/pipeline/jit/fetchpixelptrpart.cpp 293 blend2d/pipeline/jit/fetchpixelptrpart_p.h 294 blend2d/pipeline/jit/fetchsolidpart.cpp 295 blend2d/pipeline/jit/fetchsolidpart_p.h 296 blend2d/pipeline/jit/fetchutilsbilinear_p.h 297 blend2d/pipeline/jit/fetchutilscoverage.cpp 298 blend2d/pipeline/jit/fetchutilscoverage_p.h 299 blend2d/pipeline/jit/fetchutilsinlineloops.cpp 300 blend2d/pipeline/jit/fetchutilsinlineloops_p.h 301 blend2d/pipeline/jit/fetchutilspixelaccess.cpp 302 blend2d/pipeline/jit/fetchutilspixelaccess_p.h 303 blend2d/pipeline/jit/fetchutilspixelgather.cpp 304 blend2d/pipeline/jit/fetchutilspixelgather_p.h 305 blend2d/pipeline/jit/fillpart.cpp 306 blend2d/pipeline/jit/fillpart_p.h 307 blend2d/pipeline/jit/jitbase_p.h 308 blend2d/pipeline/jit/pipecompiler.cpp 309 blend2d/pipeline/jit/pipecompiler_p.h 310 blend2d/pipeline/jit/pipecomposer.cpp 311 blend2d/pipeline/jit/pipecomposer_p.h 312 blend2d/pipeline/jit/pipedebug_p.h 313 blend2d/pipeline/jit/pipefunction_p.h 314 blend2d/pipeline/jit/pipefunction.cpp 315 blend2d/pipeline/jit/pipeprimitives.cpp 316 blend2d/pipeline/jit/pipeprimitives_p.h 317 blend2d/pipeline/jit/pipegenruntime_p.h 318 blend2d/pipeline/jit/pipegenruntime.cpp 319 blend2d/pipeline/jit/pipepart.cpp 320 blend2d/pipeline/jit/pipepart_p.h 321 322 blend2d/pipeline/reference/compopgeneric_p.h 323 blend2d/pipeline/reference/fetchgeneric_p.h 324 blend2d/pipeline/reference/fillgeneric_p.h 325 blend2d/pipeline/reference/fixedpiperuntime_p.h 326 blend2d/pipeline/reference/fixedpiperuntime.cpp 327 blend2d/pipeline/reference/pixelbufferptr_p.h 328 blend2d/pipeline/reference/pixelgeneric_p.h 329 330 blend2d/pixelops/interpolation.cpp 331 blend2d/pixelops/interpolation_avx2.cpp 332 blend2d/pixelops/interpolation_sse2.cpp 333 blend2d/pixelops/funcs.cpp 334 blend2d/pixelops/funcs_p.h 335 blend2d/pixelops/scalar_test.cpp 336 blend2d/pixelops/scalar_p.h 337 338 blend2d/raster/analyticrasterizer_test.cpp 339 blend2d/raster/analyticrasterizer_p.h 340 blend2d/raster/debugging_p.h 341 blend2d/raster/edgebuilder_p.h 342 blend2d/raster/edgestorage_p.h 343 blend2d/raster/rastercontext.cpp 344 blend2d/raster/rastercontext_p.h 345 blend2d/raster/rastercontextops.cpp 346 blend2d/raster/rastercontextops_p.h 347 blend2d/raster/rasterdefs_p.h 348 blend2d/raster/renderbatch_p.h 349 blend2d/raster/rendercommand_p.h 350 blend2d/raster/rendercommandprocasync_p.h 351 blend2d/raster/rendercommandprocsync_p.h 352 blend2d/raster/renderfetchdata.cpp 353 blend2d/raster/renderfetchdata_p.h 354 blend2d/raster/renderjob_p.h 355 blend2d/raster/renderjobproc_p.h 356 blend2d/raster/renderqueue_p.h 357 blend2d/raster/rendertargetinfo.cpp 358 blend2d/raster/rendertargetinfo_p.h 359 blend2d/raster/statedata_p.h 360 blend2d/raster/styledata_p.h 361 blend2d/raster/workdata.cpp 362 blend2d/raster/workdata_p.h 363 blend2d/raster/workermanager.cpp 364 blend2d/raster/workermanager_p.h 365 blend2d/raster/workerproc.cpp 366 blend2d/raster/workerproc_p.h 367 blend2d/raster/workersynchronization.cpp 368 blend2d/raster/workersynchronization_p.h 369 370 blend2d/simd/simd_p.h 371 blend2d/simd/simd_test.cpp 372 blend2d/simd/simd_test_p.h 373 blend2d/simd/simdbase_p.h 374 blend2d/simd/simdarm_p.h 375 blend2d/simd/simdarm_test_asimd.cpp 376 blend2d/simd/simdx86_p.h 377 blend2d/simd/simdx86_test_avx.cpp 378 blend2d/simd/simdx86_test_avx2.cpp 379 blend2d/simd/simdx86_test_avx512.cpp 380 blend2d/simd/simdx86_test_sse2.cpp 381 blend2d/simd/simdx86_test_sse4_1.cpp 382 blend2d/simd/simdx86_test_sse4_2.cpp 383 blend2d/simd/simdx86_test_ssse3.cpp 384 385 blend2d/support/algorithm_test.cpp 386 blend2d/support/algorithm_p.h 387 blend2d/support/arenaallocator.cpp 388 blend2d/support/arenaallocator_p.h 389 blend2d/support/arenabitarray_test.cpp 390 blend2d/support/arenabitarray_p.h 391 blend2d/support/arenahashmap.cpp 392 blend2d/support/arenahashmap_test.cpp 393 blend2d/support/arenahashmap_p.h 394 blend2d/support/arenalist_test.cpp 395 blend2d/support/arenalist_p.h 396 blend2d/support/arenatree_test.cpp 397 blend2d/support/arenatree_p.h 398 blend2d/support/bitops_test.cpp 399 blend2d/support/bitops_p.h 400 blend2d/support/fixedbitarray_p.h 401 blend2d/support/hashops_p.h 402 blend2d/support/intops_test.cpp 403 blend2d/support/intops_p.h 404 blend2d/support/lookuptable_p.h 405 blend2d/support/math.cpp 406 blend2d/support/math_test.cpp 407 blend2d/support/math_p.h 408 blend2d/support/memops_test.cpp 409 blend2d/support/memops_p.h 410 blend2d/support/ptrops_test.cpp 411 blend2d/support/ptrops_p.h 412 blend2d/support/scopedallocator.cpp 413 blend2d/support/scopedallocator_p.h 414 blend2d/support/scopedbuffer_p.h 415 blend2d/support/stringops_p.h 416 blend2d/support/wrap_p.h 417 blend2d/support/zeroallocator.cpp 418 blend2d/support/zeroallocator_test.cpp 419 blend2d/support/zeroallocator_p.h 420 421 blend2d/tables/tables.cpp 422 blend2d/tables/tables_test.cpp 423 blend2d/tables/tables_p.h 424 425 blend2d/threading/atomic_p.h 426 blend2d/threading/conditionvariable_p.h 427 blend2d/threading/futex.cpp 428 blend2d/threading/futex_p.h 429 blend2d/threading/mutex_p.h 430 blend2d/threading/thread.cpp 431 blend2d/threading/thread_p.h 432 blend2d/threading/threadingutils_p.h 433 blend2d/threading/threadpool.cpp 434 blend2d/threading/threadpool_test.cpp 435 blend2d/threading/threadpool_p.h 436 blend2d/threading/tsanutils_p.h 437 blend2d/threading/uniqueidgenerator.cpp 438 blend2d/threading/uniqueidgenerator_p.h 439 440 blend2d/unicode/unicode.cpp 441 blend2d/unicode/unicode_test.cpp 442 blend2d/unicode/unicode_p.h 443 ) 444 445 set(BLEND2D_BENCH_SRC 446 testing/bench/bl_bench_app.cpp 447 testing/bench/bl_bench_app.h 448 testing/bench/bl_bench_backend.cpp 449 testing/bench/bl_bench_backend.h 450 testing/bench/bl_bench_backend_agg.cpp 451 testing/bench/bl_bench_backend_blend2d.cpp 452 testing/bench/bl_bench_backend_cairo.cpp 453 testing/bench/bl_bench_backend_coregraphics.cpp 454 testing/bench/bl_bench_backend_juce.cpp 455 testing/bench/bl_bench_backend_qt.cpp 456 testing/bench/bl_bench_backend_skia.cpp 457 testing/bench/images_data.h 458 testing/bench/jsonbuilder.cpp 459 testing/bench/jsonbuilder.h 460 testing/bench/shape_data.cpp 461 testing/bench/shape_data.h 462 ) 463 464 # Blend2D - CMake Utilities 465 # ========================= 466 467 include(CheckCXXCompilerFlag) 468 include(CheckCSourceCompiles) 469 include(CheckLinkerFlag) 470 include(GNUInstallDirs) 471 472 # Detects target architecture - since the code doesn't run it works also for cross-compilation. 473 function(blend2d_detect_target_arch out) 474 set(${out} "unknown" PARENT_SCOPE) 475 foreach(target_arch "X86_64" "AARCH64" "X86" "AARCH32") 476 check_c_source_compiles(" 477 #if defined(_M_X64) || defined(__x86_64__) 478 static int target_arch_is_X86_64() { return 1; } 479 #elif defined(_M_IX86) || defined(__X86__) || defined(__i386__) 480 static int target_arch_is_X86() { return 1; } 481 #elif defined(_M_ARM64) || defined(__arm64__) || defined(__aarch64__) 482 static int target_arch_is_AARCH64() { return 1; } 483 #elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__) || defined(__thumb2__) 484 static int target_arch_is_AARCH32() { return 1; } 485 #endif 486 int main(void) { return target_arch_is_${target_arch}(); }" "${out}_${target_arch}") 487 if (${${out}_${target_arch}}) 488 set(${out} "${target_arch}" PARENT_SCOPE) 489 return() 490 endif() 491 endforeach() 492 endfunction() 493 494 # Detects C++ compile flags and appends all detected ones to `out`. 495 function(blend2d_detect_cflags out) 496 set(_out_array ${${out}}) 497 string(REGEX REPLACE "[+]" "x" _flag_signature "${ARGN}") 498 string(REGEX REPLACE "[-= :;/.\]" "_" _flag_signature "${_flag_signature}") 499 500 if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(GNU|Clang|AppleClang)$") 501 check_cxx_compiler_flag("${ARGN} -Werror" "__CxxFlag_${_flag_signature}") 502 else() 503 check_cxx_compiler_flag("${ARGN}" "__CxxFlag_${_flag_signature}") 504 endif() 505 506 if (${__CxxFlag_${_flag_signature}}) 507 list(APPEND _out_array ${ARGN}) 508 endif() 509 set(${out} "${_out_array}" PARENT_SCOPE) 510 endfunction() 511 512 # Detects C++ link flags and appends all detected ones to `out`. 513 function(blend2d_detect_lflags out) 514 set(_out_array ${${out}}) 515 516 foreach(_flag ${ARGN}) 517 string(REGEX REPLACE "[+]" "x" _flag_signature "${_flag}") 518 string(REGEX REPLACE "[-= :;/.\]" "_" _flag_signature "${_flag_signature}") 519 check_linker_flag(CXX "${_flag}" "__LinkFlag_${_flag_signature}") 520 if (${__LinkFlag_${_flag_signature}}) 521 list(APPEND _out_array ${_flag}) 522 endif() 523 endforeach() 524 525 set(${out} "${_out_array}" PARENT_SCOPE) 526 endfunction() 527 528 # Support for various sanitizers provided by C/C++ compilers. 529 function(blend2d_detect_sanitizers out) 530 set(_out_array ${${out}}) 531 set(_flags "") 532 533 foreach(_arg ${ARGN}) 534 string(REPLACE "," ";" _arg "${_arg}") 535 list(APPEND _flags ${_arg}) 536 endforeach() 537 538 foreach(_flag ${_flags}) 539 if (NOT "${_flag}" MATCHES "^-fsanitize=") 540 SET(_flag "-fsanitize=${_flag}") 541 endif() 542 543 # Sanitizers also require link flags, see CMAKE_REQUIRED_FLAGS. 544 set(CMAKE_REQUIRED_FLAGS "${_flag}") 545 blend2d_detect_cflags(_out_array ${_flag}) 546 unset(CMAKE_REQUIRED_FLAGS) 547 endforeach() 548 549 set(${out} "${_out_array}" PARENT_SCOPE) 550 endfunction() 551 552 function(blend2d_add_target target target_type) 553 set(multi_value_args SOURCES INCLUDE_DIRS CFLAGS CFLAGS_DBG CFLAGS_REL LFLAGS LIBRARIES) 554 cmake_parse_arguments("ARG" "" "" "${multi_value_args}" ${ARGN}) 555 556 if ("${target_type}" MATCHES "^(EXECUTABLE|EXECUTABLE_WIN32|TEST)$") 557 if ("${target_type}" MATCHES "^(EXECUTABLE_WIN32)$") 558 add_executable(${target} WIN32 ${ARG_SOURCES}) 559 else() 560 add_executable(${target} ${ARG_SOURCES}) 561 endif() 562 set_target_properties(${target} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$(TargetDir).") 563 else() 564 add_library(${target} ${target_type} ${ARG_SOURCES}) 565 endif() 566 567 set_target_properties(${target} PROPERTIES DEFINE_SYMBOL "" CXX_VISIBILITY_PRESET hidden) 568 target_include_directories(${target} BEFORE PRIVATE ${ARG_INCLUDE_DIRS}) 569 target_compile_options(${target} PRIVATE ${ARG_CFLAGS} ${BLEND2D_SANITIZE_CFLAGS} $<IF:$<CONFIG:Debug>,${ARG_CFLAGS_DBG},${ARG_CFLAGS_REL}>) 570 target_compile_features(${target} PUBLIC cxx_std_17) 571 target_link_options(${target} PRIVATE ${ARG_LFLAGS} ${BLEND2D_SANITIZE_LFLAGS}) 572 target_link_libraries(${target} PRIVATE ${ARG_LIBRARIES}) 573 574 if ("${target_type}" STREQUAL "TEST") 575 add_test(NAME ${target} COMMAND ${target}) 576 endif() 577 endfunction() 578 579 # Blend2D - Features 580 # ================== 581 582 blend2d_detect_target_arch(BLEND2D_TARGET_ARCH) 583 584 if (BLEND2D_NO_JIT) 585 message(STATUS "[blend2d] Disabling JIT compiler support ('BLEND2D_TARGET_ARCH=${BLEND2D_TARGET_ARCH}', but 'BLEND2D_NO_JIT=${BLEND2D_NO_JIT}')") 586 set(BLEND2D_BUILD_WITH_JIT FALSE) 587 elseif ("${BLEND2D_TARGET_ARCH}" MATCHES "^(X86|X86_64|AARCH64)$") 588 message(STATUS "[blend2d] Enabling JIT compiler support ('BLEND2D_TARGET_ARCH=${BLEND2D_TARGET_ARCH}' is supported)") 589 set(BLEND2D_BUILD_WITH_JIT TRUE) 590 else() 591 message(STATUS "[blend2d] Disabling JIT compiler support ('BLEND2D_TARGET_ARCH=${BLEND2D_TARGET_ARCH}' isn't supported)") 592 set(BLEND2D_BUILD_WITH_JIT FALSE) 593 endif() 594 595 if (BLEND2D_NO_TLS) 596 message(STATUS "[blend2d] Disabling use of TLS ('BLEND2D_NO_TLS=${BLEND2D_NO_TLS}')") 597 list(APPEND BLEND2D_PRIVATE_CFLAGS -DBL_BUILD_NO_TLS) 598 endif() 599 600 if (BLEND2D_NO_FUTEX) 601 message(STATUS "[blend2d] Disabling futex support ('BLEND2D_NO_FUTEX=${BLEND2D_NO_FUTEX}')") 602 list(APPEND BLEND2D_PRIVATE_CFLAGS -DBL_BUILD_NO_FUTEX) 603 endif() 604 605 # Blend2D - Compiler Support - Detection 606 # ====================================== 607 608 if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") 609 list(APPEND BLEND2D_WARNING_CFLAGS -W4) # [+] Warning level 4. 610 611 list(APPEND BLEND2D_PRIVATE_CFLAGS -MP) # [+] Multi-Process Compilation. 612 list(APPEND BLEND2D_PRIVATE_CFLAGS -GR-) # [-] Runtime type information. 613 list(APPEND BLEND2D_PRIVATE_CFLAGS -GF) # [+] Eliminate duplicate strings. 614 list(APPEND BLEND2D_PRIVATE_CFLAGS -Zc:__cplusplus) # [+] Conforming __cplusplus definition. 615 list(APPEND BLEND2D_PRIVATE_CFLAGS -Zc:inline) # [+] Remove unreferenced COMDAT. 616 list(APPEND BLEND2D_PRIVATE_CFLAGS -Zc:strictStrings) # [+] Strict const qualification of string literals. 617 list(APPEND BLEND2D_PRIVATE_CFLAGS -Zc:threadSafeInit-) # [-] Thread-safe statics. 618 619 list(APPEND BLEND2D_PRIVATE_CFLAGS_DBG -GS) # [+] Buffer security-check. 620 list(APPEND BLEND2D_PRIVATE_CFLAGS_REL -GS-) # [-] Buffer security-check. 621 list(APPEND BLEND2D_PRIVATE_CFLAGS_REL -O2) # [+] Favor speed over size. 622 list(APPEND BLEND2D_PRIVATE_CFLAGS_REL -Oi) # [+] Generate Intrinsic Functions. 623 624 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 625 list(APPEND BLEND2D_PRIVATE_CFLAGS -clang:-fno-rtti -clang:-fno-math-errno -clang:-fno-trapping-math) 626 endif() 627 blend2d_detect_cflags(BLEND2D_PRIVATE_CFLAGS -Zc:arm64-aliased-neon-types-) # [-] ARM64 aliased neon types 628 elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang") 629 list(APPEND BLEND2D_WARNING_CFLAGS -Wall -Wextra -Wconversion) # [+] Add baseline warnings that can be used safely even with system headers. 630 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wdouble-promotion) # [+] Warn about double promotions. 631 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wduplicated-cond) # [+] Warn about duplicate conditions. 632 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wduplicated-branches) # [+] Warn about duplicate branches. 633 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wlogical-op) # [+] Warn about suspicious uses of logical operators in expressions. 634 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wlogical-not-parentheses) # [+] Warn about logical not used on the left hand side operand of a comparison. 635 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wrestrict) 636 blend2d_detect_cflags(BLEND2D_WARNING_CFLAGS -Wbidi-chars=any) # [+] Warn about using BIDI characters in source code (we don't use them). 637 638 list(APPEND BLEND2D_PRIVATE_CFLAGS -fno-math-errno) # [-] Disable math functions setting errno (performance reasons). 639 list(APPEND BLEND2D_PRIVATE_CFLAGS -fno-threadsafe-statics) # [-] Don't add guards when initializing statics (we don't need it). 640 list(APPEND BLEND2D_PRIVATE_CFLAGS -fno-exceptions -fno-rtti) # [-] Disable exceptions and RTTI (we never throw, we don't need RTTI). 641 list(APPEND BLEND2D_PRIVATE_CFLAGS_REL -O2) # [+] Compiling with -O2 in release mode is what we generally want. 642 list(APPEND BLEND2D_PRIVATE_CFLAGS_REL -fmerge-all-constants) # [+] We don't need unique address per constant (merging improves library size). 643 644 # -fno-semantic-interposition is not available on apple - the compiler issues a warning, which is not detected. 645 if (NOT APPLE) 646 blend2d_detect_cflags(BLEND2D_PRIVATE_CFLAGS -fno-semantic-interposition) 647 endif() 648 649 if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "iOS") 650 list(APPEND BLEND2D_PRIVATE_CFLAGS -fno-trapping-math -fno-finite-math-only)# [-] Disable these flags in case somebody uses `-ffast-math` globally. 651 blend2d_detect_cflags(BLEND2D_PRIVATE_CFLAGS_REL -fno-enforce-eh-specs) # [-] We never throw, so we don't need strict exception handling enforcement. 652 endif() 653 654 blend2d_detect_cflags(BLEND2D_PRIVATE_CFLAGS -mllvm --disable-loop-idiom-all) # [-] Don't use memset/memcpy instead of our own loops (critical in some cases). 655 blend2d_detect_cflags(BLEND2D_PRIVATE_CFLAGS_REL -ftree-vectorize) # [+] Auto-vectorize by default in release builds (sometimes helps). 656 657 # Building Blend2D without C++ library support requires these to be setup. 658 if (BLEND2D_NO_STDCXX) 659 message(STATUS "[blend2d] Enabling build without linking to the C++ standard library ('BLEND2D_NO_STDCXX=${BLEND2D_NO_STDCXX}')") 660 list(APPEND BLEND2D_NO_STDCXX_CFLAGS -DBL_BUILD_NO_STDCXX) 661 blend2d_detect_lflags(BLEND2D_NO_STDCXX_LFLAGS -static-libgcc -static-libstdc++) 662 endif() 663 endif() 664 665 if (BLEND2D_TARGET_ARCH MATCHES "^(X86|X86_64)$") 666 set(BLEND2D_CFLAGS_SSE2 "") 667 if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") 668 if ("${BLEND2D_TARGET_ARCH}" STREQUAL "X86") 669 set(BLEND2D_CFLAGS_SSE2 -arch:SSE2) # 32-bit target requires -arch:SSE2. 670 endif() 671 672 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 673 # To enable certain optimizations for clang-cl additional flags have to be passed (MSVC incompatibility). 674 set(BLEND2D_CFLAGS_SSE3 ${BLEND2D_CFLAGS_SSE2} -msse3) 675 set(BLEND2D_CFLAGS_SSSE3 ${BLEND2D_CFLAGS_SSE2} -mssse3) 676 set(BLEND2D_CFLAGS_SSE4_1 ${BLEND2D_CFLAGS_SSE2} -msse4.1) 677 set(BLEND2D_CFLAGS_SSE4_2 ${BLEND2D_CFLAGS_SSE2} -msse4.2 -mpopcnt -mpclmul) 678 set(BLEND2D_CFLAGS_AVX -arch:AVX -mpopcnt -mpclmul) 679 set(BLEND2D_CFLAGS_AVX2 -arch:AVX2 -mpopcnt -mpclmul -mbmi -mbmi2) 680 set(BLEND2D_CFLAGS_AVX2FMA -arch:AVX2 -mpopcnt -mpclmul -mbmi -mbmi2 -mfma) 681 set(BLEND2D_CFLAGS_AVX512 -arch:AVX512 -mpopcnt -mpclmul -mbmi -mbmi2) 682 else() 683 # MSVC doesn't distinguish between some optimization levels - so add some definitions manually. 684 set(BLEND2D_CFLAGS_SSE3 ${BLEND2D_CFLAGS_SSE2} -D__SSE3__) 685 set(BLEND2D_CFLAGS_SSSE3 ${BLEND2D_CFLAGS_SSE2} -D__SSSE3__) 686 set(BLEND2D_CFLAGS_SSE4_1 ${BLEND2D_CFLAGS_SSE2} -D__SSE4_1__) 687 set(BLEND2D_CFLAGS_SSE4_2 ${BLEND2D_CFLAGS_SSE2} -D__SSE4_2__) 688 set(BLEND2D_CFLAGS_AVX -arch:AVX) 689 set(BLEND2D_CFLAGS_AVX2 -arch:AVX2) 690 set(BLEND2D_CFLAGS_AVX2FMA -arch:AVX2) 691 set(BLEND2D_CFLAGS_AVX512 -arch:AVX512) 692 endif() 693 else() 694 if ("${BLEND2D_TARGET_ARCH}" STREQUAL "X86") 695 if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 696 set(BLEND2D_CFLAGS_SSE2 -msse2 -mfpmath=sse) 697 else() 698 set(BLEND2D_CFLAGS_SSE2 -msse2) 699 endif() 700 endif() 701 set(BLEND2D_CFLAGS_SSE3 -msse3) 702 set(BLEND2D_CFLAGS_SSSE3 -mssse3) 703 set(BLEND2D_CFLAGS_SSE4_1 -msse4.1) 704 set(BLEND2D_CFLAGS_SSE4_2 -mpopcnt -mpclmul -msse4.2) 705 set(BLEND2D_CFLAGS_AVX -mpopcnt -mpclmul -mavx) 706 set(BLEND2D_CFLAGS_AVX2 -mpopcnt -mpclmul -mbmi -mbmi2 -mavx2) 707 set(BLEND2D_CFLAGS_AVX2FMA -mpopcnt -mpclmul -mbmi -mbmi2 -mavx2 -mfma) 708 set(BLEND2D_CFLAGS_AVX512 -mpopcnt -mpclmul -mbmi -mbmi2 -mavx512f -mavx512bw -mavx512dq -mavx512cd -mavx512vl) 709 endif() 710 711 list(APPEND BLEND2D_CFLAGS_AVX2 -DBL_TARGET_OPT_POPCNT -DBL_TARGET_OPT_BMI2) 712 list(APPEND BLEND2D_CFLAGS_AVX2FMA -DBL_TARGET_OPT_POPCNT -DBL_TARGET_OPT_BMI2 -DBL_TARGET_OPT_FMA) 713 list(APPEND BLEND2D_CFLAGS_AVX512 -DBL_TARGET_OPT_POPCNT -DBL_TARGET_OPT_BMI2) 714 715 # SSE2 is our baseline if no other baseline is specified; AVX512 is our maximum. 716 list(APPEND BLEND2D_PRIVATE_CFLAGS ${BLEND2D_CFLAGS_SSE2} -DBL_BUILD_OPT_AVX512) 717 elseif ("${BLEND2D_TARGET_ARCH}" MATCHES "^(AARCH32|AARCH64)$") 718 if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") 719 # FIXME: Not sure whether it makes sense to detect anything in this case. 720 else() 721 blend2d_detect_cflags(BLEND2D_CFLAGS_ASIMD -mfpu=neon-vfpv4) 722 if ("${BLEND2D_TARGET_ARCH}" STREQUAL "AARCH64") 723 blend2d_detect_cflags(BLEND2D_CFLAGS_ASIMD_CRYPTO -march=armv8-a+aes+crc+crypto) 724 endif() 725 endif() 726 727 if (BLEND2D_CFLAGS_ASIMD) 728 list(APPEND BLEND2D_PRIVATE_CFLAGS -DBL_BUILD_OPT_ASIMD) 729 list(APPEND BLEND2D_CFLAGS_ASIMD -DBL_TARGET_OPT_ASIMD) 730 endif() 731 732 if (BLEND2D_CFLAGS_ASIMD_CRYPTO) 733 list(APPEND BLEND2D_PRIVATE_CFLAGS -DBL_BUILD_OPT_ASIMD_CRYPTO) 734 list(APPEND BLEND2D_CFLAGS_ASIMD_CRYPTO -DBL_TARGET_OPT_ASIMD_CRYPTO) 735 endif() 736 endif() 737 738 list(APPEND BLEND2D_PRIVATE_CFLAGS ${BLEND2D_WARNING_CFLAGS}) 739 740 # Blend2D - Compiler Support - Sanitizers 741 # ======================================= 742 743 if (BLEND2D_SANITIZE) 744 blend2d_detect_sanitizers(BLEND2D_SANITIZE_CFLAGS ${BLEND2D_SANITIZE}) 745 if (BLEND2D_SANITIZE_CFLAGS) 746 message(STATUS "[blend2d] Enabling sanitizers: '${BLEND2D_SANITIZE_CFLAGS}'") 747 748 # Linker must receive the same flags as the compiler when it comes to sanitizers. 749 set(BLEND2D_SANITIZE_LFLAGS ${BLEND2D_SANITIZE_CFLAGS}) 750 751 # Don't omit frame pointer if sanitizers are enabled. 752 if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") 753 list(APPEND BLEND2D_SANITIZE_CFLAGS -Oy-) 754 else() 755 list(APPEND BLEND2D_SANITIZE_CFLAGS -fno-omit-frame-pointer -g) 756 endif() 757 758 list(APPEND BLEND2D_PRIVATE_CFLAGS ${BLEND2D_SANITIZE_CFLAGS}) 759 list(APPEND BLEND2D_PRIVATE_LFLAGS ${BLEND2D_SANITIZE_LFLAGS}) 760 endif() 761 endif() 762 763 # Blend2D - Compiler Support - Natvis Embedding 764 # ============================================= 765 766 if (WIN32) 767 if(CMAKE_LINKER MATCHES "link\\.exe" OR CMAKE_LINKER MATCHES "lld-link\\.exe") 768 set(BLEND2D_LINKER_SUPPORTS_NATVIS TRUE) 769 endif() 770 endif() 771 772 # Blend2D - Dependencies 773 # ====================== 774 775 if (WIN32) 776 # Dependency: nothing extra at the moment. 777 elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") 778 # Dependency: libc is the only required library on Android as it also provides libthread. 779 message(STATUS "[blend2d] Adding libc dependency (Android)") 780 list(APPEND BLEND2D_DEPS c) 781 elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku") 782 # Dependency: libroot is used by Haiku instead of libc, so link to libroot and libpthread. 783 message(STATUS "[blend2d] Adding libroot, libm, and libpthread dependencies (Haiku)") 784 list(APPEND BLEND2D_DEPS root m pthread) 785 else() 786 # Dependency: libc is always required. 787 message(STATUS "[blend2d] Adding libc dependency (Linux, BSD, or other UNIX/POSIX environment)") 788 list(APPEND BLEND2D_DEPS c) 789 790 # Dependency: pthread (required so Blend2D can use pthread_rwlock, pthread_create, ...). 791 check_c_source_compiles(" 792 #include <pthread.h> 793 794 static void* thread_entry_point(void* arg) { return arg; } 795 int main() { 796 pthread_rwlock_t m; 797 pthread_rwlock_init(&m, (void*)0); 798 pthread_rwlock_wrlock(&m); 799 pthread_rwlock_unlock(&m); 800 801 pthread_attr_t attr; 802 pthread_attr_init(&attr); 803 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 804 pthread_attr_setstacksize(&attr, 1024*1024); 805 806 pthread_t handle; 807 return pthread_create(&handle, &attr, thread_entry_point, (void*)0); 808 } 809 " BLEND2D_LIBC_HAS_LIBPTHREAD) 810 if (BLEND2D_LIBC_HAS_LIBPTHREAD) 811 message(STATUS "[blend2d] Library 'libpthread' provided by 'libc' (not linking to libpthread)") 812 else() 813 message(STATUS "[blend2d] Library 'libpthread' not provided by 'libc' (linking to libpthread)") 814 list(APPEND BLEND2D_DEPS pthread) 815 endif() 816 817 check_c_source_compiles(" 818 #include <math.h> 819 int main(int argc, char* argv[]) { 820 (void)argv; return (int)sin((double)argc * 0.1234); 821 } 822 " BLEND2D_LIBC_HAS_LIBM) 823 if (BLEND2D_LIBC_HAS_LIBM) 824 message(STATUS "[blend2d] Library 'libm' provided by 'libc' (not linking to libm)") 825 else() 826 message(STATUS "[blend2d] Library 'libm' not provided by 'libc' (linking to libm)") 827 list(APPEND BLEND2D_DEPS m) 828 endif() 829 endif() 830 831 # Find asmjit dependency if building with JIT. 832 if (BLEND2D_BUILD_WITH_JIT) 833 if (BLEND2D_EXTERNAL_ASMJIT) 834 message(STATUS "[blend2d] Trying to find external asmjit ('BLEND2D_EXTERNAL_ASMJIT=${BLEND2D_EXTERNAL_ASMJIT}')\n") 835 message(WARNING 836 "Using external asmjit library means you are opting out of using the\n" 837 "bundled one, which is the preferred way especially if Blend2D is compiled\n" 838 "as a shared library. In that case asmjit is configured by Blend2D to only\n" 839 "include the target architecture that is actually used (all foreign backends\n" 840 "are disabled) and is built the same way as Blend2D (without exceptions/rtti).\n" 841 "\n" 842 "In general, using external asmjit option was introduced for package managers\n" 843 "that prefer each dependency to be built separately. In this case the burden\n" 844 "of configuring the dependency is on you.\n" 845 "\n" 846 "Do you want a smaller binary? Use 'ASMJIT_NO_FOREIGN' option to disable foreign\n" 847 "architectures.\n" 848 "\n" 849 "If you are concerned about security (not using anything bundled) you can\n" 850 "just git checkout https://github.com/asmjit/asmjit into [root]/3rdparty/asmjit\n" 851 "or set ASMJIT_DIR variable to point to a previously checked out asmjit.\n") 852 find_package(asmjit REQUIRED) 853 list(APPEND BLEND2D_DEPS asmjit::asmjit) 854 else() 855 message(STATUS "[blend2d] Trying to find bundled asmjit ('BLEND2D_EXTERNAL_ASMJIT=OFF')") 856 if (NOT DEFINED ASMJIT_DIR) 857 foreach(dir "${CMAKE_CURRENT_LIST_DIR}/3rdparty/asmjit" "${CMAKE_CURRENT_LIST_DIR}/../asmjit") 858 if (EXISTS ${dir}/CMakeLists.txt) 859 set(ASMJIT_DIR "${dir}" CACHE PATH "Location of 'asmjit'") 860 break() 861 endif() 862 endforeach() 863 if (NOT DEFINED ASMJIT_DIR) 864 message(FATAL 865 "[blend2d] Unable to find asmjit, please see <https://blend2d.com/doc/build-instructions.html>\n" 866 "\n" 867 "Blend2D expects asmjit to be in the following directories:\n" 868 "\n" 869 " - ASMJIT_DIR - CMake variable specifying asmjit directory\n" 870 " - '<root>/3rdparty/asmjit' - asmjit bundled in source releases\n" 871 " - '<root>/../asmjit' - asmjit location when developing Blend2D\n" 872 "\n" 873 "Alternatively, if you use C/C++ package managers and would like to use\n" 874 "a packaged asmjit instead, set BLEND2D_EXTERNAL_ASMJIT cmake variable to TRUE.\n" 875 "This way Blend2D would not try to auto-detect the location of asmjit and would\n" 876 "try to find it by using find_package() instead. Please note that using extenal\n" 877 "asmjit means that Blend2D would not be able to avoid linking to a C++ standard\n" 878 "library, which it does by default when building a shared Blend2D library with\n" 879 "bundled asmjit." 880 ) 881 endif() 882 endif() 883 884 if (NOT DEFINED ASMJIT_EMBED) 885 set(ASMJIT_EMBED TRUE CACHE BOOL "") 886 endif() 887 888 message(STATUS "[blend2d] === Embedding asmjit (including its CMakeLists.txt) ===") 889 include("${ASMJIT_DIR}/CMakeLists.txt") 890 message(STATUS "[blend2d] === Embedding asmjit done ===") 891 892 list(APPEND BLEND2D_DEPS ${ASMJIT_LIBS}) 893 list(APPEND BLEND2D_PRIVATE_CFLAGS ${ASMJIT_CFLAGS}) 894 list(APPEND BLEND2D_PRIVATE_CFLAGS -DASMJIT_NO_STDCXX -DASMJIT_NO_FOREIGN -DASMJIT_ABI_NAMESPACE=abi_bl) 895 896 # A possibility to reduce the resulting binary size by disabling asmjit logging. 897 if (BLEND2D_NO_JIT_LOGGING) 898 message(STATUS "[blend2d] Disabling asmjit logging functionality (JIT)") 899 list(APPEND BLEND2D_PRIVATE_CFLAGS -DASMJIT_NO_LOGGING -DASMJIT_NO_TEXT) 900 endif() 901 endif() 902 else() 903 list(APPEND BLEND2D_PRIVATE_CFLAGS -DBL_BUILD_NO_JIT) 904 endif() 905 906 # Blend2D - Finalize Build Options 907 # ================================ 908 909 list(REMOVE_DUPLICATES BLEND2D_DEPS) 910 list(REMOVE_DUPLICATES BLEND2D_PRIVATE_CFLAGS) 911 912 # Blend2D - Source Files Processing 913 # ================================= 914 915 if (MSVC AND NOT BLEND2D_NO_NATVIS) 916 list(APPEND BLEND2D_SRC_LIST blend2d.natvis) 917 endif() 918 919 set(BLEND2D_SRC "") 920 set(BLEND2D_TEST_SRC_FILES "") 921 set(BLEND2D_OPT_EXTENSIONS "sse2|sse3|ssse3|sse4_1|sse4_2|avx|avx2|avx2fma|avx512|asimd|asimd_crypto") 922 923 foreach(src_file ${BLEND2D_SRC_LIST}) 924 set(src_file "${CMAKE_CURRENT_LIST_DIR}/src/${src_file}") 925 926 if ("${src_file}" MATCHES "_test(_(${BLEND2D_OPT_EXTENSIONS}))?\\.cpp$") 927 list(APPEND BLEND2D_TEST_SRC_FILES ${src_file}) 928 else() 929 list(APPEND BLEND2D_SRC ${src_file}) 930 endif() 931 932 string(REGEX MATCH "_(${BLEND2D_OPT_EXTENSIONS})\\.(c|cc|cxx|cpp|m|mm)$" FEATURE ${src_file}) 933 if (FEATURE) 934 # HACK 1: Cmake uses global variables everywhere, `CMAKE_MATCH_1` is the first capture... 935 string(TOUPPER "${CMAKE_MATCH_1}" FEATURE) 936 # HACK 2: Interestingly COMPILE_OPTIONS is not available for SOURCE files before CMake 3.11. 937 # set_property(SOURCE "${src_file}" APPEND PROPERTY COMPILE_OPTIONS ${BLEND2D_CFLAGS_${FEATURE}}) 938 foreach(src_cflag ${BLEND2D_CFLAGS_${FEATURE}}) 939 set_property(SOURCE "${src_file}" APPEND_STRING PROPERTY COMPILE_FLAGS " ${src_cflag}") 940 endforeach() 941 endif() 942 943 if ("${src_file}" MATCHES "\\.natvis") 944 if (BLEND2D_LINKER_SUPPORTS_NATVIS) 945 list(APPEND BLEND2D_PRIVATE_LFLAGS "-natvis:${src_file}") 946 endif() 947 endif() 948 endforeach() 949 950 source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${BLEND2D_SRC}) 951 952 set(BLEND2D_ALL_SRC_FILES ${BLEND2D_SRC}) 953 if (ASMJIT_EMBED) 954 list(APPEND BLEND2D_ALL_SRC_FILES ${ASMJIT_SRC}) 955 endif() 956 957 # Blend2D - Summary 958 # ================= 959 960 message("** Blend2D Summary **") 961 message(" BLEND2D_DEPS=${BLEND2D_DEPS}") 962 message(" BLEND2D_CFLAGS=${BLEND2D_CFLAGS}") 963 message(" BLEND2D_WARNING_CFLAGS=${BLEND2D_WARNING_CFLAGS}") 964 message(" BLEND2D_PRIVATE_CFLAGS=${BLEND2D_PRIVATE_CFLAGS}") 965 message(" BLEND2D_PRIVATE_CFLAGS_DBG=${BLEND2D_PRIVATE_CFLAGS_DBG}") 966 message(" BLEND2D_PRIVATE_CFLAGS_REL=${BLEND2D_PRIVATE_CFLAGS_REL}") 967 if (BLEND2D_SANITIZE) 968 message(" BLEND2D_SANITIZE=${BLEND2D_SANITIZE}") 969 message(" BLEND2D_SANITIZE_CFLAGS=${BLEND2D_SANITIZE_CFLAGS}") 970 message(" BLEND2D_SANITIZE_LFLAGS=${BLEND2D_SANITIZE_LFLAGS}") 971 endif() 972 973 # Blend2D - Targets - Core Library & 'blend2d::blend2d' Alias 974 # =========================================================== 975 976 blend2d_add_target(blend2d ${BLEND2D_TARGET_TYPE} 977 SOURCES ${BLEND2D_ALL_SRC_FILES} 978 LIBRARIES ${BLEND2D_DEPS} 979 INCLUDE_DIRS ${ASMJIT_INCLUDE_DIRS} 980 CFLAGS ${BLEND2D_PRIVATE_CFLAGS} ${BLEND2D_NO_STDCXX_CFLAGS} 981 CFLAGS_DBG ${BLEND2D_PRIVATE_CFLAGS_DBG} 982 CFLAGS_REL ${BLEND2D_PRIVATE_CFLAGS_REL} 983 LFLAGS ${BLEND2D_NO_STDCXX_LFLAGS}) 984 985 target_compile_options(blend2d INTERFACE ${BLEND2D_CFLAGS}) 986 target_include_directories(blend2d BEFORE INTERFACE 987 $<BUILD_INTERFACE:${BLEND2D_INCLUDE_DIRS}> 988 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) 989 990 add_library(blend2d::blend2d ALIAS blend2d) 991 992 # Add Blend2D install instructions (library and public headers). 993 if (NOT BLEND2D_NO_INSTALL) 994 message(STATUS "[blend2d] Enabling install support ('BLEND2D_NO_INSTALL=OFF')") 995 include(CMakePackageConfigHelpers) 996 997 install(TARGETS blend2d 998 EXPORT blend2d-targets 999 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 1000 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 1001 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 1002 INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 1003 1004 install(EXPORT blend2d-targets 1005 NAMESPACE blend2d:: 1006 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/blend2d") 1007 1008 configure_package_config_file("${CMAKE_CURRENT_LIST_DIR}/blend2d-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/blend2d-config.cmake" 1009 INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/blend2d" 1010 NO_SET_AND_CHECK_MACRO 1011 NO_CHECK_REQUIRED_COMPONENTS_MACRO) 1012 1013 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/blend2d-config.cmake" 1014 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/blend2d") 1015 1016 foreach(src_file ${BLEND2D_SRC_LIST}) 1017 if ("${src_file}" MATCHES "\\.h$" AND NOT "${src_file}" MATCHES "_p\\.h$") 1018 get_filename_component(_src_dir ${src_file} PATH) 1019 install(FILES "${CMAKE_CURRENT_LIST_DIR}/src/${src_file}" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_src_dir}") 1020 endif() 1021 endforeach() 1022 else() 1023 message(STATUS "[blend2d] Disabling install support ('BLEND2D_NO_INSTALL=${BLEND2D_NO_INSTALL}')") 1024 endif() 1025 1026 # Blend2D - Targets - Tests 1027 # ========================= 1028 1029 if (BLEND2D_TEST) 1030 enable_testing() 1031 message(STATUS "[blend2d] Enabling Blend2D tests ('BLEND2D_TEST=${BLEND2D_TEST}')") 1032 1033 # Blend2D Tests 1034 # ------------- 1035 1036 # bl_test_runner - optimize static builds (no need to build Blend2D twice). 1037 if (BLEND2D_STATIC) 1038 blend2d_add_target(bl_test_runner TEST 1039 SOURCES ${BLEND2D_TEST_SRC_FILES} 1040 testing/tests/bl_test_runner.cpp 1041 testing/tests/broken.cpp 1042 testing/tests/broken.h 1043 LIBRARIES blend2d::blend2d 1044 CFLAGS ${BLEND2D_PRIVATE_CFLAGS} -DBL_TEST -DBL_STATIC 1045 CFLAGS_DBG ${BLEND2D_PRIVATE_CFLAGS_DBG} 1046 CFLAGS_REL ${BLEND2D_PRIVATE_CFLAGS_REL} 1047 INCLUDE_DIRS ${ASMJIT_INCLUDE_DIRS}) 1048 else() 1049 blend2d_add_target(bl_test_runner TEST 1050 SOURCES ${BLEND2D_TEST_SRC_FILES} 1051 ${BLEND2D_ALL_SRC_FILES} 1052 testing/tests/bl_test_runner.cpp 1053 testing/tests/broken.cpp 1054 testing/tests/broken.h 1055 LIBRARIES ${BLEND2D_DEPS} 1056 CFLAGS ${BLEND2D_PRIVATE_CFLAGS} -DBL_TEST -DBL_STATIC 1057 CFLAGS_DBG ${BLEND2D_PRIVATE_CFLAGS_DBG} 1058 CFLAGS_REL ${BLEND2D_PRIVATE_CFLAGS_REL} 1059 INCLUDE_DIRS ${ASMJIT_INCLUDE_DIRS} ${BLEND2D_INCLUDE_DIRS}) 1060 endif() 1061 1062 # bl_test_context_xxx are all based on the same base-app. 1063 foreach(app bl_test_context_simple bl_test_context_mt bl_test_context_jit) 1064 blend2d_add_target(${app} TEST 1065 SOURCES testing/tests/${app}.cpp 1066 testing/tests/bl_test_context_baseapp.cpp 1067 testing/tests/bl_test_context_baseapp.h 1068 testing/tests/bl_test_context_utilities.h 1069 LIBRARIES blend2d::blend2d 1070 CFLAGS ${BLEND2D_PRIVATE_CFLAGS} 1071 CFLAGS_DBG ${BLEND2D_PRIVATE_CFLAGS_DBG} 1072 CFLAGS_REL ${BLEND2D_PRIVATE_CFLAGS_REL}) 1073 endforeach() 1074 1075 blend2d_add_target(bl_test_image_io EXECUTABLE 1076 SOURCES testing/tests/bl_test_image_io.cpp 1077 LIBRARIES blend2d::blend2d 1078 CFLAGS ${BLEND2D_PRIVATE_CFLAGS} 1079 CFLAGS_DBG ${BLEND2D_PRIVATE_CFLAGS_DBG} 1080 CFLAGS_REL ${BLEND2D_PRIVATE_CFLAGS_REL}) 1081 1082 # Add a limited version of 'bl_bench' in case we are building tests, but not demos. 1083 if (NOT BLEND2D_DEMOS) 1084 blend2d_add_target(bl_bench EXECUTABLE 1085 SOURCES ${BLEND2D_BENCH_SRC} 1086 LIBRARIES blend2d::blend2d 1087 CFLAGS ${BLEND2D_PRIVATE_CFLAGS} 1088 CFLAGS_DBG ${BLEND2D_PRIVATE_CFLAGS_DBG} 1089 CFLAGS_REL ${BLEND2D_PRIVATE_CFLAGS_REL}) 1090 endif() 1091 1092 # Blend2D C & C++ Samples 1093 # ----------------------- 1094 1095 foreach(app bl_sample_1 bl_sample_2 bl_sample_3 bl_sample_4 bl_sample_5 bl_sample_6 bl_sample_7 bl_sample_8) 1096 blend2d_add_target(${app} EXECUTABLE 1097 SOURCES testing/samples/${app}.cpp 1098 LIBRARIES blend2d::blend2d 1099 CFLAGS ${BLEND2D_WARNING_CFLAGS}) 1100 endforeach() 1101 1102 foreach(app bl_sample_capi) 1103 blend2d_add_target(${app} EXECUTABLE 1104 SOURCES testing/samples/${app}.c 1105 LIBRARIES blend2d::blend2d 1106 CFLAGS ${BLEND2D_WARNING_CFLAGS}) 1107 1108 # Sanitizers usually require a C++ linker and library support. 1109 if (BLEND2D_SANITIZE_CFLAGS) 1110 set_target_properties(${app} PROPERTIES LINKER_LANGUAGE CXX) 1111 endif() 1112 endforeach() 1113 1114 # Blend2D Generator 1115 # ----------------- 1116 1117 blend2d_add_target(bl_generator EXECUTABLE 1118 SOURCES testing/generator/bl_generator.cpp 1119 testing/generator/bl_generator.h 1120 CFLAGS ${BLEND2D_WARNING_CFLAGS}) 1121 if (NOT WIN32) 1122 target_link_libraries(bl_generator "pthread") 1123 endif() 1124 1125 # TODO: Not sure this is the best way of copying resources. 1126 foreach(resource ABeeZee-Regular.ttf Leaves.jpeg) 1127 if (NOT CMAKE_BUILD_TYPE) 1128 add_custom_command(TARGET blend2d POST_BUILD 1129 COMMAND "${CMAKE_COMMAND}" -E copy 1130 "${CMAKE_CURRENT_SOURCE_DIR}/testing/resources/${resource}" 1131 "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>/${resource}" 1132 COMMENT "Resources") 1133 else() 1134 add_custom_command(TARGET blend2d POST_BUILD 1135 COMMAND "${CMAKE_COMMAND}" -E copy 1136 "${CMAKE_CURRENT_SOURCE_DIR}/testing/resources/${resource}" 1137 "${CMAKE_CURRENT_BINARY_DIR}/${resource}" 1138 COMMENT "Resources") 1139 endif() 1140 endforeach() 1141 else() 1142 message(STATUS "[blend2d] Disabling Blend2D tests ('BLEND2D_TEST=OFF')") 1143 endif() 1144 1145 # Blend2D - Targets - Demos + Benchmarking 1146 # ======================================== 1147 1148 if (BLEND2D_DEMOS) 1149 include(FindPkgConfig) 1150 message(STATUS "[blend2d] Enabling Blend2D demos ('BLEND2D_DEMOS=${BLEND2D_DEMOS}')") 1151 1152 set(BLEND2D_BENCH_SRCS "") 1153 set(BLEND2D_BENCH_LIBS "") 1154 set(BLEND2D_BENCH_CFLAGS "") 1155 set(BLEND2D_BENCH_INCLUDE_DIRS "") 1156 set(BLEND2D_BENCH_LIBRARY_DIRS "") 1157 1158 # Demos - Probe Dependencies 1159 find_package(Qt6 COMPONENTS Core Gui Widgets) 1160 if(Qt6Gui_FOUND) 1161 message(STATUS "[blend2d] Qt6 found - adding support for Qt6 (benchmarking + demo apps)") 1162 1163 list(APPEND BLEND2D_BENCH_CFLAGS -DBL_BENCH_ENABLE_QT) 1164 list(APPEND BLEND2D_BENCH_LIBS Qt6::Gui Qt6::Widgets) 1165 else() 1166 message(STATUS "[blend2d] Qt6 not found - cannot build Qt6 benchmark backend and demo apps") 1167 endif() 1168 1169 pkg_check_modules(CAIRO cairo) 1170 if(CAIRO_FOUND) 1171 message(STATUS "[blend2d] Cairo found - adding support for cairo (benchmarking)") 1172 1173 list(APPEND BLEND2D_BENCH_CFLAGS -DBL_BENCH_ENABLE_CAIRO) 1174 list(APPEND BLEND2D_BENCH_LIBS ${CAIRO_LIBRARIES}) 1175 list(APPEND BLEND2D_BENCH_LIBRARY_DIRS ${CAIRO_LIBRARY_DIRS}) 1176 list(APPEND BLEND2D_BENCH_INCLUDE_DIRS ${CAIRO_INCLUDE_DIRS}) 1177 else() 1178 message(STATUS "[blend2d] Cairo not found - cannot build cairo benchmark backend") 1179 endif() 1180 1181 find_package(unofficial-skia CONFIG) 1182 if(TARGET unofficial::skia::skia) 1183 message(STATUS "[blend2d] Skia found - adding support for SKIA (benchmarking)") 1184 1185 list(APPEND BLEND2D_BENCH_CFLAGS -DBL_BENCH_ENABLE_SKIA) 1186 list(APPEND BLEND2D_BENCH_LIBS unofficial::skia::skia) 1187 else() 1188 message(STATUS "[blend2d] Skia not found - cannot build Skia benchmark backend") 1189 endif() 1190 1191 if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/3rdparty/agg/include/agg_curves.h") 1192 message(STATUS "[blend2d] AGG found (./3rdparty/agg) - adding support for AGG (benchmarking)") 1193 1194 file(GLOB_RECURSE 1195 BLEND2D_BENCH_SRCS 1196 LIST_DIRECTORIES FALSE 1197 RELATIVE "${CMAKE_CURRENT_LIST_DIR}" 1198 CONFIGURE_DEPENDS 1199 "3rdparty/agg/*.h" "3rdparty/agg/*.cpp") 1200 list(APPEND BLEND2D_BENCH_CFLAGS -DBL_BENCH_ENABLE_AGG) 1201 list(APPEND BLEND2D_BENCH_INCLUDE_DIRS 3rdparty/agg/include) 1202 else() 1203 message(STATUS "[blend2d] AGG not found (./3rdparty/agg) - cannot build AGG benchmark backend") 1204 endif() 1205 1206 if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/3rdparty/JUCE/CMakeLists.txt") 1207 message(STATUS "[blend2d] JUCE found (./3rdparty/JUCE) - adding support for JUCE (benchmarking)") 1208 1209 add_definitions(-DJUCE_USE_CURL=0 -DUSE_COREGRAPHICS_RENDERING=0) 1210 add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/3rdparty/JUCE" JUCE) 1211 1212 list(APPEND BLEND2D_BENCH_CFLAGS -DBL_BENCH_ENABLE_JUCE) 1213 list(APPEND BLEND2D_BENCH_LIBS juce::juce_core juce::juce_events juce::juce_graphics) 1214 else() 1215 message(STATUS "[blend2d] JUCE not found (./3rdparty/JUCE) - cannot build JUCE benchmark backend") 1216 endif() 1217 1218 if (APPLE) 1219 message(STATUS "[blend2d] CoreGraphics (system) - adding support for CoreGraphics (benchmarking)") 1220 1221 list(APPEND BLEND2D_BENCH_CFLAGS -DBL_BENCH_ENABLE_COREGRAPHICS) 1222 list(APPEND BLEND2D_BENCH_LIBS "-framework CoreGraphics") 1223 endif() 1224 1225 if(Qt6Gui_FOUND) 1226 message(STATUS "[blend2d] Adding demos that use Qt framework") 1227 1228 foreach(app bl_demo_bounces 1229 bl_demo_bubbles 1230 bl_demo_circles 1231 bl_demo_elliptic_arc 1232 bl_demo_gradients 1233 bl_demo_image_view 1234 bl_demo_particles 1235 bl_demo_paths 1236 bl_demo_pattern 1237 bl_demo_rects 1238 bl_demo_sprites 1239 bl_demo_stroke 1240 bl_demo_text 1241 bl_demo_tiger) 1242 blend2d_add_target(${app} EXECUTABLE_WIN32 1243 SOURCES 1244 testing/demos/${app}.cpp 1245 testing/demos/bl_qt_canvas.cpp 1246 testing/demos/bl_qt_canvas.h 1247 testing/demos/bl_qt_headers.h 1248 LIBRARIES 1249 blend2d::blend2d Qt6::Gui Qt6::Widgets) 1250 set_property(TARGET ${app} PROPERTY AUTOMOC TRUE) 1251 endforeach() 1252 endif() 1253 1254 blend2d_add_target(bl_bench EXECUTABLE 1255 SOURCES ${BLEND2D_BENCH_SRC} ${BLEND2D_BENCH_SRCS} 1256 LIBRARIES blend2d::blend2d ${BLEND2D_BENCH_LIBS} 1257 CFLAGS ${BLEND2D_BENCH_CFLAGS} 1258 INCLUDE_DIRS ${BLEND2D_BENCH_INCLUDE_DIRS}) 1259 target_link_directories(bl_bench PRIVATE ${BLEND2D_BENCH_LIBRARY_DIRS}) 1260 else() 1261 message(STATUS "[blend2d] Disabling Blend2D demos ('BLEND2D_DEMOS=OFF')") 1262 endif()