You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

589 lines
24 KiB

  1. # Copyright 2008-present Contributors to the OpenImageIO project.
  2. # SPDX-License-Identifier: BSD-3-Clause
  3. # https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
  4. ###########################################################################
  5. #
  6. # This file contains compiler-related detection, options, and actions.
  7. #
  8. # Each option declaration is kept close to the related logic for that
  9. # option.
  10. #
  11. ###########################################################################
  12. ###########################################################################
  13. # Print some basic status about the system and compiler
  14. #
  15. if (VERBOSE)
  16. message (STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
  17. message (STATUS "CMAKE_SYSTEM_VERSION = ${CMAKE_SYSTEM_VERSION}")
  18. message (STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
  19. endif ()
  20. message (STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
  21. message (STATUS "CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
  22. ###########################################################################
  23. # C++ language standard
  24. #
  25. set (CMAKE_CXX_STANDARD 11 CACHE STRING
  26. "C++ standard to prefer (11, 14, 17, 20, etc.)")
  27. set (CMAKE_CXX_STANDARD_REQUIRED ON)
  28. set (CMAKE_CXX_EXTENSIONS OFF)
  29. message (STATUS "Building for C++${CMAKE_CXX_STANDARD}")
  30. ###########################################################################
  31. # Figure out which compiler we're using
  32. #
  33. if (CMAKE_COMPILER_IS_GNUCC)
  34. execute_process (COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
  35. OUTPUT_VARIABLE GCC_VERSION
  36. OUTPUT_STRIP_TRAILING_WHITESPACE)
  37. if (VERBOSE)
  38. message (STATUS "Using gcc ${GCC_VERSION} as the compiler")
  39. endif ()
  40. else ()
  41. set (GCC_VERSION 0)
  42. endif ()
  43. if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER MATCHES "[Cc]lang")
  44. # If using any flavor of clang, set CMAKE_COMPILER_IS_CLANG. If it's
  45. # Apple's variety, set CMAKE_COMPILER_IS_APPLECLANG and
  46. # APPLECLANG_VERSION_STRING, otherwise for generic clang set
  47. # CLANG_VERSION_STRING.
  48. set (CMAKE_COMPILER_IS_CLANG 1)
  49. EXECUTE_PROCESS( COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE clang_full_version_string )
  50. if (clang_full_version_string MATCHES "Apple")
  51. set (CMAKE_CXX_COMPILER_ID "AppleClang")
  52. set (CMAKE_COMPILER_IS_APPLECLANG 1)
  53. string (REGEX REPLACE ".* version ([0-9]+\\.[0-9]+).*" "\\1" APPLECLANG_VERSION_STRING ${clang_full_version_string})
  54. if (VERBOSE)
  55. message (STATUS "The compiler is Clang: ${CMAKE_CXX_COMPILER_ID} version ${APPLECLANG_VERSION_STRING}")
  56. endif ()
  57. else ()
  58. string (REGEX REPLACE ".* version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION_STRING ${clang_full_version_string})
  59. if (VERBOSE)
  60. message (STATUS "The compiler is Clang: ${CMAKE_CXX_COMPILER_ID} version ${CLANG_VERSION_STRING}")
  61. endif ()
  62. endif ()
  63. elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
  64. set (CMAKE_COMPILER_IS_INTEL 1)
  65. if (VERBOSE)
  66. message (STATUS "Using Intel as the compiler")
  67. endif ()
  68. endif ()
  69. ###########################################################################
  70. # Turn on more detailed warnings and optionally consider warnings as errors
  71. #
  72. if (${PROJECT_NAME}_SUPPORTED_RELEASE)
  73. option (STOP_ON_WARNING "Stop building if there are any compiler warnings" OFF)
  74. else ()
  75. option (STOP_ON_WARNING "Stop building if there are any compiler warnings" ON)
  76. endif()
  77. option (EXTRA_WARNINGS "Enable lots of extra pedantic warnings" OFF)
  78. if (NOT MSVC)
  79. add_compile_options ("-Wall")
  80. if (EXTRA_WARNINGS)
  81. add_compile_options ("-Wextra")
  82. endif ()
  83. if (STOP_ON_WARNING OR DEFINED ENV{CI})
  84. add_compile_options ("-Werror")
  85. # N.B. Force CI builds to use -Werror, even if STOP_ON_WARNING has
  86. # been switched off by default, which we may do in release
  87. # branches.
  88. endif ()
  89. endif ()
  90. ###########################################################################
  91. # Control symbol visibility
  92. #
  93. # We try hard to make default symbol visibility be "hidden", except for
  94. # symbols that are part of the public API, which should be marked in the
  95. # source code with a special decorator, OIIO_API.
  96. #
  97. # Additionally, there is a hidesymbols.map file that on some platforms may
  98. # give more fine-grained control for hiding symbols, because sometimes
  99. # dependent libraries may not be well behaved and need extra hiding.
  100. #
  101. set (CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
  102. option (VISIBILITY_INLINES_HIDDEN "Hide symbol visibility of inline functions" ON)
  103. set (VISIBILITY_MAP_FILE "${PROJECT_SOURCE_DIR}/src/build-scripts/hidesymbols.map" CACHE FILEPATH "Visibility map file")
  104. set (C_VISIBILITY_PRESET ${CXX_VISIBILITY_PRESET})
  105. if (${CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND
  106. (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) AND
  107. (CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "GNU"))
  108. # Linux/FreeBSD/Hurd: also hide all the symbols of dependent libraries
  109. # to prevent clashes if an app using this project is linked against
  110. # other versions of our dependencies.
  111. set (VISIBILITY_MAP_COMMAND "-Wl,--version-script=${VISIBILITY_MAP_FILE}")
  112. endif ()
  113. ###########################################################################
  114. # Compiler-specific and platform-specific options.
  115. #
  116. # Here is where we add a whole bunch of options for specific compilers or
  117. # platforms. Usually this is to suppress false-positive compiler warnings.
  118. #
  119. if (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_APPLECLANG)
  120. # Clang-specific options
  121. add_compile_options ("-Wno-unused-function")
  122. add_compile_options ("-Wno-overloaded-virtual")
  123. add_compile_options ("-Wno-unneeded-internal-declaration")
  124. add_compile_options ("-Wno-unused-private-field")
  125. add_compile_options ("-Wno-tautological-compare")
  126. # disable warning about unused command line arguments
  127. add_compile_options ("-Qunused-arguments")
  128. # Don't warn if we ask it not to warn about warnings it doesn't know
  129. add_compile_options ("-Wunknown-warning-option")
  130. if (CLANG_VERSION_STRING VERSION_GREATER_EQUAL 3.6 OR
  131. APPLECLANG_VERSION_STRING VERSION_GREATER 6.1)
  132. add_compile_options ("-Wno-unused-local-typedefs")
  133. endif ()
  134. if (CLANG_VERSION_STRING VERSION_GREATER_EQUAL 3.9)
  135. # Don't warn about using unknown preprocessor symbols in `#if`
  136. add_compile_options ("-Wno-expansion-to-defined")
  137. endif ()
  138. endif ()
  139. if (CMAKE_COMPILER_IS_GNUCC AND NOT (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_APPLECLANG))
  140. # gcc specific options
  141. add_compile_options ("-Wno-unused-local-typedefs")
  142. add_compile_options ("-Wno-unused-result")
  143. if (NOT ${GCC_VERSION} VERSION_LESS 7.0)
  144. add_compile_options ("-Wno-aligned-new")
  145. add_compile_options ("-Wno-noexcept-type")
  146. endif ()
  147. endif ()
  148. if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
  149. # Options common to gcc and clang
  150. # Ensure this macro is set for stdint.h
  151. add_definitions ("-D__STDC_LIMIT_MACROS")
  152. add_definitions ("-D__STDC_CONSTANT_MACROS")
  153. # this allows native instructions to be used for sqrtf instead of a function call
  154. add_compile_options ("-fno-math-errno")
  155. endif ()
  156. if (MSVC)
  157. # Microsoft specific options
  158. add_compile_options (/W1)
  159. add_definitions (-D_CRT_SECURE_NO_DEPRECATE)
  160. add_definitions (-D_CRT_SECURE_NO_WARNINGS)
  161. add_definitions (-D_CRT_NONSTDC_NO_WARNINGS)
  162. add_definitions (-D_SCL_SECURE_NO_WARNINGS)
  163. add_definitions (-DJAS_WIN_MSVC_BUILD)
  164. endif (MSVC)
  165. if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD"
  166. AND ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
  167. # For FreeBSD, minimum arch of i586 is needed for atomic cpu instructions
  168. add_compile_options (-march=i586)
  169. endif ()
  170. ###########################################################################
  171. # Use ccache if found
  172. #
  173. # This can really speed up compilation by caching object files that have
  174. # been compiled previously with identical arguments and inputs. Putting this
  175. # logic here makes it work even if the user is unaware of ccache. If it's
  176. # not found on the system, it will simply be silently not used.
  177. option (USE_CCACHE "Use ccache if found" ON)
  178. find_program (CCACHE_FOUND ccache)
  179. if (CCACHE_FOUND AND USE_CCACHE)
  180. if (CMAKE_COMPILER_IS_CLANG AND USE_QT AND (NOT DEFINED ENV{CCACHE_CPP2}))
  181. message (STATUS "Ignoring ccache because clang + Qt + env CCACHE_CPP2 is not set")
  182. else ()
  183. set_property (GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
  184. set_property (GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
  185. endif ()
  186. endif ()
  187. ###########################################################################
  188. # Option to force use of libc++ (the LLVM project's alternate C++ standard
  189. # library). Currently this only has an effect if using clang as the
  190. # compiler. Maybe it would also work for g++? Investigate.
  191. option (USE_LIBCPLUSPLUS "Compile with clang libc++" OFF)
  192. if (USE_LIBCPLUSPLUS AND CMAKE_COMPILER_IS_CLANG)
  193. message (STATUS "Using libc++")
  194. set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  195. endif ()
  196. ###########################################################################
  197. # For gcc >= 5, allow an option to force which version of the C++ ABI to
  198. # use (mostly this affects the implementation of std::string).
  199. #
  200. # FIXME: In theory, this should also be needed for clang, if compiling with
  201. # the gcc libstdc++ toolchain. In practice, I could not get things to build
  202. # with clang properly when using this option, and I haven't yet seen a case
  203. # where it's needed. We can return to this and fix for clang if it becomes a
  204. # legit problem later.
  205. #
  206. set (GLIBCXX_USE_CXX11_ABI "" CACHE STRING "For gcc, use the new C++11 library ABI (0|1)")
  207. if (CMAKE_COMPILER_IS_GNUCC AND ${GCC_VERSION} VERSION_GREATER_EQUAL 5.0)
  208. if (NOT ${GLIBCXX_USE_CXX11_ABI} STREQUAL "")
  209. add_definitions ("-D_GLIBCXX_USE_CXX11_ABI=${GLIBCXX_USE_CXX11_ABI}")
  210. endif ()
  211. endif ()
  212. ###########################################################################
  213. # SIMD and machine architecture options.
  214. #
  215. # The USE_SIMD option may be set to a comma-separated list of machine /
  216. # instruction set options, such as "avx3,f16c". The list will be parsed and
  217. # the proper compiler directives added to generate code for those ISA
  218. # capabilities.
  219. #
  220. set (USE_SIMD "" CACHE STRING "Use SIMD directives (0, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2, avx512f, f16c, aes)")
  221. set (SIMD_COMPILE_FLAGS "")
  222. if (NOT USE_SIMD STREQUAL "")
  223. message (STATUS "Compiling with SIMD level ${USE_SIMD}")
  224. if (USE_SIMD STREQUAL "0")
  225. set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "-DOIIO_NO_SSE=1")
  226. else ()
  227. string (REPLACE "," ";" SIMD_FEATURE_LIST ${USE_SIMD})
  228. foreach (feature ${SIMD_FEATURE_LIST})
  229. if (VERBOSE)
  230. message (STATUS "SIMD feature: ${feature}")
  231. endif ()
  232. if (MSVC OR CMAKE_COMPILER_IS_INTEL)
  233. set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "/arch:${feature}")
  234. else ()
  235. set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "-m${feature}")
  236. endif ()
  237. if (feature STREQUAL "fma" AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
  238. # If fma is requested, for numerical accuracy sake, turn it
  239. # off by default except when we explicitly use madd. At some
  240. # future time, we should look at this again carefully and
  241. # see if we want to use it more widely by ffp-contract=fast.
  242. add_compile_options ("-ffp-contract=off")
  243. endif ()
  244. endforeach()
  245. endif ()
  246. add_compile_options (${SIMD_COMPILE_FLAGS})
  247. endif ()
  248. ###########################################################################
  249. # Preparation to test for compiler/language features
  250. if (NOT VERBOSE)
  251. set (CMAKE_REQUIRED_QUIET 1)
  252. endif ()
  253. include (CMakePushCheckState)
  254. include (CheckCXXSourceRuns)
  255. include (CheckLibraryExists)
  256. ###########################################################################
  257. # Find out if it's safe for us to use std::regex or if we need boost.regex.
  258. # This is primarily about gcc 4.8 having a broken regex implementation.
  259. # This will be obsolete once our minimum supported gcc is >= 4.9.
  260. #
  261. #cmake_push_check_state ()
  262. #check_cxx_source_runs("
  263. # #include <regex>
  264. # int main() {
  265. # std::string r = std::regex_replace(std::string(\"abc\"), std::regex(\"b\"), \" \");
  266. # return r == \"a c\" ? 0 : -1;
  267. # }"
  268. # USE_STD_REGEX)
  269. #cmake_pop_check_state ()
  270. #if (USE_STD_REGEX)
  271. # add_definitions (-DUSE_STD_REGEX)
  272. #else ()
  273. add_definitions (-DUSE_BOOST_REGEX)
  274. #endif ()
  275. ###########################################################################
  276. # Check if we need libatomic on this platform. We shouldn't on mainstream
  277. # x86/x86_64, but might on some other platforms.
  278. #
  279. if (NOT MSVC AND NOT APPLE)
  280. cmake_push_check_state ()
  281. check_cxx_source_runs(
  282. "#include <atomic>
  283. #include <cstdint>
  284. std::atomic<uint64_t> x {0};
  285. int main() {
  286. uint64_t i = x.load(std::memory_order_relaxed);
  287. return 0;
  288. }"
  289. COMPILER_SUPPORTS_ATOMIC_WITHOUT_LIBATOMIC)
  290. cmake_pop_check_state ()
  291. if (NOT COMPILER_SUPPORTS_ATOMIC_WITHOUT_LIBATOMIC)
  292. check_library_exists (atomic __atomic_load_8 "" LIBATOMIC_WORKS)
  293. if (LIBATOMIC_WORKS)
  294. list (APPEND GCC_ATOMIC_LIBRARIES "-latomic")
  295. message (STATUS "Compiler needs libatomic, added")
  296. else ()
  297. message (FATAL_ERROR "Compiler needs libatomic, but not found")
  298. endif ()
  299. else ()
  300. if (VERBOSE)
  301. message (STATUS "Compiler supports std::atomic, no libatomic necessary")
  302. endif ()
  303. endif ()
  304. endif ()
  305. ###########################################################################
  306. # Code coverage options
  307. #
  308. option (CODECOV "Build code coverage tests" OFF)
  309. if (CODECOV AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
  310. message (STATUS "Compiling for code coverage analysis")
  311. add_compile_options ("-ftest-coverage -fprofile-arcs -O0")
  312. add_definitions ("-D${PROJ_NAME}_CODE_COVERAGE=1")
  313. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs")
  314. set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs")
  315. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -ftest-coverage -fprofile-arcs")
  316. endif ()
  317. ###########################################################################
  318. # Sanitizer options
  319. #
  320. set (SANITIZE "" CACHE STRING "Build code using sanitizer (address, thread)")
  321. if (SANITIZE AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
  322. message (STATUS "Compiling for sanitizer=${SANITIZE}")
  323. string (REPLACE "," ";" SANITIZE_FEATURE_LIST ${SANITIZE})
  324. foreach (feature ${SANITIZE_FEATURE_LIST})
  325. message (STATUS " sanitize feature: ${feature}")
  326. add_compile_options (-fsanitize=${feature})
  327. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${feature}")
  328. set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=${feature}")
  329. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=${feature}")
  330. endforeach()
  331. add_compile_options (-g -fno-omit-frame-pointer)
  332. if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
  333. set (SANITIZE_ON_LINUX 1)
  334. endif ()
  335. if (CMAKE_COMPILER_IS_GNUCC AND ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
  336. add_compile_options ("-fuse-ld=gold")
  337. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
  338. set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=gold")
  339. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold")
  340. set (SANITIZE_LIBRARIES "asan;pthread")
  341. # set (SANITIZE_LIBRARIES "asan" "ubsan")
  342. endif()
  343. if (CMAKE_COMPILER_IS_GNUCC)
  344. # turn on glibcxx extra annotations to find vector writes past end
  345. add_definitions ("-D_GLIBCXX_SANITIZE_VECTOR=1")
  346. endif ()
  347. add_definitions ("-D${PROJECT_NAME}_SANITIZE=1")
  348. endif ()
  349. ###########################################################################
  350. # clang-tidy options
  351. #
  352. # clang-tidy is a static analyzer that is part of the LLVM tools. It has a
  353. # variety of the usual bug and security tests, linting, and also tests for
  354. # things like finding (and correcting!) use of older language constructs.
  355. #
  356. # If clang-tidy is found and enabled, a "clang-tidy" build target will be
  357. # enabled. The set of tests can be customized both here and through
  358. # the .clang-tidy file that is part of this project.
  359. #
  360. option (CLANG_TIDY "Enable clang-tidy" OFF)
  361. set (CLANG_TIDY_CHECKS "-*" CACHE STRING "clang-tidy checks to perform (none='-*')")
  362. set (CLANG_TIDY_ARGS "" CACHE STRING "clang-tidy args")
  363. option (CLANG_TIDY_FIX "Have clang-tidy fix source" OFF)
  364. if (CLANG_TIDY)
  365. find_program(CLANG_TIDY_EXE NAMES "clang-tidy"
  366. DOC "Path to clang-tidy executable")
  367. message (STATUS "CLANG_TIDY_EXE ${CLANG_TIDY_EXE}")
  368. if (CLANG_TIDY_EXE AND NOT ${CMAKE_VERSION} VERSION_LESS 3.6)
  369. set (CMAKE_CXX_CLANG_TIDY
  370. "${CLANG_TIDY_EXE}"
  371. )
  372. if (CLANG_TIDY_ARGS)
  373. list (APPEND CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_ARGS})
  374. endif ()
  375. if (CLANG_TIDY_CHECKS)
  376. list (APPEND CMAKE_CXX_CLANG_TIDY -checks="${CLANG_TIDY_CHECKS}")
  377. endif ()
  378. execute_process (COMMAND ${CMAKE_CXX_CLANG_TIDY} -list-checks
  379. OUTPUT_VARIABLE tidy_checks
  380. OUTPUT_STRIP_TRAILING_WHITESPACE)
  381. if (CLANG_TIDY_FIX)
  382. list (APPEND CMAKE_CXX_CLANG_TIDY "-fix")
  383. endif ()
  384. message (STATUS "clang-tidy command line is: ${CMAKE_CXX_CLANG_TIDY}")
  385. message (STATUS "${tidy_checks}")
  386. else ()
  387. message (STATUS "Cannot run clang-tidy as requested")
  388. endif ()
  389. # Hint: run with CLANG_TIDY_ARGS=-list-checks to list all the checks
  390. endif ()
  391. ###########################################################################
  392. # clang-format options
  393. #
  394. # clang-format is a source code reformatter that is part of the LLVM tools.
  395. # It can be used to check adherence to project code formatting rules and
  396. # correct any deviations. If clang-format is found on the system, a
  397. # "clang-format" build target will trigger a reformatting.
  398. #
  399. # Note: skip all of this checking, setup, and cmake-format target if this
  400. # is being built as a subproject.
  401. if (NOT ${PROJECT_NAME}_IS_SUBPROJECT)
  402. set (CLANG_FORMAT_EXE_HINT "" CACHE PATH "clang-format executable's directory (will search if not specified")
  403. set (CLANG_FORMAT_INCLUDES "src/*.h" "src/*.cpp"
  404. CACHE STRING "Glob patterns to include for clang-format")
  405. set (CLANG_FORMAT_EXCLUDES "*pugixml*" "*SHA1*" "*/farmhash.cpp"
  406. "src/dpx.imageio/libdpx/*"
  407. "src/cineon.imageio/libcineon/*"
  408. "src/dds.imageio/squish/*"
  409. "src/gif.imageio/gif.h"
  410. "src/hdr.imageio/rgbe.cpp"
  411. "src/libutil/stb_sprintf.h"
  412. CACHE STRING "Glob patterns to exclude for clang-format")
  413. find_program (CLANG_FORMAT_EXE
  414. NAMES clang-format bin/clang-format
  415. HINTS ${CLANG_FORMAT_EXE_HINT} ENV CLANG_FORMAT_EXE_HINT
  416. ENV LLVM_DIRECTORY
  417. NO_DEFAULT_PATH
  418. DOC "Path to clang-format executable")
  419. find_program (CLANG_FORMAT_EXE NAMES clang-format bin/clang-format)
  420. if (CLANG_FORMAT_EXE)
  421. message (STATUS "clang-format found: ${CLANG_FORMAT_EXE}")
  422. # Start with the list of files to include when formatting...
  423. file (GLOB_RECURSE FILES_TO_FORMAT ${CLANG_FORMAT_INCLUDES})
  424. # ... then process any list of excludes we are given
  425. foreach (_pat ${CLANG_FORMAT_EXCLUDES})
  426. file (GLOB_RECURSE _excl ${_pat})
  427. list (REMOVE_ITEM FILES_TO_FORMAT ${_excl})
  428. endforeach ()
  429. #message (STATUS "clang-format file list: ${FILES_TO_FORMAT}")
  430. file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/.clang-format
  431. DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
  432. add_custom_target (clang-format
  433. COMMAND "${CLANG_FORMAT_EXE}" -i -style=file ${FILES_TO_FORMAT} )
  434. else ()
  435. message (STATUS "clang-format not found.")
  436. endif ()
  437. endif ()
  438. ###########################################################################
  439. # Another way to sneak in custom compiler and DSO linking flags.
  440. #
  441. set (EXTRA_CPP_ARGS "" CACHE STRING "Extra C++ command line definitions")
  442. if (EXTRA_CPP_ARGS)
  443. message (STATUS "Extra C++ args: ${EXTRA_CPP_ARGS}")
  444. add_compile_options ("${EXTRA_CPP_ARGS}")
  445. endif()
  446. set (EXTRA_DSO_LINK_ARGS "" CACHE STRING "Extra command line definitions when building DSOs")
  447. ###########################################################################
  448. # Set the versioning for shared libraries.
  449. #
  450. if (${PROJECT_NAME}_SUPPORTED_RELEASE)
  451. # Supported releases guarantee ABI back-compatibility within the release
  452. # family, so SO versioning is major.minor.
  453. set (SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
  454. CACHE STRING "Set the SO version for dynamic libraries")
  455. else ()
  456. # Development master makes no ABI stability guarantee, so we make the
  457. # SO naming capture down to the major.minor.patch level.
  458. set (SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
  459. CACHE STRING "Set the SO version for dynamic libraries")
  460. endif ()
  461. if (VERBOSE)
  462. message(STATUS "Setting SOVERSION to: ${SOVERSION}")
  463. endif ()
  464. ###########################################################################
  465. # BUILD_SHARED_LIBS, if turned off, will disable building of .so/.dll
  466. # dynamic libraries and instead only build static libraries.
  467. #
  468. option (BUILD_SHARED_LIBS "Build shared libraries (set to OFF to build static libs)" ON)
  469. if (NOT BUILD_SHARED_LIBS)
  470. add_definitions (-D${PROJ_NAME}_STATIC_DEFINE=1)
  471. endif ()
  472. ###########################################################################
  473. # LINKSTATIC, if enabled, will cause us to favor linking static versions
  474. # of library dependencies, if they are available.
  475. #
  476. option (LINKSTATIC "Link with static external libraries when possible" OFF)
  477. if (LINKSTATIC)
  478. #set (_orig_link_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
  479. message (STATUS "Statically linking external libraries when possible")
  480. if (WIN32)
  481. set (CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
  482. else ()
  483. set (CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
  484. endif ()
  485. endif ()
  486. ###########################################################################
  487. # Any extra logic to be run only for CI builds goes here.
  488. #
  489. if (DEFINED ENV{CI} OR DEFINED ENV{GITHUB_ACTIONS})
  490. add_definitions ("-D${PROJ_NAME}_CI=1" "-DBUILD_CI=1")
  491. if (APPLE)
  492. # Keep Mono framework from being incorrectly searched for include
  493. # files on GitHub Actions CI.
  494. set(CMAKE_FIND_FRAMEWORK LAST)
  495. endif ()
  496. endif ()
  497. ###########################################################################
  498. # Rpath handling at the install step
  499. #
  500. set (MACOSX_RPATH ON)
  501. if (CMAKE_SKIP_RPATH)
  502. # We need to disallow the user from truly setting CMAKE_SKIP_RPATH, since
  503. # we want to run the generated executables from the build tree in order to
  504. # generate the manual page documentation. However, we make sure the
  505. # install rpath is unset so that the install tree is still free of rpaths
  506. # for linux packaging purposes.
  507. set (CMAKE_SKIP_RPATH FALSE)
  508. unset (CMAKE_INSTALL_RPATH)
  509. else ()
  510. if (NOT CMAKE_INSTALL_RPATH)
  511. set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
  512. endif ()
  513. # add the automatically determined parts of the RPATH that
  514. # point to directories outside the build tree to the install RPATH
  515. set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
  516. if (VERBOSE)
  517. message (STATUS "CMAKE_INSTALL_RPATH = ${CMAKE_INSTALL_RPATH}")
  518. endif ()
  519. endif ()
  520. ###########################################################################
  521. # Macro to install targets to the appropriate locations. Use this instead
  522. # of the install(TARGETS ...) signature. Note that it adds it to the
  523. # export targets list for when we generate config files.
  524. #
  525. # Usage:
  526. #
  527. # install_targets (target1 [target2 ...])
  528. #
  529. macro (install_targets)
  530. install (TARGETS ${ARGN}
  531. EXPORT ${PROJ_NAME}_EXPORTED_TARGETS
  532. RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT user
  533. LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT user
  534. ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT developer)
  535. endmacro()