CMakeLists.txt raw

   1  #
   2  # Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
   3  # Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
   4  # Copyright (c) 1998 by Fergus Henderson.  All rights reserved.
   5  # Copyright (c) 2000-2010 by Hewlett-Packard Company.  All rights reserved.
   6  # Copyright (c) 2010-2022 Ivan Maidanski
   7  ##
   8  # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
   9  # OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  10  ##
  11  # Permission is hereby granted to use or copy this program
  12  # for any purpose, provided the above notices are retained on all copies.
  13  # Permission to modify the code and to distribute modified code is granted,
  14  # provided the above notices are retained, and a notice that the code was
  15  # modified is included with the above copyright notice.
  16  ##
  17  
  18  cmake_minimum_required(VERSION 3.10)
  19  
  20  set(PACKAGE_VERSION 8.3.0)
  21  # Version must match that in `AC_INIT` of `configure.ac` file and in README.
  22  # Version must conform to: [0-9]+[.][0-9]+[.][0-9]+
  23  
  24  # Info (`current:revision:age`) for the Libtool versioning system.
  25  # These values should match those in `cord/cord.am` and `Makefile.am` files.
  26  set(LIBCORD_VER_INFO    6:1:5)
  27  set(LIBGC_VER_INFO      6:3:5)
  28  set(LIBGCCPP_VER_INFO   6:0:5)
  29  
  30  option(enable_cplusplus "C++ support" OFF)
  31  if (enable_cplusplus)
  32    project(gc)
  33  else()
  34    project(gc C)
  35  endif()
  36  
  37  if (POLICY CMP0057)
  38    # Required for `CheckLinkerFlag`, at least.
  39    cmake_policy(SET CMP0057 NEW)
  40  endif()
  41  
  42  include(CheckCCompilerFlag)
  43  include(CheckCSourceCompiles)
  44  include(CheckFunctionExists)
  45  include(CheckIncludeFile)
  46  include(CheckSymbolExists)
  47  include(CMakePackageConfigHelpers)
  48  include(CTest)
  49  include(GNUInstallDirs)
  50  
  51  if (NOT (${CMAKE_VERSION} VERSION_LESS "3.18.0"))
  52    include(CheckLinkerFlag)
  53  endif()
  54  
  55  set(default_enable_threads ON)
  56  find_package(Threads QUIET)
  57  if (NOT (CMAKE_USE_PTHREADS_INIT OR CMAKE_USE_WIN32_THREADS_INIT) OR EMSCRIPTEN OR WASI)
  58    set(default_enable_threads OFF)
  59  endif()
  60  
  61  # Customize the build by passing "-D<option_name>=ON|OFF" in the command line.
  62  option(BUILD_SHARED_LIBS "Build shared libraries" ON)
  63  option(build_cord "Build cord library" ON)
  64  option(build_tests "Build tests" OFF)
  65  option(enable_docs "Build and install documentation" ON)
  66  option(enable_threads "Support threads" ${default_enable_threads})
  67  option(enable_parallel_mark "Parallelize marking and free list construction" ON)
  68  option(enable_thread_local_alloc "Turn on thread-local allocation optimization" ON)
  69  option(enable_threads_discovery "Enable threads discovery in GC" ON)
  70  option(enable_rwlock "Enable reader mode of the allocator lock" OFF)
  71  option(enable_throw_bad_alloc_library "Turn on C++ gctba library build" ON)
  72  option(enable_gcj_support "Support for gcj" ON)
  73  option(enable_sigrt_signals "Use SIGRTMIN-based signals for thread suspend/resume" OFF)
  74  option(enable_valgrind_tracking "Support tracking GC_malloc and friends for heap profiling tools" OFF)
  75  option(enable_gc_debug "Support for pointer back-tracing" OFF)
  76  option(disable_gc_debug "Disable debugging like GC_dump and its callees" OFF)
  77  option(enable_java_finalization "Support for java finalization" ON)
  78  option(enable_atomic_uncollectable "Support for atomic uncollectible allocation" ON)
  79  option(enable_redirect_malloc "Redirect malloc and friends to GC routines" OFF)
  80  option(enable_disclaim "Support alternative finalization interface" ON)
  81  option(enable_dynamic_pointer_mask "Support pointer mask/shift set at runtime" OFF)
  82  option(enable_large_config "Optimize for large heap or root set" OFF)
  83  option(enable_gc_assertions "Enable collector-internal assertion checking" OFF)
  84  option(enable_mmap "Use mmap instead of sbrk to expand the heap" OFF)
  85  option(enable_munmap "Return page to the OS if empty for N collections" ON)
  86  option(enable_dynamic_loading "Enable tracing of dynamic library data roots" ON)
  87  option(enable_register_main_static_data "Perform the initial guess of data root sets" ON)
  88  option(enable_checksums "Report erroneously cleared dirty bits" OFF)
  89  option(enable_werror "Pass -Werror to the C compiler (treat warnings as errors)" OFF)
  90  option(enable_single_obj_compilation "Compile all libgc source files into single .o" OFF)
  91  option(disable_single_obj_compilation "Compile each libgc source file independently" OFF)
  92  option(enable_handle_fork "Attempt to ensure a usable collector after fork()" ON)
  93  option(disable_handle_fork "Prohibit installation of pthread_atfork() handlers" OFF)
  94  option(enable_emscripten_asyncify "Use Emscripten asyncify feature" OFF)
  95  option(install_headers "Install header and pkg-config metadata files" ON)
  96  option(with_libatomic_ops "Use an external libatomic_ops" OFF)
  97  option(without_libatomic_ops "Use atomic_ops.h in libatomic_ops/src" OFF)
  98  
  99  # Override the default build type to `RelWithDebInfo` (this instructs `cmake`
 100  # to pass `-O2 -g -DNDEBUG` options to the compiler by default).
 101  if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
 102    set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE
 103        STRING "Choose the type of build." FORCE)
 104    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
 105                 STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel")
 106  endif()
 107  
 108  # Convert `VER_INFO` values to `VERSION`, `SOVERSION` ones.
 109  if (BUILD_SHARED_LIBS)
 110    # `cord`:
 111    string(REGEX REPLACE "(.+):.+:.+"  "\\1" cord_cur ${LIBCORD_VER_INFO})
 112    string(REGEX REPLACE ".+:(.+):.+"  "\\1" cord_rev ${LIBCORD_VER_INFO})
 113    string(REGEX REPLACE ".+:.+:(.+)$" "\\1" cord_age ${LIBCORD_VER_INFO})
 114    math(EXPR CORD_SOVERSION "${cord_cur} - ${cord_age}")
 115    set(CORD_VERSION_PROP "${CORD_SOVERSION}.${cord_age}.${cord_rev}")
 116    message(STATUS "CORD_VERSION_PROP = ${CORD_VERSION_PROP}")
 117    # `gc`:
 118    string(REGEX REPLACE "(.+):.+:.+"  "\\1" gc_cur ${LIBGC_VER_INFO})
 119    string(REGEX REPLACE ".+:(.+):.+"  "\\1" gc_rev ${LIBGC_VER_INFO})
 120    string(REGEX REPLACE ".+:.+:(.+)$" "\\1" gc_age ${LIBGC_VER_INFO})
 121    math(EXPR GC_SOVERSION "${gc_cur} - ${gc_age}")
 122    set(GC_VERSION_PROP "${GC_SOVERSION}.${gc_age}.${gc_rev}")
 123    message(STATUS "GC_VERSION_PROP = ${GC_VERSION_PROP}")
 124    # `gccpp` and `gctba`:
 125    string(REGEX REPLACE "(.+):.+:.+"  "\\1" gccpp_cur ${LIBGCCPP_VER_INFO})
 126    string(REGEX REPLACE ".+:(.+):.+"  "\\1" gccpp_rev ${LIBGCCPP_VER_INFO})
 127    string(REGEX REPLACE ".+:.+:(.+)$" "\\1" gccpp_age ${LIBGCCPP_VER_INFO})
 128    math(EXPR GCCPP_SOVERSION "${gccpp_cur} - ${gccpp_age}")
 129    set(GCCPP_VERSION_PROP "${GCCPP_SOVERSION}.${gccpp_age}.${gccpp_rev}")
 130    message(STATUS "GCCPP_VERSION_PROP = ${GCCPP_VERSION_PROP}")
 131  endif(BUILD_SHARED_LIBS)
 132  
 133  add_definitions("-DALL_INTERIOR_POINTERS")
 134  add_definitions("-DNO_EXECUTE_PERMISSION")
 135  
 136  # Set struct packing alignment to word (instead of 1-byte).
 137  if (BORLAND)
 138    add_compile_options(/a4)
 139  elseif (WATCOM)
 140    add_compile_options(/zp4)
 141  endif()
 142  
 143  # Output all warnings.
 144  if (BORLAND)
 145    # All warnings except for particular ones.
 146    add_compile_options(/w /w-aus /w-ccc /w-inl /w-pro /w-rch /w-use)
 147  elseif (MSVC)
 148    # All warnings but ignoring "conditional expression is constant" one.
 149    add_compile_options(/W4 /wd4127)
 150  elseif (WATCOM)
 151    add_compile_options(/wx)
 152    if (enable_gc_assertions)
 153      # Suppress "unreachable code" warning in `GC_ASSERT()` if some constant
 154      # nonzero expression is given as the argument.
 155      add_compile_options(/wcd=201)
 156    endif()
 157    if (enable_threads)
 158      # Suppress "missing return value" wcc warning for `AO_test_and_set_full()`
 159      # and `AO_char_fetch_and_add_full()` in AO `msftc/x86.h` file.
 160      add_compile_options($<$<COMPILE_LANGUAGE:C>:/wcd=107>)
 161    endif(enable_threads)
 162  else()
 163    add_compile_options(-Wall)
 164    add_compile_options(-Wextra)
 165    # TODO: add `-[W]pedantic -Wno-long-long`
 166  endif()
 167  
 168  if (WIN32)
 169    # Disable MS crt security warnings reported e.g. for `getenv`, `strcpy`.
 170    add_definitions("-D_CRT_SECURE_NO_DEPRECATE")
 171  endif()
 172  
 173  include_directories(include)
 174  
 175  set(SRC allchblk.c alloc.c blacklst.c dbg_mlc.c dyn_load.c finalize.c
 176          headers.c mach_dep.c malloc.c mallocx.c mark.c mark_rts.c misc.c
 177          new_hblk.c os_dep.c ptr_chck.c reclaim.c typd_mlc.c)
 178  
 179  set(NODIST_SRC)
 180  set(ATOMIC_OPS_LIBS)
 181  set(ATOMIC_OPS_LIBS_CMAKE)
 182  set(THREADDLLIBS_LIST)
 183  set(NEED_LIB_RT)
 184  
 185  set(_HOST ${CMAKE_SYSTEM_PROCESSOR}-unknown-${CMAKE_SYSTEM})
 186  string(TOLOWER ${_HOST} HOST)
 187  message(STATUS "TARGET = ${HOST}")
 188  
 189  if (enable_threads)
 190    find_package(Threads REQUIRED)
 191    message(STATUS "Thread library: ${CMAKE_THREAD_LIBS_INIT}")
 192    include_directories(${Threads_INCLUDE_DIR})
 193    if (with_libatomic_ops)
 194      if (without_libatomic_ops)
 195        message(FATAL_ERROR
 196          "with_libatomic_ops and without_libatomic_ops are mutually exclusive")
 197      endif()
 198      set(ATOMIC_OPS_LIBS "-latomic_ops")
 199      find_package(Atomic_ops CONFIG)
 200      if (Atomic_ops_FOUND)
 201        get_target_property(AO_INCLUDE_DIRS Atomic_ops::atomic_ops
 202                            INTERFACE_INCLUDE_DIRECTORIES)
 203        include_directories(${AO_INCLUDE_DIRS})
 204        message(STATUS "AO_INCLUDE_DIRS = ${AO_INCLUDE_DIRS}")
 205        set(ATOMIC_OPS_LIBS_CMAKE Atomic_ops::atomic_ops)
 206      else()
 207        set(ATOMIC_OPS_LIBS_CMAKE ${ATOMIC_OPS_LIBS})
 208      endif()
 209    elseif (without_libatomic_ops)
 210      include_directories(libatomic_ops/src)
 211      # In the tests we use the source files directly from `libatomic_ops`
 212      # subtree.
 213      set(NODIST_SRC libatomic_ops/src/atomic_ops.c)
 214      if (CMAKE_C_COMPILER_ID STREQUAL "SunPro")
 215        # SunCC compiler on SunOS (Solaris).
 216        enable_language(ASM)
 217        set(NODIST_SRC ${NODIST_SRC} libatomic_ops/src/atomic_ops_sysdeps.S)
 218      endif()
 219    elseif (BORLAND OR MSVC OR WATCOM)
 220      include_directories(libatomic_ops/src)
 221      # Note: alternatively, use `CFLAGS_EXTRA` to
 222      # pass `-I<...>/libatomic_ops/src`.
 223    else()
 224      # Assume the compiler supports GCC atomic intrinsics.
 225      add_definitions("-DGC_BUILTIN_ATOMIC")
 226    endif()
 227    set(THREADDLLIBS_LIST ${CMAKE_THREAD_LIBS_INIT})
 228    if (${CMAKE_DL_LIBS} MATCHES ^[^-].*)
 229      # Some `cmake` versions have a broken nonempty `CMAKE_DL_LIBS`
 230      # omitting "-l".  Assume `CMAKE_DL_LIBS` contains just one library.
 231      set(THREADDLLIBS_LIST ${THREADDLLIBS_LIST} -l${CMAKE_DL_LIBS})
 232    else()
 233      set(THREADDLLIBS_LIST ${THREADDLLIBS_LIST} ${CMAKE_DL_LIBS})
 234    endif()
 235    # Thread support detection.
 236    if (CMAKE_USE_PTHREADS_INIT)
 237      set(SRC ${SRC} gc_dlopen.c pthread_start.c pthread_support.c)
 238      if (CYGWIN OR WIN32)
 239        set(SRC ${SRC} win32_threads.c)
 240      else()
 241        if (APPLE)
 242          set(SRC ${SRC} darwin_stop_world.c)
 243        else()
 244          set(SRC ${SRC} pthread_stop_world.c)
 245        endif()
 246      endif()
 247      if (HOST MATCHES .*-.*-hpux10.*)
 248        message(FATAL_ERROR "HP/UX 10 POSIX threads are not supported.")
 249      endif()
 250      # Common defines for POSIX platforms.
 251      add_definitions("-DGC_THREADS")
 252      add_definitions("-D_REENTRANT")
 253      if (enable_parallel_mark)
 254        add_definitions("-DPARALLEL_MARK")
 255      endif()
 256      if (enable_thread_local_alloc)
 257        add_definitions("-DTHREAD_LOCAL_ALLOC")
 258        set(SRC ${SRC} specific.c thread_local_alloc.c)
 259      endif()
 260      message("Explicit GC_INIT() calls may be required.")
 261      if (HOST MATCHES .*-.*-hpux11.*)
 262        message("Only HP/UX 11 POSIX threads are supported.")
 263        add_definitions("-D_POSIX_C_SOURCE=199506L")
 264        set(NEED_LIB_RT ON)
 265      elseif (HOST MATCHES .*-.*-netbsd.*)
 266        add_definitions("-D_PTHREADS")
 267        set(NEED_LIB_RT ON)
 268      elseif (CMAKE_C_COMPILER_ID STREQUAL "SunPro")
 269        set(NEED_LIB_RT ON)
 270      endif()
 271      if (WIN32) # AND NOT CYGWIN
 272        # Does not provide process `fork` functionality.
 273      elseif (enable_handle_fork AND NOT disable_handle_fork)
 274        add_definitions("-DHANDLE_FORK")
 275      endif()
 276      if (enable_sigrt_signals)
 277        add_definitions("-DGC_USESIGRT_SIGNALS")
 278      endif()
 279    elseif (CMAKE_USE_WIN32_THREADS_INIT)
 280      add_definitions("-DGC_THREADS")
 281      if (enable_parallel_mark)
 282        add_definitions("-DPARALLEL_MARK")
 283      endif()
 284      if (enable_thread_local_alloc AND (enable_parallel_mark OR NOT BUILD_SHARED_LIBS))
 285        # Imply `THREAD_LOCAL_ALLOC` unless `GC_DLL`.
 286        add_definitions("-DTHREAD_LOCAL_ALLOC")
 287        set(SRC ${SRC} thread_local_alloc.c)
 288      endif()
 289      add_definitions("-DEMPTY_GETENV_RESULTS")
 290      # Add `pthread_start.c` file just in case client defines
 291      # `GC_WIN32_PTHREADS` macro.
 292      set(SRC ${SRC} pthread_start.c)
 293      set(SRC ${SRC} pthread_support.c win32_threads.c)
 294    elseif (CMAKE_HP_PTHREADS_INIT OR CMAKE_USE_SPROC_INIT)
 295      message(FATAL_ERROR "Unsupported thread package")
 296    endif()
 297    if (BORLAND)
 298      # Workaround "cannot locate assembly file" and "out of hash space"
 299      # compilation errors, "restarting compile using assembly" warning.
 300      add_definitions("-DAO_NO_ASM_XADD")
 301      add_definitions("-DAO_NO_ASM_XCHG")
 302    endif()
 303  endif(enable_threads)
 304  
 305  # Check whether `-lrt` linker option is needed to use `clock_gettime`.
 306  if (NOT NEED_LIB_RT)
 307    check_function_exists(clock_gettime HAVE_CLOCK_GETTIME_DIRECTLY)
 308    if (NOT HAVE_CLOCK_GETTIME_DIRECTLY)
 309      # Use of `clock_gettime` probably requires linking with `rt` library.
 310      set(NEED_LIB_RT ON)
 311    endif()
 312  endif()
 313  
 314  # Locate and use `rt` library if needed (and the library is available).
 315  if (NEED_LIB_RT)
 316    find_library(LIBRT rt)
 317    if (LIBRT)
 318      set(THREADDLLIBS_LIST ${THREADDLLIBS_LIST} ${LIBRT})
 319    endif()
 320  endif(NEED_LIB_RT)
 321  
 322  if (disable_handle_fork)
 323    add_definitions("-DNO_HANDLE_FORK")
 324  endif()
 325  
 326  if (enable_gcj_support)
 327    add_definitions("-DGC_GCJ_SUPPORT")
 328    if (enable_threads AND NOT (enable_thread_local_alloc AND HOST MATCHES .*-.*-kfreebsd.*-gnu))
 329      # FIXME: For a reason, `gctest` hangs up on kFreeBSD if both of
 330      # `THREAD_LOCAL_ALLOC` and `GC_ENABLE_SUSPEND_THREAD` are defined.
 331      add_definitions("-DGC_ENABLE_SUSPEND_THREAD")
 332    endif()
 333    set(SRC ${SRC} gcj_mlc.c)
 334  endif(enable_gcj_support)
 335  
 336  if (enable_disclaim)
 337    add_definitions("-DENABLE_DISCLAIM")
 338    set(SRC ${SRC} fnlz_mlc.c)
 339  endif()
 340  
 341  if (enable_dynamic_pointer_mask)
 342    add_definitions("-DDYNAMIC_POINTER_MASK")
 343  endif()
 344  
 345  if (enable_java_finalization)
 346    add_definitions("-DJAVA_FINALIZATION")
 347  endif()
 348  
 349  if (enable_atomic_uncollectable)
 350    add_definitions("-DGC_ATOMIC_UNCOLLECTABLE")
 351  endif()
 352  
 353  if (enable_valgrind_tracking)
 354    add_definitions("-DVALGRIND_TRACKING")
 355  endif()
 356  
 357  if (enable_gc_debug)
 358    add_definitions("-DDBG_HDRS_ALL")
 359    add_definitions("-DKEEP_BACK_PTRS")
 360    if (HOST MATCHES i.86-.*-dgux.*|.*-.*-.*linux.*)
 361      add_definitions("-DMAKE_BACK_GRAPH")
 362      if (HOST MATCHES .*-.*-.*linux.* AND NOT (HOST MATCHES e2k-.*-linux.*))
 363        add_definitions("-DSAVE_CALL_COUNT=8")
 364      endif()
 365      set(SRC ${SRC} backgraph.c)
 366    endif()
 367  endif(enable_gc_debug)
 368  
 369  if (disable_gc_debug)
 370    add_definitions("-DNO_DEBUGGING")
 371  elseif (WINCE)
 372    # Read environment variables from `<program>.gc.env` file.
 373    add_definitions("-DGC_READ_ENV_FILE")
 374  endif()
 375  
 376  if (enable_redirect_malloc)
 377    if (enable_gc_debug)
 378      add_definitions("-DREDIRECT_MALLOC=GC_debug_malloc_replacement")
 379      add_definitions("-DREDIRECT_REALLOC=GC_debug_realloc_replacement")
 380      add_definitions("-DREDIRECT_FREE=GC_debug_free")
 381    else()
 382      add_definitions("-DREDIRECT_MALLOC=GC_malloc")
 383    endif()
 384    if (WIN32)
 385      add_definitions("-DREDIRECT_MALLOC_IN_HEADER")
 386    else()
 387      add_definitions("-DGC_USE_DLOPEN_WRAP")
 388    endif()
 389  endif(enable_redirect_malloc)
 390  
 391  if (enable_mmap OR enable_munmap)
 392    add_definitions("-DUSE_MMAP")
 393    if (enable_munmap)
 394      add_definitions("-DUSE_MUNMAP")
 395    endif(enable_munmap)
 396  endif()
 397  
 398  if (NOT enable_dynamic_loading)
 399    add_definitions("-DIGNORE_DYNAMIC_LOADING")
 400  endif()
 401  
 402  if (NOT enable_register_main_static_data)
 403    add_definitions("-DGC_DONT_REGISTER_MAIN_STATIC_DATA")
 404  endif()
 405  
 406  if (enable_large_config)
 407    add_definitions("-DLARGE_CONFIG")
 408  endif()
 409  
 410  if (enable_gc_assertions)
 411    add_definitions("-DGC_ASSERTIONS")
 412    # TODO: pass `-Wno-missing-prototypes` (if supported) to turn off the clang
 413    # warning for `STATIC` functions.
 414  endif()
 415  
 416  if (NOT enable_threads_discovery)
 417    add_definitions("-DGC_NO_THREADS_DISCOVERY")
 418  endif()
 419  
 420  if (enable_rwlock)
 421    # Use `rwlock` for the allocator lock instead of mutex.
 422    add_definitions("-DUSE_RWLOCK")
 423  endif()
 424  
 425  if (enable_checksums)
 426    if (enable_munmap OR enable_threads)
 427      message(FATAL_ERROR "CHECKSUMS not compatible with USE_MUNMAP or threads")
 428    endif()
 429    add_definitions("-DCHECKSUMS")
 430    set(SRC ${SRC} checksums.c)
 431  endif(enable_checksums)
 432  
 433  if (enable_werror)
 434    if (BORLAND)
 435      add_compile_options(/w!)
 436    elseif (MSVC)
 437      add_compile_options(/WX)
 438      # Workaround "typedef ignored on left of ..." warning reported in
 439      # `imagehlp.h` file of e.g. Windows Kit 8.1.
 440      add_compile_options(/wd4091)
 441    elseif (WATCOM)
 442      add_compile_options(/we)
 443    else()
 444      add_compile_options(-Werror)
 445    endif()
 446  endif(enable_werror)
 447  
 448  if (enable_single_obj_compilation OR (BUILD_SHARED_LIBS AND NOT disable_single_obj_compilation))
 449    set(SRC extra/gc.c) # override `SRC`
 450    if (enable_threads AND CMAKE_USE_PTHREADS_INIT AND NOT (APPLE OR CYGWIN OR WIN32))
 451      add_definitions("-DGC_PTHREAD_START_STANDALONE")
 452      set(SRC ${SRC} pthread_start.c)
 453    endif()
 454  endif()
 455  
 456  # Add implementation of `backtrace` and `backtrace_symbols`.
 457  if (MSVC)
 458    set(SRC ${SRC} extra/msvc_dbg.c)
 459  endif()
 460  
 461  # Declare that the libraries do not refer to external symbols.
 462  if (BUILD_SHARED_LIBS AND NOT (APPLE OR ${CMAKE_SYSTEM_NAME} MATCHES "BSD"))
 463    # Note: performed before `CMAKE_REQUIRED_FLAGS` is updated with "-c".
 464    if (${CMAKE_VERSION} VERSION_LESS "3.18.0")
 465      set(WL_NO_UNDEFINED_OPT "-Wl,--no-undefined")
 466      check_c_compiler_flag(${WL_NO_UNDEFINED_OPT} HAVE_FLAG_WL_NO_UNDEFINED)
 467    else()
 468      set(WL_NO_UNDEFINED_OPT "LINKER:--no-undefined")
 469      check_linker_flag(C "${WL_NO_UNDEFINED_OPT}" HAVE_FLAG_WL_NO_UNDEFINED)
 470    endif()
 471  endif()
 472  
 473  # Instruct `check_c_source_compiles` to skip linking.
 474  # Alternatively, we could set `CMAKE_REQUIRED_LIBRARIES` properly.
 475  SET(CMAKE_REQUIRED_FLAGS "-c")
 476  
 477  if (NOT (BORLAND OR MSVC OR WATCOM))
 478    # Instruct `check_c_source_compiles` and similar `cmake` checks not to
 479    # ignore compiler warnings (like "implicit declaration of function").
 480    check_c_compiler_flag(-Werror HAVE_FLAG_WERROR)
 481    if (HAVE_FLAG_WERROR)
 482      check_c_compiler_flag(-Wno-unused-command-line-argument
 483                            HAVE_FLAG_WNO_UNUSED_CMDLINE_ARG)
 484      SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
 485      # Prevent "linker input unused" error in further `check_c_compiler_flag`.
 486      if (HAVE_FLAG_WNO_UNUSED_CMDLINE_ARG)
 487        SET(CMAKE_REQUIRED_FLAGS
 488            "${CMAKE_REQUIRED_FLAGS} -Wno-unused-command-line-argument")
 489      endif()
 490    endif(HAVE_FLAG_WERROR)
 491    # Prevent "__builtin_return_address with nonzero argument is unsafe" warning.
 492    check_c_compiler_flag(-Wno-frame-address HAVE_FLAG_WNO_FRAME_ADDRESS)
 493    if (HAVE_FLAG_WNO_FRAME_ADDRESS)
 494      add_compile_options(-Wno-frame-address)
 495    endif(HAVE_FLAG_WNO_FRAME_ADDRESS)
 496  endif()
 497  
 498  if (BUILD_SHARED_LIBS)
 499    add_definitions("-DGC_DLL")
 500    # Pass `-fvisibility=hidden` option if supported.
 501    check_c_compiler_flag(-fvisibility=hidden HAVE_FLAG_F_VISIBILITY_HIDDEN)
 502    if (HAVE_FLAG_F_VISIBILITY_HIDDEN)
 503      add_definitions("-DGC_VISIBILITY_HIDDEN_SET")
 504      add_compile_options(-fvisibility=hidden)
 505    else()
 506      add_definitions("-DGC_NO_VISIBILITY")
 507    endif()
 508  else()
 509    add_definitions("-DGC_NOT_DLL")
 510    if (WIN32)
 511      # Do not require the clients to link with `user32` system library.
 512      add_definitions("-DDONT_USE_USER32_DLL")
 513    endif(WIN32)
 514  endif()
 515  
 516  # Configuration of machine-dependent code.
 517  if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(sparc.*|SPARC.*)")
 518    # TODO: Handle NetBSD/SPARC (32-bit) specially.
 519    enable_language(ASM)
 520    set(SRC ${SRC} sparc_mach_dep.S)
 521  endif()
 522  
 523  # Extra user-defined flags to pass both to C and C++ compilers.
 524  if (DEFINED CFLAGS_EXTRA)
 525    separate_arguments(CFLAGS_EXTRA_LIST UNIX_COMMAND "${CFLAGS_EXTRA}")
 526    add_compile_options(${CFLAGS_EXTRA_LIST})
 527  endif()
 528  
 529  # Check whether platform `execinfo.h` file is present.
 530  check_include_file(execinfo.h HAVE_EXECINFO_H)
 531  if (NOT HAVE_EXECINFO_H)
 532    add_definitions("-DGC_MISSING_EXECINFO_H")
 533  endif()
 534  
 535  check_include_file(sys/types.h HAVE_SYS_TYPES_H)
 536  if (HAVE_SYS_TYPES_H)
 537    add_definitions("-DHAVE_SYS_TYPES_H")
 538  endif()
 539  
 540  if (NOT WIN32)
 541    check_include_file(unistd.h HAVE_UNISTD_H)
 542    if (HAVE_UNISTD_H)
 543      add_definitions("-DHAVE_UNISTD_H")
 544    endif()
 545  endif()
 546  
 547  # Check for `getcontext` (e.g., uClibc can be configured without it).
 548  if (NOT (BORLAND OR MSVC))
 549    check_function_exists(getcontext HAVE_GETCONTEXT)
 550    if (HAVE_GETCONTEXT AND NOT APPLE)
 551      # Double check `getcontext` is available (needed at least on OpenBSD 7.3).
 552      # Note: OS X is excluded here because the header filename differs.
 553      check_c_source_compiles("
 554  #include <ucontext.h>\n
 555  int main(void) { ucontext_t ctxt; (void)getcontext(&ctxt); return 0; }"
 556        HAVE_GETCONTEXT_FUNC)
 557      if (NOT HAVE_GETCONTEXT_FUNC)
 558        set(HAVE_GETCONTEXT OFF)
 559      endif()
 560    endif()
 561    if (NOT HAVE_GETCONTEXT)
 562      add_definitions("-DNO_GETCONTEXT")
 563    endif()
 564  endif()
 565  
 566  # Check whether `dl_iterate_phdr` exists (as a strong symbol).
 567  if (NOT (APPLE OR CYGWIN OR WIN32))
 568    check_function_exists(dl_iterate_phdr HAVE_DL_ITERATE_PHDR)
 569    if (HAVE_DL_ITERATE_PHDR)
 570      add_definitions("-DHAVE_DL_ITERATE_PHDR")
 571    endif(HAVE_DL_ITERATE_PHDR)
 572  endif()
 573  
 574  # Check for `pthread_sigmask` and `sigset_t`.
 575  if (enable_threads AND CMAKE_USE_PTHREADS_INIT)
 576    if (NOT (APPLE OR CYGWIN OR WIN32))
 577      check_c_source_compiles("
 578  #define _GNU_SOURCE 1\n
 579  #include <pthread.h>\n
 580  #include <signal.h>\n
 581  int main(void) { sigset_t t; (void)pthread_sigmask(SIG_BLOCK, 0, &t); return 0; }"
 582        HAVE_PTHREAD_SIGMASK)
 583      if (HAVE_PTHREAD_SIGMASK)
 584        # Define to use `pthread_sigmask` function if needed.
 585        add_definitions("-DGC_HAVE_PTHREAD_SIGMASK")
 586      endif(HAVE_PTHREAD_SIGMASK)
 587    endif()
 588  endif()
 589  
 590  check_symbol_exists(sigsetjmp setjmp.h HAVE_SIGSETJMP)
 591  if (NOT HAVE_SIGSETJMP)
 592    add_definitions("-DGC_NO_SIGSETJMP")
 593  endif()
 594  
 595  # Build with `GC_wcsdup` support if possible.
 596  check_symbol_exists(wcslen wchar.h HAVE_WCSLEN)
 597  if (HAVE_WCSLEN)
 598    add_definitions("-DGC_REQUIRE_WCSDUP")
 599  endif()
 600  
 601  # `pthread_setname_np`, if available, may have 1, 2 or 3 arguments.
 602  if (enable_threads AND CMAKE_USE_PTHREADS_INIT)
 603    check_c_source_compiles("
 604  #define _GNU_SOURCE 1\n
 605  #include <pthread.h>\n
 606  int main(void) { (void)pthread_setname_np(\"thread-name\"); return 0; }"
 607      HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID)
 608    if (HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID)
 609      # Define to use `pthread_setname_np(const char *)`.
 610      add_definitions("-DHAVE_PTHREAD_SETNAME_NP_WITHOUT_TID")
 611    else()
 612      check_c_source_compiles("
 613  #define _GNU_SOURCE 1\n
 614  #include <pthread.h>\n
 615  int main(void) {\n
 616    (void)pthread_setname_np(pthread_self(), \"thread-name-%u\", 0); return 0; }"
 617        HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG)
 618      if (HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG)
 619        # Define to use `pthread_setname_np(pthread_t, const char *, void *)`.
 620        add_definitions("-DHAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG")
 621      else()
 622        check_c_source_compiles("
 623  #define _GNU_SOURCE 1\n
 624  #include <pthread.h>\n
 625  int main(void) {\n
 626    (void)pthread_setname_np(pthread_self(), \"thread-name\"); return 0; }"
 627          HAVE_PTHREAD_SETNAME_NP_WITH_TID)
 628        if (HAVE_PTHREAD_SETNAME_NP_WITH_TID)
 629          # Define to use `pthread_setname_np(pthread_t, const char *)`.
 630          add_definitions("-DHAVE_PTHREAD_SETNAME_NP_WITH_TID")
 631        else()
 632          check_c_source_compiles("
 633  #include <pthread.h>\n
 634  #include <pthread_np.h>\n
 635  int main(void) {\n
 636    pthread_set_name_np(pthread_self(), \"thread-name\"); return 0; }"
 637            HAVE_PTHREAD_SET_NAME_NP)
 638          if (HAVE_PTHREAD_SET_NAME_NP)
 639            # Define to use `pthread_set_name_np(pthread_t, const char *)`.
 640            add_definitions("-DHAVE_PTHREAD_SET_NAME_NP")
 641          endif()
 642        endif(HAVE_PTHREAD_SETNAME_NP_WITH_TID)
 643      endif(HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG)
 644    endif(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID)
 645  endif()
 646  
 647  # Check for `dladdr` (used for debugging).
 648  check_c_source_compiles("
 649  #define _GNU_SOURCE 1\n
 650  #include <dlfcn.h>\n
 651  int main(void) { Dl_info info; (void)dladdr(\"\", &info); return 0; }"
 652    HAVE_DLADDR)
 653  if (HAVE_DLADDR)
 654    # Define to use `dladdr` function.
 655    add_definitions("-DHAVE_DLADDR")
 656  endif()
 657  
 658  # Check for `emscripten`; use `asyncify` feature if requested.
 659  check_c_source_compiles("
 660  #ifndef __EMSCRIPTEN__\n
 661  # error This is not Emscripten\n
 662  #endif\n
 663  int main(void) { return 0; }"
 664    EMSCRIPTEN)
 665  if (EMSCRIPTEN AND enable_emscripten_asyncify)
 666    # Use this option if your program is targeting `-sASYNCIFY`.  The latter is
 667    # required to scan the stack, `ASYNCIFY_STACK_SIZE` is probably needed for
 668    # `gctest` only.
 669    add_definitions("-DEMSCRIPTEN_ASYNCIFY")
 670    set(CMAKE_EXE_LINKER_FLAGS
 671          "${CMAKE_EXE_LINKER_FLAGS} -sASYNCIFY -sASYNCIFY_STACK_SIZE=128000")
 672  endif()
 673  
 674  add_library(gc ${SRC})
 675  add_library(bdwgc::gc ALIAS gc)
 676  target_link_libraries(gc
 677                  PRIVATE ${ATOMIC_OPS_LIBS_CMAKE} ${THREADDLLIBS_LIST})
 678  target_include_directories(gc INTERFACE
 679          "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
 680          "$<INSTALL_INTERFACE:include>")
 681  
 682  if (enable_cplusplus)
 683    if (BORLAND OR MSVC OR WATCOM)
 684      add_library(gccpp gc_badalc.cpp gc_cpp.cpp)
 685    else()
 686      add_library(gccpp gc_badalc.cc gc_cpp.cc)
 687    endif()
 688    add_library(bdwgc::gccpp ALIAS gccpp)
 689    target_link_libraries(gccpp PRIVATE gc)
 690    target_include_directories(gccpp INTERFACE
 691          "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
 692          "$<INSTALL_INTERFACE:include>")
 693    if (enable_throw_bad_alloc_library)
 694      # The same as `gccpp` but contains only `gc_badalc`.
 695      if (BORLAND OR MSVC OR WATCOM)
 696        add_library(gctba gc_badalc.cpp)
 697      else()
 698        add_library(gctba gc_badalc.cc)
 699      endif()
 700      add_library(bdwgc::gctba ALIAS gctba)
 701      target_link_libraries(gctba PRIVATE gc)
 702      target_include_directories(gctba INTERFACE
 703          "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
 704          "$<INSTALL_INTERFACE:include>")
 705    endif(enable_throw_bad_alloc_library)
 706  endif()
 707  
 708  if (build_cord)
 709    set(CORD_SRC cord/cordbscs.c cord/cordprnt.c cord/cordxtra.c)
 710    add_library(cord ${CORD_SRC})
 711    add_library(bdwgc::cord ALIAS cord)
 712    target_link_libraries(cord PRIVATE gc)
 713    target_include_directories(cord INTERFACE
 714          "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
 715          "$<INSTALL_INTERFACE:include>")
 716    if (BUILD_SHARED_LIBS)
 717      set_property(TARGET cord PROPERTY VERSION ${CORD_VERSION_PROP})
 718      set_property(TARGET cord PROPERTY SOVERSION ${CORD_SOVERSION})
 719    endif()
 720    install(TARGETS cord EXPORT BDWgcTargets
 721            LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 722            ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 723            RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
 724            INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 725  endif(build_cord)
 726  
 727  if (BUILD_SHARED_LIBS AND HAVE_FLAG_WL_NO_UNDEFINED)
 728    # Declare that the libraries do not refer to external symbols.
 729    if (${CMAKE_VERSION} VERSION_LESS "3.13.0")
 730      target_link_libraries(gc PRIVATE ${WL_NO_UNDEFINED_OPT})
 731      if (enable_cplusplus)
 732        target_link_libraries(gccpp PRIVATE ${WL_NO_UNDEFINED_OPT})
 733        if (enable_throw_bad_alloc_library)
 734          target_link_libraries(gctba PRIVATE ${WL_NO_UNDEFINED_OPT})
 735        endif(enable_throw_bad_alloc_library)
 736      endif(enable_cplusplus)
 737      if (build_cord)
 738        target_link_libraries(cord PRIVATE ${WL_NO_UNDEFINED_OPT})
 739      endif(build_cord)
 740    else()
 741      target_link_options(gc PRIVATE ${WL_NO_UNDEFINED_OPT})
 742      if (enable_cplusplus)
 743        target_link_options(gccpp PRIVATE ${WL_NO_UNDEFINED_OPT})
 744        if (enable_throw_bad_alloc_library)
 745          target_link_options(gctba PRIVATE ${WL_NO_UNDEFINED_OPT})
 746        endif(enable_throw_bad_alloc_library)
 747      endif(enable_cplusplus)
 748      if (build_cord)
 749        target_link_options(cord PRIVATE ${WL_NO_UNDEFINED_OPT})
 750      endif(build_cord)
 751    endif()
 752  endif()
 753  
 754  if (BUILD_SHARED_LIBS)
 755    set_property(TARGET gc PROPERTY VERSION ${GC_VERSION_PROP})
 756    set_property(TARGET gc PROPERTY SOVERSION ${GC_SOVERSION})
 757  endif()
 758  install(TARGETS gc EXPORT BDWgcTargets
 759          LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 760          ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 761          RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
 762          INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 763  
 764  if (enable_cplusplus)
 765    if (BUILD_SHARED_LIBS)
 766      set_property(TARGET gccpp PROPERTY VERSION ${GCCPP_VERSION_PROP})
 767      set_property(TARGET gccpp PROPERTY SOVERSION ${GCCPP_SOVERSION})
 768    endif()
 769    install(TARGETS gccpp EXPORT BDWgcTargets
 770            LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 771            ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 772            RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
 773            INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 774    if (enable_throw_bad_alloc_library)
 775      if (BUILD_SHARED_LIBS)
 776        set_property(TARGET gctba PROPERTY VERSION ${GCCPP_VERSION_PROP})
 777        set_property(TARGET gctba PROPERTY SOVERSION ${GCCPP_SOVERSION})
 778      endif()
 779      install(TARGETS gctba EXPORT BDWgcTargets
 780              LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 781              ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
 782              RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
 783              INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 784    endif(enable_throw_bad_alloc_library)
 785  endif(enable_cplusplus)
 786  
 787  if (install_headers)
 788    install(FILES include/gc/gc.h
 789                  include/gc/gc_backptr.h
 790                  include/gc/gc_config_macros.h
 791                  include/gc/gc_inline.h
 792                  include/gc/gc_mark.h
 793                  include/gc/gc_tiny_fl.h
 794                  include/gc/gc_typed.h
 795                  include/gc/gc_version.h
 796                  include/gc/javaxfc.h
 797                  include/gc/leak_detector.h
 798            DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc")
 799    install(FILES include/gc.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 800    if (enable_cplusplus)
 801      install(FILES include/gc_cpp.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 802      install(FILES include/gc/gc_allocator.h
 803                    include/gc/gc_cpp.h
 804              DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc")
 805    endif()
 806    if (enable_disclaim)
 807      install(FILES include/gc/gc_disclaim.h
 808              DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc")
 809    endif()
 810    if (enable_gcj_support)
 811      install(FILES include/gc/gc_gcj.h
 812              DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc")
 813    endif()
 814    if (enable_threads)
 815      install(FILES include/gc/gc_pthread_redirects.h
 816              DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc")
 817    endif()
 818    if (build_cord)
 819      install(FILES include/gc/cord.h
 820                    include/gc/cord_pos.h
 821                    include/gc/ec.h
 822              DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc")
 823    endif()
 824  
 825    # Provide `pkg-config` metadata.
 826    set(prefix "${CMAKE_INSTALL_PREFIX}")
 827    set(exec_prefix \${prefix})
 828    set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
 829    set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
 830    string(REPLACE ";" " " THREADDLLIBS "${THREADDLLIBS_LIST}")
 831    # `ATOMIC_OPS_LIBS`, `PACKAGE_VERSION` are defined above.
 832    configure_file(bdw-gc.pc.in bdw-gc.pc @ONLY)
 833    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/bdw-gc.pc"
 834            DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
 835  endif(install_headers)
 836  
 837  if (build_tests)
 838    if (build_cord)
 839      add_executable(cordtest cord/tests/cordtest.c ${NODIST_SRC})
 840      target_link_libraries(cordtest PRIVATE cord gc)
 841      add_test(NAME cordtest COMMAND cordtest)
 842  
 843      if (WIN32) # AND NOT CYGWIN
 844        if (NOT (CMAKE_C_COMPILER_ID STREQUAL "Clang"))
 845          # Workaround MS Clang failure to compile a resource file.
 846          set(DE_WIN_RC cord/tests/de_win.rc)
 847        endif()
 848        add_executable(de cord/tests/de.c cord/tests/de_win.c
 849                       ${DE_WIN_RC} ${NODIST_SRC})
 850        set_target_properties(de PROPERTIES WIN32_EXECUTABLE TRUE)
 851        target_link_libraries(de PRIVATE cord gc gdi32)
 852      endif()
 853    endif(build_cord)
 854  
 855    # Compile some tests as C++ to test `extern "C"` in header files.
 856    if (enable_cplusplus)
 857      set_source_files_properties(tests/leak.c PROPERTIES LANGUAGE CXX)
 858      if (BORLAND OR MSVC OR WATCOM)
 859        # `WinMain`-based test hangs at startup if compiled by VC as C++ code.
 860      else()
 861        set_source_files_properties(tests/gctest.c PROPERTIES LANGUAGE CXX)
 862        # To avoid "treating 'c' input as 'c++' when in C++ mode" Clang warning.
 863        add_compile_options(-x c++)
 864      endif()
 865    endif(enable_cplusplus)
 866  
 867    add_executable(gctest WIN32 tests/gctest.c ${NODIST_SRC})
 868    target_link_libraries(gctest
 869                  PRIVATE gc ${ATOMIC_OPS_LIBS_CMAKE} ${THREADDLLIBS_LIST})
 870    add_test(NAME gctest COMMAND gctest)
 871    if (WATCOM AND NOT enable_gc_assertions)
 872      # Suppress "unreachable code" warning in `GC_MALLOC_WORDS()` and
 873      # `GC_MALLOC_ATOMIC_WORDS()`.
 874      target_compile_options(gctest PRIVATE /wcd=201)
 875    endif()
 876  
 877    add_executable(hugetest tests/huge.c ${NODIST_SRC})
 878    target_link_libraries(hugetest PRIVATE gc)
 879    add_test(NAME hugetest COMMAND hugetest)
 880  
 881    add_executable(leaktest tests/leak.c ${NODIST_SRC})
 882    target_link_libraries(leaktest PRIVATE gc)
 883    add_test(NAME leaktest COMMAND leaktest)
 884  
 885    add_executable(middletest tests/middle.c ${NODIST_SRC})
 886    target_link_libraries(middletest PRIVATE gc)
 887    add_test(NAME middletest COMMAND middletest)
 888  
 889    add_executable(realloctest tests/realloc.c ${NODIST_SRC})
 890    target_link_libraries(realloctest PRIVATE gc)
 891    add_test(NAME realloctest COMMAND realloctest)
 892  
 893    add_executable(smashtest tests/smash.c ${NODIST_SRC})
 894    target_link_libraries(smashtest PRIVATE gc)
 895    add_test(NAME smashtest COMMAND smashtest)
 896  
 897    if (NOT (BUILD_SHARED_LIBS AND WIN32))
 898      add_library(staticroots_lib_test tests/staticroots_lib.c)
 899      target_link_libraries(staticroots_lib_test PRIVATE gc)
 900      add_library(staticroots_lib2_test tests/staticroots_lib.c)
 901      target_compile_options(staticroots_lib2_test PRIVATE "-DSTATICROOTSLIB2")
 902      target_link_libraries(staticroots_lib2_test PRIVATE gc)
 903      add_executable(staticrootstest tests/staticroots.c ${NODIST_SRC})
 904      target_compile_options(staticrootstest PRIVATE "-DSTATICROOTSLIB2")
 905      target_link_libraries(staticrootstest PRIVATE
 906                            gc staticroots_lib_test staticroots_lib2_test)
 907      add_test(NAME staticrootstest COMMAND staticrootstest)
 908    endif()
 909  
 910    if (enable_gc_debug)
 911      add_executable(tracetest tests/trace.c ${NODIST_SRC})
 912      target_link_libraries(tracetest PRIVATE gc)
 913      add_test(NAME tracetest COMMAND tracetest)
 914    endif()
 915  
 916    if (enable_threads)
 917      add_executable(atomicopstest tests/atomicops.c ${NODIST_SRC})
 918      target_link_libraries(atomicopstest
 919                  PRIVATE ${ATOMIC_OPS_LIBS_CMAKE} ${THREADDLLIBS_LIST})
 920      add_test(NAME atomicopstest COMMAND atomicopstest)
 921  
 922      add_executable(initfromthreadtest tests/initfromthread.c ${NODIST_SRC})
 923      target_link_libraries(initfromthreadtest PRIVATE gc ${THREADDLLIBS_LIST})
 924      add_test(NAME initfromthreadtest COMMAND initfromthreadtest)
 925  
 926      add_executable(subthreadcreatetest tests/subthreadcreate.c ${NODIST_SRC})
 927      target_link_libraries(subthreadcreatetest
 928                  PRIVATE gc ${ATOMIC_OPS_LIBS_CMAKE} ${THREADDLLIBS_LIST})
 929      add_test(NAME subthreadcreatetest COMMAND subthreadcreatetest)
 930  
 931      add_executable(threadleaktest tests/threadleak.c ${NODIST_SRC})
 932      target_link_libraries(threadleaktest PRIVATE gc ${THREADDLLIBS_LIST})
 933      add_test(NAME threadleaktest COMMAND threadleaktest)
 934  
 935      if (NOT WIN32)
 936        add_executable(threadkeytest tests/threadkey.c ${NODIST_SRC})
 937        target_link_libraries(threadkeytest PRIVATE gc ${THREADDLLIBS_LIST})
 938        add_test(NAME threadkeytest COMMAND threadkeytest)
 939      endif()
 940    endif(enable_threads)
 941  
 942    if (enable_cplusplus)
 943      add_executable(cpptest WIN32 tests/cpp.cc ${NODIST_SRC})
 944      target_link_libraries(cpptest PRIVATE gc gccpp)
 945      add_test(NAME cpptest COMMAND cpptest)
 946      if (enable_throw_bad_alloc_library)
 947        add_executable(treetest tests/tree.cc ${NODIST_SRC})
 948        target_link_libraries(treetest PRIVATE gc gctba)
 949        add_test(NAME treetest COMMAND treetest)
 950      endif(enable_throw_bad_alloc_library)
 951    endif()
 952  
 953    if (enable_disclaim)
 954      add_executable(disclaim_bench tests/disclaim_bench.c ${NODIST_SRC})
 955      target_link_libraries(disclaim_bench PRIVATE gc)
 956      add_test(NAME disclaim_bench COMMAND disclaim_bench)
 957  
 958      add_executable(disclaimtest tests/disclaim.c ${NODIST_SRC})
 959      target_link_libraries(disclaimtest PRIVATE gc ${THREADDLLIBS_LIST})
 960      add_test(NAME disclaimtest COMMAND disclaimtest)
 961  
 962      add_executable(weakmaptest tests/weakmap.c ${NODIST_SRC})
 963      target_link_libraries(weakmaptest
 964                  PRIVATE gc ${ATOMIC_OPS_LIBS_CMAKE} ${THREADDLLIBS_LIST})
 965      add_test(NAME weakmaptest COMMAND weakmaptest)
 966    endif()
 967  endif(build_tests)
 968  
 969  if (enable_docs)
 970    install(FILES AUTHORS ChangeLog LICENSE README.md
 971            DESTINATION "${CMAKE_INSTALL_DOCDIR}")
 972    install(FILES
 973              docs/autoconf.md
 974              docs/cmake.md
 975              docs/cords.md
 976              docs/debugging.md
 977              docs/environment.md
 978              docs/faq.md
 979              docs/finalization.md
 980              docs/gcdescr.md
 981              docs/gcinterface.md
 982              docs/leak.md
 983              docs/macros.md
 984              docs/overview.md
 985              docs/porting.md
 986              docs/scale.md
 987              docs/simple_example.md
 988              docs/tree.md
 989            DESTINATION "${CMAKE_INSTALL_DOCDIR}/docs")
 990    install(FILES
 991              docs/platforms/README.aix
 992              docs/platforms/README.arm_cross
 993              docs/platforms/README.darwin
 994              docs/platforms/README.dgux386
 995              docs/platforms/README.emscripten
 996              docs/platforms/README.ews4800
 997              docs/platforms/README.hp
 998              docs/platforms/README.linux
 999              docs/platforms/README.os2
1000              docs/platforms/README.sgi
1001              docs/platforms/README.solaris2
1002              docs/platforms/README.symbian
1003              docs/platforms/README.uts
1004              docs/platforms/README.win32
1005              docs/platforms/README.win64
1006            DESTINATION "${CMAKE_INSTALL_DOCDIR}/docs/platforms")
1007  
1008    install(FILES gc.man DESTINATION "${CMAKE_INSTALL_MANDIR}/man3" RENAME gc.3)
1009  endif(enable_docs)
1010  
1011  # CMake config/targets files.
1012  install(EXPORT BDWgcTargets FILE BDWgcTargets.cmake
1013          NAMESPACE BDWgc:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/bdwgc")
1014  
1015  configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in"
1016          "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfig.cmake"
1017          INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/bdwgc"
1018          NO_SET_AND_CHECK_MACRO)
1019  
1020  write_basic_package_version_file(
1021          "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfigVersion.cmake"
1022          VERSION "${PACKAGE_VERSION}" COMPATIBILITY AnyNewerVersion)
1023  
1024  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfig.cmake"
1025                "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfigVersion.cmake"
1026          DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/bdwgc")
1027  
1028  export(EXPORT BDWgcTargets
1029         FILE "${CMAKE_CURRENT_BINARY_DIR}/BDWgcTargets.cmake")
1030