2
0

CheckGCCAtomicIntrinsics.cmake 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #
  2. # SRT - Secure, Reliable, Transport Copyright (c) 2021 Haivision Systems Inc.
  3. #
  4. # This Source Code Form is subject to the terms of the Mozilla Public License,
  5. # v. 2.0. If a copy of the MPL was not distributed with this file, You can
  6. # obtain one at http://mozilla.org/MPL/2.0/.
  7. #
  8. # Check for GCC Atomic Intrinsics and whether libatomic is required.
  9. #
  10. # Sets:
  11. # HAVE_LIBATOMIC
  12. # HAVE_LIBATOMIC_COMPILES
  13. # HAVE_LIBATOMIC_COMPILES_STATIC
  14. # HAVE_GCCATOMIC_INTRINSICS
  15. # HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC
  16. #
  17. # See
  18. # https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
  19. # https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
  20. include(CheckCSourceCompiles)
  21. include(CheckLibraryExists)
  22. function(CheckGCCAtomicIntrinsics)
  23. unset(HAVE_LIBATOMIC CACHE)
  24. unset(HAVE_LIBATOMIC_COMPILES CACHE)
  25. unset(HAVE_LIBATOMIC_COMPILES_STATIC CACHE)
  26. unset(HAVE_GCCATOMIC_INTRINSICS CACHE)
  27. unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC CACHE)
  28. set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6
  29. unset(CMAKE_REQUIRED_FLAGS)
  30. unset(CMAKE_REQUIRED_LIBRARIES)
  31. unset(CMAKE_REQUIRED_LINK_OPTIONS)
  32. # Check for existence of libatomic and whether this symbol is present.
  33. check_library_exists(atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC)
  34. set(CheckLibAtomicCompiles_CODE
  35. "
  36. int main(void)
  37. {
  38. const int result = 0;
  39. return result;
  40. }
  41. ")
  42. set(CMAKE_REQUIRED_LIBRARIES "atomic")
  43. # Check that the compiler can build a simple application and link with
  44. # libatomic.
  45. check_c_source_compiles("${CheckLibAtomicCompiles_CODE}"
  46. HAVE_LIBATOMIC_COMPILES)
  47. if(NOT HAVE_LIBATOMIC_COMPILES)
  48. set(HAVE_LIBATOMIC
  49. 0
  50. CACHE INTERNAL "" FORCE)
  51. endif()
  52. if(HAVE_LIBATOMIC AND HAVE_LIBATOMIC_COMPILES)
  53. # CMAKE_REQUIRED_LINK_OPTIONS was introduced in CMake 3.14.
  54. if(CMAKE_VERSION VERSION_LESS "3.14")
  55. set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
  56. else()
  57. set(CMAKE_REQUIRED_FLAGS "-static")
  58. endif()
  59. # Check that the compiler can build a simple application and statically link
  60. # with libatomic.
  61. check_c_source_compiles("${CheckLibAtomicCompiles_CODE}"
  62. HAVE_LIBATOMIC_COMPILES_STATIC)
  63. else()
  64. set(HAVE_LIBATOMIC_COMPILES_STATIC
  65. 0
  66. CACHE INTERNAL "" FORCE)
  67. endif()
  68. unset(CMAKE_REQUIRED_FLAGS)
  69. unset(CMAKE_REQUIRED_LIBRARIES)
  70. unset(CMAKE_REQUIRED_LINK_OPTIONS)
  71. set(CheckGCCAtomicIntrinsics_CODE
  72. "
  73. #include<stddef.h>
  74. #include<stdint.h>
  75. int main(void)
  76. {
  77. ptrdiff_t x = 0;
  78. intmax_t y = 0;
  79. __atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST);
  80. __atomic_add_fetch(&y, 1, __ATOMIC_SEQ_CST);
  81. return __atomic_sub_fetch(&x, 1, __ATOMIC_SEQ_CST)
  82. + __atomic_sub_fetch(&y, 1, __ATOMIC_SEQ_CST);
  83. }
  84. ")
  85. set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6
  86. check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}"
  87. HAVE_GCCATOMIC_INTRINSICS)
  88. if(NOT HAVE_GCCATOMIC_INTRINSICS AND HAVE_LIBATOMIC)
  89. set(CMAKE_REQUIRED_LIBRARIES "atomic")
  90. check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}"
  91. HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC)
  92. if(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC)
  93. set(HAVE_GCCATOMIC_INTRINSICS
  94. 1
  95. CACHE INTERNAL "" FORCE)
  96. endif()
  97. endif()
  98. endfunction(CheckGCCAtomicIntrinsics)