odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

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()