From 88b003ce5289e6de5f48b2eb8558394ed8694e0c Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 22 Nov 2023 18:01:47 +0100 Subject: [PATCH 01/10] =?UTF-8?q?=F0=9F=AA=9D=20Added=20a=20simple=20initi?= =?UTF-8?q?al=20pre-commit=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..9d4c4297e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,30 @@ +# To run all pre-commit checks, use: +# +# pre-commit run -a +# +# To install pre-commit hooks that run every time you commit: +# +# pre-commit install +# + +ci: + autoupdate_commit_msg: "⬆️ Bump pre-commit hooks" + autofix_commit_msg: "🎨 Incorporated pre-commit fixes" + +exclude: "^libs/|^benchmarks/" + +repos: + # Standard hooks + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-docstring-first + - id: check-merge-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: trailing-whitespace From 23363f472fe2e7acff61b81de42e289f19c762fe Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:39:30 +0100 Subject: [PATCH 02/10] :art: Incorporated pre-commit fixes --- .github/release-drafter.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 2 +- cli/cmd/physical_design/exact.hpp | 2 +- cmake/FindTBB.cmake | 2 +- docs/_static/hexagonalization.svg | 2 +- docs/layouts/gate_level_layout.rst | 1 - test/io/print_layout.cpp | 2 +- 7 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index fac619066..30746d9c7 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -49,7 +49,7 @@ footer: | template: | ## 👀 What's Changed - + $CHANGES - + **Full [CHANGELOG](https://fiction.readthedocs.io/en/latest/changelog.html)**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a8567b76b..b07852217 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -59,7 +59,7 @@ jobs: large-packages: false docker-images: false swap-storage: false - + - name: Install libraries and the respective compiler run: sudo apt-get update && sudo apt-get install -yq libtbb-dev ${{matrix.compiler}} diff --git a/cli/cmd/physical_design/exact.hpp b/cli/cmd/physical_design/exact.hpp index 47a4f7227..571085400 100644 --- a/cli/cmd/physical_design/exact.hpp +++ b/cli/cmd/physical_design/exact.hpp @@ -280,4 +280,4 @@ ALICE_ADD_COMMAND(exact, "Physical Design") #endif // FICTION_CMD_EXACT_HPP -#endif // FICTION_Z3_SOLVER \ No newline at end of file +#endif // FICTION_Z3_SOLVER diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake index 03cb18fa7..32fc261d0 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake @@ -427,4 +427,4 @@ if (NOT TBB_VERSION) ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") -endif () \ No newline at end of file +endif () diff --git a/docs/_static/hexagonalization.svg b/docs/_static/hexagonalization.svg index 5dd840f4e..79d1f5b01 100644 --- a/docs/_static/hexagonalization.svg +++ b/docs/_static/hexagonalization.svg @@ -1,3 +1,3 @@ -
$$(0, 0)$$
$$(1, 0)$$
$$(2, 0)$$
$$(0, 1)$$
$$(1, 1)$$
$$(2, 1)$$
$$(0, 2)$$
$$(1, 2)$$
$$(2, 2)$$
$$(1, 0)$$
$$w$$
$$h$$
$$(0, 1)$$
$$(1, 1)$$
$$(0, 2)$$
$$(1, 2)$$
$$(2, 2)$$
$$(0, 3)$$
$$(1, 3)$$
$$(1, 4)$$
Text is not SVG - cannot display
\ No newline at end of file +
$$(0, 0)$$
$$(1, 0)$$
$$(2, 0)$$
$$(0, 1)$$
$$(1, 1)$$
$$(2, 1)$$
$$(0, 2)$$
$$(1, 2)$$
$$(2, 2)$$
$$(1, 0)$$
$$w$$
$$h$$
$$(0, 1)$$
$$(1, 1)$$
$$(0, 2)$$
$$(1, 2)$$
$$(2, 2)$$
$$(0, 3)$$
$$(1, 3)$$
$$(1, 4)$$
Text is not SVG - cannot display
diff --git a/docs/layouts/gate_level_layout.rst b/docs/layouts/gate_level_layout.rst index e58f24654..3039a6c37 100644 --- a/docs/layouts/gate_level_layout.rst +++ b/docs/layouts/gate_level_layout.rst @@ -16,4 +16,3 @@ has to have a concrete position assigned, mockturtle cannot be used to generate .. doxygenclass:: fiction::gate_level_layout :members: - diff --git a/test/io/print_layout.cpp b/test/io/print_layout.cpp index 27fe6212f..cf16b8399 100644 --- a/test/io/print_layout.cpp +++ b/test/io/print_layout.cpp @@ -643,4 +643,4 @@ TEST_CASE("Print Bestagon OR-gate", "[print-charge-layout]") "\n"; CHECK(layout_print == print_stream.str()); -} \ No newline at end of file +} From e44130516ac5781f20329c1c2c83f43912778416 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:40:19 +0100 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=AA=9D=20Added=20a=20check=20to=20h?= =?UTF-8?q?andle=20unwanted=20unicode=20characters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d4c4297e..3ca816405 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,3 +28,10 @@ repos: - id: end-of-file-fixer - id: mixed-line-ending - id: trailing-whitespace + + # Handling unwanted unicode characters + - repo: https://github.com/sirosen/texthooks + rev: 0.6.2 + hooks: + - id: fix-ligatures + - id: fix-smartquotes From 32b9cd563acb1d1ac050fa3f321223ab89656447 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:41:25 +0100 Subject: [PATCH 04/10] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commit?= =?UTF-8?q?=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cli/cmd/io/tt.hpp | 2 +- docs/cli.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/cmd/io/tt.hpp b/cli/cmd/io/tt.hpp index 08d5b4268..3ac3af028 100644 --- a/cli/cmd/io/tt.hpp +++ b/cli/cmd/io/tt.hpp @@ -37,7 +37,7 @@ class tt_command : public command "expression !E, the conjunction of multiple expressions (E...E), the disjunction of " "multiple expressions {E...E}, the exclusive OR of multiple expressions [E...E], or the " "majority of three expressions . Examples are [(ab)(!ac)] to describe if-then-else, " - "or !{!a!b} to describe the application of De Morgan’s law to (ab). The size of the truth " + "or !{!a!b} to describe the application of De Morgan's law to (ab). The size of the truth " "table must fit the largest variable in the expression, e.g., if c is the largest " "variable, then the truth table have at least three variables.") { diff --git a/docs/cli.rst b/docs/cli.rst index 3f4086d1b..f50241ecd 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -83,7 +83,7 @@ or be obtained by :ref:`simulating` a ``network`` or ``gate_la An expression ``E`` is a constant ``0`` or ``1``, or a variable ``a, b, ..., p``, the negation of an expression ``!E``, the conjunction of multiple expressions ``(E...E)``, the disjunction of multiple expressions ``{E...E}``, the exclusive OR of multiple expressions ``[E...E]``, or the majority of three expressions ````. Examples are ``[(ab)(!ac)]`` to describe -if-then-else, or ``!{!a!b}`` to describe the application of De Morgan’s law to ``(ab)``. The size of the truth table must +if-then-else, or ``!{!a!b}`` to describe the application of De Morgan's law to ``(ab)``. The size of the truth table must fit the largest variable in the expression, e.g., if ``c`` is the largest variable, then the truth table has at least three variables. From 3f859c0c78793eff7b5194c1dac183177852c39d Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:42:37 +0100 Subject: [PATCH 05/10] =?UTF-8?q?=F0=9F=AA=9D=20Added=20a=20check=20for=20?= =?UTF-8?q?common=20RST=20mistakes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3ca816405..8a4b09387 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,9 +29,17 @@ repos: - id: mixed-line-ending - id: trailing-whitespace - # Handling unwanted unicode characters + # Handle unwanted unicode characters - repo: https://github.com/sirosen/texthooks rev: 0.6.2 hooks: - id: fix-ligatures - id: fix-smartquotes + + # Check for common RST mistakes + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 + hooks: + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal From 93c8d03b241310246ff480e84355596adfcf2d72 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:43:46 +0100 Subject: [PATCH 06/10] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commit?= =?UTF-8?q?=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/utils/utils.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index 18f2c0022..f9905b695 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -198,8 +198,8 @@ Math Utils .. doxygenfunction:: fiction::binomial_coefficient -`phmap` -------- +``phmap`` +--------- **Header:** ``fiction/utils/phmap_utils.hpp`` From 9b87f760d70a746294d2899fa1cee4144fe4820f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:44:51 +0100 Subject: [PATCH 07/10] =?UTF-8?q?=F0=9F=AA=9D=20Added=20an=20automatic=20c?= =?UTF-8?q?lang-format=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8a4b09387..f6031b63c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,3 +43,11 @@ repos: - id: rst-backticks - id: rst-directive-colons - id: rst-inline-touching-normal + + # clang-format the C++ part of the code base + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v17.0.4 + hooks: + - id: clang-format + types_or: [ c++, c ] + args: [ "-style=file" ] From 3e81c34b386e0c79f0b5f693a481473164a0850f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:45:11 +0100 Subject: [PATCH 08/10] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commit?= =?UTF-8?q?=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cli/cmd/logic/miginvopt.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cmd/logic/miginvopt.hpp b/cli/cmd/logic/miginvopt.hpp index 889c0d515..59216df1a 100644 --- a/cli/cmd/logic/miginvopt.hpp +++ b/cli/cmd/logic/miginvopt.hpp @@ -62,7 +62,7 @@ class miginvopt_command : public command // clone it because inverter optimization is an in-place algorithm auto ntk_clone = ntk_ptr->clone(); -// mockturtle::fanout_view fo_ntk_clone{ntk_clone}; + // mockturtle::fanout_view fo_ntk_clone{ntk_clone}; mockturtle::mig_inv_optimization(ntk_clone, &st); const auto mig_ptr = std::make_shared(ntk_clone); From f2f566d3a50fc595ee8fcf7b8db56f979ddc9721 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:47:52 +0100 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=AA=9D=20Added=20a=20check=20for=20?= =?UTF-8?q?CMake=20linting=20and=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f6031b63c..0ff7a38e0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,3 +51,12 @@ repos: - id: clang-format types_or: [ c++, c ] args: [ "-style=file" ] + + # CMake format and lint the CMakeLists.txt files + - repo: https://github.com/cheshirekow/cmake-format-precommit + rev: v0.6.13 + hooks: + - id: cmake-format + additional_dependencies: [ pyyaml ] + - id: cmake-lint + additional_dependencies: [ pyyaml ] From 5dee5bc71252ac72c2a148d14503ef13c567c27f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 27 Nov 2023 12:48:07 +0100 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commit?= =?UTF-8?q?=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 105 ++-- cli/CMakeLists.txt | 43 +- cmake/Cache.cmake | 53 +- cmake/CheckSubmodules.cmake | 14 +- cmake/CompilerWarnings.cmake | 218 ++++---- cmake/Coverage.cmake | 3 +- cmake/FindTBB.cmake | 711 ++++++++++++------------ cmake/FindZ3.cmake | 305 +++++----- cmake/Hardening.cmake | 178 +++--- cmake/InterproceduralOptimization.cmake | 14 +- cmake/PackageProject.cmake | 391 ++++++------- cmake/PreventInSourceBuilds.cmake | 22 +- cmake/ProjectOptions.cmake | 255 ++++----- cmake/Sanitizers.cmake | 158 +++--- cmake/StandardProjectSettings.cmake | 77 ++- cmake/SystemLink.cmake | 118 ++-- cmake/Utilities.cmake | 190 +++---- cmake/VCEnvironment.cmake | 121 ++-- experiments/CMakeLists.txt | 76 +-- include/CMakeLists.txt | 17 +- test/CMakeLists.txt | 35 +- test/benchmark/CMakeLists.txt | 38 +- 22 files changed, 1583 insertions(+), 1559 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96c8c6411..76e9b749d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,26 +1,28 @@ -# Large parts of this build system are based on Jason Turner's -# C++ Starter Project (https://github.com/lefticus/cpp_starter_project) and -# CMake Template (https://github.com/cpp-best-practices/cmake_template) +# Large parts of this build system are based on Jason Turner's C++ Starter +# Project (https://github.com/lefticus/cpp_starter_project) and CMake Template +# (https://github.com/cpp-best-practices/cmake_template) cmake_minimum_required(VERSION 3.21) # Only set the CMAKE_CXX_STANDARD if it is not set by someone else -if (NOT DEFINED CMAKE_CXX_STANDARD) - # Set C++ standard; at least C++17 is required - set(CMAKE_CXX_STANDARD 17) -endif () +if(NOT DEFINED CMAKE_CXX_STANDARD) + # Set C++ standard; at least C++17 is required + set(CMAKE_CXX_STANDARD 17) +endif() # strongly encouraged to enable this globally to avoid conflicts between -# -Wpedantic being enabled and -std=c++20 and -std=gnu++20 for example -# when compiling with PCH enabled +# -Wpedantic being enabled and -std=c++20 and -std=gnu++20 for example when +# compiling with PCH enabled set(CMAKE_CXX_EXTENSIONS OFF) # Set the project name and version -project(fiction - VERSION 0.5.0 - DESCRIPTION "An open-source design automation framework for Field-coupled Nanotechnologies" - HOMEPAGE_URL "https://github.com/cda-tum/fiction" - LANGUAGES CXX C) +project( + fiction + VERSION 0.5.0 + DESCRIPTION + "An open-source design automation framework for Field-coupled Nanotechnologies" + HOMEPAGE_URL "https://github.com/cda-tum/fiction" + LANGUAGES CXX C) include(cmake/PreventInSourceBuilds.cmake) include(cmake/ProjectOptions.cmake) @@ -30,18 +32,13 @@ fiction_setup_options() fiction_global_options() fiction_local_options() - # don't know if this should be set globally from here or not... set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(GIT_SHA - "Unknown" - CACHE STRING "SHA this build was generated from") -string( - SUBSTRING "${GIT_SHA}" - 0 - 8 - GIT_SHORT_SHA) + "Unknown" + CACHE STRING "SHA this build was generated from") +string(SUBSTRING "${GIT_SHA}" 0 8 GIT_SHORT_SHA) target_compile_features(fiction_options INTERFACE cxx_std_${CMAKE_CXX_STANDARD}) @@ -57,46 +54,50 @@ add_subdirectory(include) add_subdirectory(libs) # Enable progress bars -if (NOT WIN32) - option(FICTION_PROGRESS_BARS "Enable animated progress bars in command line" ON) - if (FICTION_PROGRESS_BARS) - target_compile_definitions(fiction_options INTERFACE PROGRESS_BARS) - endif () -endif () +if(NOT WIN32) + option(FICTION_PROGRESS_BARS "Enable animated progress bars in command line" + ON) + if(FICTION_PROGRESS_BARS) + target_compile_definitions(fiction_options INTERFACE PROGRESS_BARS) + endif() +endif() # CLI option(FICTION_CLI "Build fiction CLI" ON) -if (FICTION_CLI) - message(STATUS "Building fiction CLI") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/cli) -endif () +if(FICTION_CLI) + message(STATUS "Building fiction CLI") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/cli) +endif() # Experiments option(FICTION_EXPERIMENTS "Build fiction experiments" OFF) -if (FICTION_EXPERIMENTS) - message(STATUS "Building fiction experiments") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/experiments) -endif () +if(FICTION_EXPERIMENTS) + message(STATUS "Building fiction experiments") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/experiments) +endif() # Testing option(FICTION_TEST "Build fiction tests" OFF) -if (FICTION_TEST) - enable_testing() - message(STATUS "Building fiction tests") - add_subdirectory(test) -endif () - -# If MSVC is being used, and ASAN is enabled, we need to set the debugger environment -# so that it behaves well with MSVC's debugger, and we can run the target from visual studio -if (MSVC) - get_all_installable_targets(all_targets) - message("all_targets=${all_targets}") - set_target_properties(${all_targets} PROPERTIES VS_DEBUGGER_ENVIRONMENT "PATH=$(VC_ExecutablePath_x64);%PATH%") -endif () +if(FICTION_TEST) + enable_testing() + message(STATUS "Building fiction tests") + add_subdirectory(test) +endif() + +# If MSVC is being used, and ASAN is enabled, we need to set the debugger +# environment so that it behaves well with MSVC's debugger, and we can run the +# target from visual studio +if(MSVC) + get_all_installable_targets(all_targets) + message("all_targets=${all_targets}") + set_target_properties( + ${all_targets} PROPERTIES VS_DEBUGGER_ENVIRONMENT + "PATH=$(VC_ExecutablePath_x64);%PATH%") +endif() # set the startup project for the "play" button in MSVC set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT intro) -if (CMAKE_SKIP_INSTALL_RULES) - return() -endif () +if(CMAKE_SKIP_INSTALL_RULES) + return() +endif() diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 821da21f4..8f009b738 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(SOURCES ${PROJECT_SOURCE_DIR}/cli/fiction.cpp) +set(SOURCES ${PROJECT_SOURCE_DIR}/cli/fiction.cpp) # Include configuration file include_directories(${PROJECT_BINARY_DIR}/include/) @@ -10,36 +10,31 @@ add_executable(fiction ${SOURCES}) target_link_libraries(fiction PRIVATE libfiction alice) # Strip the executable if we are in Release mode -if (CMAKE_BUILD_TYPE STREQUAL "Release") - if (CMAKE_STRIP) - add_custom_command( - TARGET fiction - POST_BUILD - COMMAND ${CMAKE_STRIP} $ - ) - else () - message(WARNING "Strip command is not available. The executables will not be stripped.") - endif () -endif () - +if(CMAKE_BUILD_TYPE STREQUAL "Release") + if(CMAKE_STRIP) + add_custom_command( + TARGET fiction + POST_BUILD + COMMAND ${CMAKE_STRIP} $) + else() + message( + WARNING + "Strip command is not available. The executables will not be stripped.") + endif() +endif() # Package the CLI executable include(../cmake/PackageProject.cmake) -# Add other targets that you want installed here, by default we just package the one executable -# we know we want to ship -fiction_package_project( - TARGETS - fiction - fiction_options - fiction_warnings -) +# Add other targets that you want installed here, by default we just package the +# one executable we know we want to ship +fiction_package_project(TARGETS fiction fiction_options fiction_warnings) # Experience shows that explicit package naming can help make it easier to sort -# out potential ABI related issues before they start, while helping you -# track a build to a specific GIT SHA +# out potential ABI related issues before they start, while helping you track a +# build to a specific GIT SHA set(CPACK_PACKAGE_FILE_NAME - "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${GIT_SHORT_SHA}-${CMAKE_SYSTEM_NAME}-${CMAKE_BUILD_TYPE}-${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}" + "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${GIT_SHORT_SHA}-${CMAKE_SYSTEM_NAME}-${CMAKE_BUILD_TYPE}-${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}" ) include(CPack) diff --git a/cmake/Cache.cmake b/cmake/Cache.cmake index 9dcb72272..c63b053ff 100644 --- a/cmake/Cache.cmake +++ b/cmake/Cache.cmake @@ -1,33 +1,30 @@ # Enable cache if available function(fiction_enable_cache) - set(CACHE_OPTION - "ccache" - CACHE STRING "Compiler cache to be used") - set(CACHE_OPTION_VALUES "ccache" "sccache") - set_property(CACHE CACHE_OPTION PROPERTY STRINGS ${CACHE_OPTION_VALUES}) - list( - FIND - CACHE_OPTION_VALUES - ${CACHE_OPTION} - CACHE_OPTION_INDEX) + set(CACHE_OPTION + "ccache" + CACHE STRING "Compiler cache to be used") + set(CACHE_OPTION_VALUES "ccache" "sccache") + set_property(CACHE CACHE_OPTION PROPERTY STRINGS ${CACHE_OPTION_VALUES}) + list(FIND CACHE_OPTION_VALUES ${CACHE_OPTION} CACHE_OPTION_INDEX) - if (${CACHE_OPTION_INDEX} EQUAL -1) - message( - STATUS - "Using custom compiler cache system: '${CACHE_OPTION}', explicitly supported entries are ${CACHE_OPTION_VALUES}" - ) - endif () + if(${CACHE_OPTION_INDEX} EQUAL -1) + message( + STATUS + "Using custom compiler cache system: '${CACHE_OPTION}', explicitly supported entries are ${CACHE_OPTION_VALUES}" + ) + endif() - find_program(CACHE_BINARY NAMES ${CACHE_OPTION_VALUES}) - if (CACHE_BINARY) - message(STATUS "${CACHE_BINARY} found and enabled") - set(CMAKE_CXX_COMPILER_LAUNCHER - ${CACHE_BINARY} - CACHE FILEPATH "CXX compiler cache used") - set(CMAKE_C_COMPILER_LAUNCHER - ${CACHE_BINARY} - CACHE FILEPATH "C compiler cache used") - else () - message(WARNING "${CACHE_OPTION} is enabled but was not found. Not using it") - endif () + find_program(CACHE_BINARY NAMES ${CACHE_OPTION_VALUES}) + if(CACHE_BINARY) + message(STATUS "${CACHE_BINARY} found and enabled") + set(CMAKE_CXX_COMPILER_LAUNCHER + ${CACHE_BINARY} + CACHE FILEPATH "CXX compiler cache used") + set(CMAKE_C_COMPILER_LAUNCHER + ${CACHE_BINARY} + CACHE FILEPATH "C compiler cache used") + else() + message( + WARNING "${CACHE_OPTION} is enabled but was not found. Not using it") + endif() endfunction() diff --git a/cmake/CheckSubmodules.cmake b/cmake/CheckSubmodules.cmake index d025449f0..b1a742a01 100644 --- a/cmake/CheckSubmodules.cmake +++ b/cmake/CheckSubmodules.cmake @@ -1,8 +1,10 @@ -# check whether the submodule ``modulename`` is correctly cloned in the ``/libs`` directory. +# check whether the submodule ``modulename`` is correctly cloned in the +# ``/libs`` directory. macro(check_if_present modulename) - if (NOT EXISTS "${PROJECT_SOURCE_DIR}/libs/${modulename}/CMakeLists.txt") - message( - FATAL_ERROR - "Submodule `${modulename}` not cloned properly. Please run `git submodule update --init --recursive` from the main project directory to fix this issue.") - endif () + if(NOT EXISTS "${PROJECT_SOURCE_DIR}/libs/${modulename}/CMakeLists.txt") + message( + FATAL_ERROR + "Submodule `${modulename}` not cloned properly. Please run `git submodule update --init --recursive` from the main project directory to fix this issue." + ) + endif() endmacro() diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake index fef36b6c0..9ebda8a6e 100644 --- a/cmake/CompilerWarnings.cmake +++ b/cmake/CompilerWarnings.cmake @@ -3,113 +3,129 @@ # https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md function( - fiction_set_project_warnings - project_name - WARNINGS_AS_ERRORS - MSVC_WARNINGS - CLANG_WARNINGS - GCC_WARNINGS - CUDA_WARNINGS) - if ("${MSVC_WARNINGS}" STREQUAL "") - set(MSVC_WARNINGS - /W4 # Baseline reasonable warnings - /w14242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data - /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data - /w14263 # 'function': member function does not override any base class virtual member function - /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not be destructed correctly - /w14287 # 'operator': unsigned/negative constant mismatch - /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside the for-loop scope - /w14296 # 'operator': expression is always 'boolean_value' - /w14311 # 'variable': pointer truncation from 'type1' to 'type2' - /w14545 # expression before comma evaluates to a function which is missing an argument list - /w14546 # function call before comma missing argument list - /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect - /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? - /w14555 # expression has no effect; expected expression with side- effect - /w14619 # pragma warning: there is no warning number 'number' - /w14640 # Enable warning on thread un-safe static member initialization - /w14826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior - /w14905 # wide string literal cast to 'LPSTR' - /w14906 # string literal cast to 'LPWSTR' - /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied - /permissive- # standards conformance mode for MSVC compiler - ) - endif () + fiction_set_project_warnings + project_name + WARNINGS_AS_ERRORS + MSVC_WARNINGS + CLANG_WARNINGS + GCC_WARNINGS + CUDA_WARNINGS) + if("${MSVC_WARNINGS}" STREQUAL "") + set(MSVC_WARNINGS + /W4 # Baseline reasonable warnings + /w14242 # 'identifier': conversion from 'type1' to 'type2', possible + # loss of data + /w14254 # 'operator': conversion from 'type1:field_bits' to + # 'type2:field_bits', possible loss of data + /w14263 # 'function': member function does not override any base class + # virtual member function + /w14265 # 'classname': class has virtual functions, but destructor is + # not virtual instances of this class may not be destructed + # correctly + /w14287 # 'operator': unsigned/negative constant mismatch + /we4289 # nonstandard extension used: 'variable': loop control variable + # declared in the for-loop is used outside the for-loop scope + /w14296 # 'operator': expression is always 'boolean_value' + /w14311 # 'variable': pointer truncation from 'type1' to 'type2' + /w14545 # expression before comma evaluates to a function which is + # missing an argument list + /w14546 # function call before comma missing argument list + /w14547 # 'operator': operator before comma has no effect; expected + # operator with side-effect + /w14549 # 'operator': operator before comma has no effect; did you + # intend 'operator'? + /w14555 # expression has no effect; expected expression with side- + # effect + /w14619 # pragma warning: there is no warning number 'number' + /w14640 # Enable warning on thread un-safe static member initialization + /w14826 # Conversion from 'type1' to 'type2' is sign-extended. This may + # cause unexpected runtime behavior + /w14905 # wide string literal cast to 'LPSTR' + /w14906 # string literal cast to 'LPWSTR' + /w14928 # illegal copy-initialization; more than one user-defined + # conversion has been implicitly applied + /permissive- # standards conformance mode for MSVC compiler + ) + endif() - if ("${CLANG_WARNINGS}" STREQUAL "") - set(CLANG_WARNINGS - -Wall - -Wextra # reasonable and standard - -Wshadow # warn the user if a variable declaration shadows one from a parent context - -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps catch hard to track down memory errors - -Wold-style-cast # warn for c-style casts - -Wcast-align # warn for potential performance problem casts - -Wunused # warn on anything being unused - -Woverloaded-virtual # warn if you overload (not override) a virtual function - -Wpedantic # warn if non-standard C++ is used - -Wconversion # warn on type conversions that may lose data - -Wsign-conversion # warn on sign conversions - -Wnull-dereference # warn if a null dereference is detected - -Wdouble-promotion # warn if float is implicit promoted to double - -Wformat=2 # warn on security issues around functions that format output (ie printf) - -Wimplicit-fallthrough # warn on statements that fallthrough without an explicit annotation - -Wno-unknown-pragmas # do not warn if encountering unknown pragmas - -Wno-pragmas # do not warn if encountering unknown pragma options - ) - endif () + if("${CLANG_WARNINGS}" STREQUAL "") + set(CLANG_WARNINGS + -Wall + -Wextra # reasonable and standard + -Wshadow # warn the user if a variable declaration shadows one from a + # parent context + -Wnon-virtual-dtor # warn the user if a class with virtual functions has + # a non-virtual destructor. This helps catch hard to + # track down memory errors + -Wold-style-cast # warn for c-style casts + -Wcast-align # warn for potential performance problem casts + -Wunused # warn on anything being unused + -Woverloaded-virtual # warn if you overload (not override) a virtual + # function + -Wpedantic # warn if non-standard C++ is used + -Wconversion # warn on type conversions that may lose data + -Wsign-conversion # warn on sign conversions + -Wnull-dereference # warn if a null dereference is detected + -Wdouble-promotion # warn if float is implicit promoted to double + -Wformat=2 # warn on security issues around functions that format output + # (ie printf) + -Wimplicit-fallthrough # warn on statements that fallthrough without an + # explicit annotation + -Wno-unknown-pragmas # do not warn if encountering unknown pragmas + -Wno-pragmas # do not warn if encountering unknown pragma options + ) + endif() - if ("${GCC_WARNINGS}" STREQUAL "") - set(GCC_WARNINGS - ${CLANG_WARNINGS} - -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist - -Wduplicated-cond # warn if if / else chain has duplicated conditions - -Wduplicated-branches # warn if if / else branches have duplicated code - -Wlogical-op # warn about logical operations being used where bitwise were probably wanted - -Wuseless-cast # warn if you perform a cast to the same type - ) - endif () + if("${GCC_WARNINGS}" STREQUAL "") + set(GCC_WARNINGS + ${CLANG_WARNINGS} + -Wmisleading-indentation # warn if indentation implies blocks where + # blocks do not exist + -Wduplicated-cond # warn if if / else chain has duplicated conditions + -Wduplicated-branches # warn if if / else branches have duplicated code + -Wlogical-op # warn about logical operations being used where bitwise + # were probably wanted + -Wuseless-cast # warn if you perform a cast to the same type + ) + endif() - if ("${CUDA_WARNINGS}" STREQUAL "") - set(CUDA_WARNINGS - -Wall - -Wextra - -Wunused - -Wconversion - -Wshadow - # TODO add more Cuda warnings - ) - endif () + if("${CUDA_WARNINGS}" STREQUAL "") + set(CUDA_WARNINGS -Wall -Wextra -Wunused -Wconversion -Wshadow + # TODO add more Cuda warnings + ) + endif() - if (WARNINGS_AS_ERRORS) - message(TRACE "Warnings are treated as errors") - list(APPEND CLANG_WARNINGS -Werror) - list(APPEND GCC_WARNINGS -Werror) - list(APPEND MSVC_WARNINGS /WX) - endif () + if(WARNINGS_AS_ERRORS) + message(TRACE "Warnings are treated as errors") + list(APPEND CLANG_WARNINGS -Werror) + list(APPEND GCC_WARNINGS -Werror) + list(APPEND MSVC_WARNINGS /WX) + endif() - if (MSVC) - set(PROJECT_WARNINGS_CXX ${MSVC_WARNINGS}) - elseif (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - set(PROJECT_WARNINGS_CXX ${CLANG_WARNINGS}) - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(PROJECT_WARNINGS_CXX ${GCC_WARNINGS}) - else () - message(AUTHOR_WARNING "No compiler warnings set for CXX compiler: '${CMAKE_CXX_COMPILER_ID}'") - # TODO support Intel compiler - endif () + if(MSVC) + set(PROJECT_WARNINGS_CXX ${MSVC_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + set(PROJECT_WARNINGS_CXX ${CLANG_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(PROJECT_WARNINGS_CXX ${GCC_WARNINGS}) + else() + message( + AUTHOR_WARNING + "No compiler warnings set for CXX compiler: '${CMAKE_CXX_COMPILER_ID}'") + # TODO support Intel compiler + endif() - # use the same warning flags for C - set(PROJECT_WARNINGS_C "${PROJECT_WARNINGS_CXX}") + # use the same warning flags for C + set(PROJECT_WARNINGS_C "${PROJECT_WARNINGS_CXX}") - set(PROJECT_WARNINGS_CUDA "${CUDA_WARNINGS}") + set(PROJECT_WARNINGS_CUDA "${CUDA_WARNINGS}") - target_compile_options( - ${project_name} - INTERFACE - # C++ warnings - $<$:${PROJECT_WARNINGS_CXX}> - # C warnings - $<$:${PROJECT_WARNINGS_C}> - # Cuda warnings - $<$:${PROJECT_WARNINGS_CUDA}>) + target_compile_options( + ${project_name} + INTERFACE # C++ warnings + $<$:${PROJECT_WARNINGS_CXX}> + # C warnings + $<$:${PROJECT_WARNINGS_C}> + # Cuda warnings + $<$:${PROJECT_WARNINGS_CUDA}>) endfunction() diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index a1e3e9bb7..7c7c5d1e3 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -1,5 +1,6 @@ function(fiction_enable_coverage project_name) - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES + ".*Clang") target_compile_options(${project_name} INTERFACE --coverage -O0 -g) target_link_libraries(${project_name} INTERFACE --coverage) endif() diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake index 32fc261d0..7b30cfb47 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake @@ -1,189 +1,197 @@ -# - Find ThreadingBuildingBlocks include dirs and libraries -# Use this module by invoking find_package with the form: -# find_package(TBB -# [REQUIRED] # Fail with error if TBB is not found -# ) # -# Once done, this will define +# * Find ThreadingBuildingBlocks include dirs and libraries Use this module by +# invoking find_package with the form: find_package(TBB [REQUIRED] # Fail with +# error if TBB is not found ) # Once done, this will +# define # -# TBB_FOUND - system has TBB -# TBB_INCLUDE_DIRS - the TBB include directories -# TBB_LIBRARIES - TBB libraries to be lined, doesn't include malloc or -# malloc proxy -# TBB::tbb - imported target for the TBB library +# TBB_FOUND - system has TBB TBB_INCLUDE_DIRS - the TBB include directories +# TBB_LIBRARIES - TBB libraries to be lined, doesn't include malloc or malloc +# proxy TBB::tbb - imported target for the TBB library # -# TBB_VERSION_MAJOR - Major Product Version Number -# TBB_VERSION_MINOR - Minor Product Version Number -# TBB_INTERFACE_VERSION - Engineering Focused Version Number -# TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major interface version -# still supported. This uses the engineering -# focused interface version numbers. +# TBB_VERSION_MAJOR - Major Product Version Number TBB_VERSION_MINOR - Minor +# Product Version Number TBB_INTERFACE_VERSION - Engineering Focused Version +# Number TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major interface version +# still supported. This uses the engineering focused interface version numbers. # -# TBB_MALLOC_FOUND - system has TBB malloc library -# TBB_MALLOC_INCLUDE_DIRS - the TBB malloc include directories -# TBB_MALLOC_LIBRARIES - The TBB malloc libraries to be lined -# TBB::malloc - imported target for the TBB malloc library +# TBB_MALLOC_FOUND - system has TBB malloc library TBB_MALLOC_INCLUDE_DIRS - the +# TBB malloc include directories TBB_MALLOC_LIBRARIES - The TBB malloc libraries +# to be lined TBB::malloc - imported target for the TBB malloc library # -# TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library -# TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories -# TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined -# TBB::malloc_proxy - imported target for the TBB malloc proxy library -# -# -# This module reads hints about search locations from variables: -# ENV TBB_ARCH_PLATFORM - for eg. set it to "mic" for Xeon Phi builds -# ENV TBB_ROOT or just TBB_ROOT - root directory of tbb installation -# ENV TBB_BUILD_PREFIX - specifies the build prefix for user built tbb -# libraries. Should be specified with ENV TBB_ROOT -# and optionally... -# ENV TBB_BUILD_DIR - if build directory is different than ${TBB_ROOT}/build +# TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library +# TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories +# TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined +# TBB::malloc_proxy - imported target for the TBB malloc proxy library # +# This module reads hints about search locations from variables: ENV +# TBB_ARCH_PLATFORM - for eg. set it to "mic" for Xeon Phi builds ENV TBB_ROOT +# or just TBB_ROOT - root directory of tbb installation ENV TBB_BUILD_PREFIX - +# specifies the build prefix for user built tbb libraries. Should be specified +# with ENV TBB_ROOT and optionally... ENV TBB_BUILD_DIR - if build directory is +# different than ${TBB_ROOT}/build # # Modified by Robert Maynard from the original OGRE source # -#------------------------------------------------------------------- -# This file is part of the CMake build system for OGRE -# (Object-oriented Graphics Rendering Engine) -# For the latest info, see http://www.ogre3d.org/ +# ------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE (Object-oriented Graphics +# Rendering Engine) For the latest info, see http://www.ogre3d.org/ # -# The contents of this file are placed in the public domain. Feel -# free to make use of it in any way you like. -#------------------------------------------------------------------- +# The contents of this file are placed in the public domain. Feel free to make +# use of it in any way you like. +# ------------------------------------------------------------------- # -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# Copyright 2012 Rolf Eike Beer +# ============================================================================= +# Copyright 2010-2012 Kitware, Inc. Copyright 2012 Rolf Eike Beer +# # -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. +# Distributed under the OSI-approved BSD License (the "License"); see +# accompanying file Copyright.txt for details. # -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - - -#============================================================================= -# FindTBB helper functions and macros -#============================================================================= - -#==================================================== +# This software is distributed WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# License for more information. +# ============================================================================= +# (To distribute this file outside of CMake, substitute the full License text +# for the above reference.) + +# ============================================================================= +# FindTBB helper functions and macros +# ============================================================================= + +# ==================================================== # Fix the library path in case it is a linker script -#==================================================== +# ==================================================== function(tbb_extract_real_library library real_library) - if (NOT UNIX OR NOT EXISTS ${library}) - set(${real_library} "${library}" PARENT_SCOPE) - return() - endif () - - #Read in the first 4 bytes and see if they are the ELF magic number - set(_elf_magic "7f454c46") - file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX) - if (_hex_data STREQUAL _elf_magic) - #we have opened a elf binary so this is what - #we should link to - set(${real_library} "${library}" PARENT_SCOPE) - return() - endif () - - file(READ ${library} _data OFFSET 0 LIMIT 1024) - if ("${_data}" MATCHES "INPUT \\(([^(]+)\\)") - #extract out the .so name from REGEX MATCH command - set(_proper_so_name "${CMAKE_MATCH_1}") - - #construct path to the real .so which is presumed to be in the same directory - #as the input file - get_filename_component(_so_dir "${library}" DIRECTORY) - set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE) - else () - #unable to determine what this library is so just hope everything works - #and pass it unmodified. - set(${real_library} "${library}" PARENT_SCOPE) - endif () + if(NOT UNIX OR NOT EXISTS ${library}) + set(${real_library} + "${library}" + PARENT_SCOPE) + return() + endif() + + # Read in the first 4 bytes and see if they are the ELF magic number + set(_elf_magic "7f454c46") + file( + READ ${library} _hex_data + OFFSET 0 + LIMIT 4 + HEX) + if(_hex_data STREQUAL _elf_magic) + # we have opened a elf binary so this is what we should link to + set(${real_library} + "${library}" + PARENT_SCOPE) + return() + endif() + + file( + READ ${library} _data + OFFSET 0 + LIMIT 1024) + if("${_data}" MATCHES "INPUT \\(([^(]+)\\)") + # extract out the .so name from REGEX MATCH command + set(_proper_so_name "${CMAKE_MATCH_1}") + + # construct path to the real .so which is presumed to be in the same + # directory as the input file + get_filename_component(_so_dir "${library}" DIRECTORY) + set(${real_library} + "${_so_dir}/${_proper_so_name}" + PARENT_SCOPE) + else() + # unable to determine what this library is so just hope everything works and + # pass it unmodified. + set(${real_library} + "${library}" + PARENT_SCOPE) + endif() endfunction() -#=============================================== +# =============================================== # Do the final processing for the package find. -#=============================================== +# =============================================== macro(findpkg_finish PREFIX TARGET_NAME) - if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) - set(${PREFIX}_FOUND TRUE) - set(${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) - set(${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) - else () - if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY) - message(FATAL_ERROR "Required library ${PREFIX} not found.") - endif () - endif () - - if (NOT TARGET "TBB::${TARGET_NAME}") - if (${PREFIX}_LIBRARY_RELEASE) - tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release) - endif () - if (${PREFIX}_LIBRARY_DEBUG) - tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug) - endif () - add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED) - set_target_properties(TBB::${TARGET_NAME} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}") - if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE) - set_target_properties(TBB::${TARGET_NAME} PROPERTIES - IMPORTED_LOCATION "${real_release}" - IMPORTED_LOCATION_DEBUG "${real_debug}" - IMPORTED_LOCATION_RELEASE "${real_release}") - elseif (${PREFIX}_LIBRARY_RELEASE) - set_target_properties(TBB::${TARGET_NAME} PROPERTIES - IMPORTED_LOCATION "${real_release}") - elseif (${PREFIX}_LIBRARY_DEBUG) - set_target_properties(TBB::${TARGET_NAME} PROPERTIES - IMPORTED_LOCATION "${real_debug}") - endif () - endif () - - #mark the following variables as internal variables - mark_as_advanced(${PREFIX}_INCLUDE_DIR - ${PREFIX}_LIBRARY - ${PREFIX}_LIBRARY_DEBUG - ${PREFIX}_LIBRARY_RELEASE) + if(${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) + set(${PREFIX}_FOUND TRUE) + set(${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) + set(${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) + else() + if(${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY) + message(FATAL_ERROR "Required library ${PREFIX} not found.") + endif() + endif() + + if(NOT TARGET "TBB::${TARGET_NAME}") + if(${PREFIX}_LIBRARY_RELEASE) + tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release) + endif() + if(${PREFIX}_LIBRARY_DEBUG) + tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug) + endif() + add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED) + set_target_properties( + TBB::${TARGET_NAME} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${${PREFIX}_INCLUDE_DIR}") + if(${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE) + set_target_properties( + TBB::${TARGET_NAME} + PROPERTIES IMPORTED_LOCATION "${real_release}" + IMPORTED_LOCATION_DEBUG "${real_debug}" + IMPORTED_LOCATION_RELEASE "${real_release}") + elseif(${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES IMPORTED_LOCATION + "${real_release}") + elseif(${PREFIX}_LIBRARY_DEBUG) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES IMPORTED_LOCATION + "${real_debug}") + endif() + endif() + + # mark the following variables as internal variables + mark_as_advanced(${PREFIX}_INCLUDE_DIR ${PREFIX}_LIBRARY + ${PREFIX}_LIBRARY_DEBUG ${PREFIX}_LIBRARY_RELEASE) endmacro() -#=============================================== +# =============================================== # Generate debug names from given release names -#=============================================== +# =============================================== macro(get_debug_names PREFIX) - foreach (i ${${PREFIX}}) - set(${PREFIX}_DEBUG ${${PREFIX}_DEBUG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i}) - endforeach () + foreach(i ${${PREFIX}}) + set(${PREFIX}_DEBUG + ${${PREFIX}_DEBUG} + ${i}d + ${i}D + ${i}_d + ${i}_D + ${i}_debug + ${i}) + endforeach() endmacro() -#=============================================== +# =============================================== # See if we have env vars to help us find tbb -#=============================================== +# =============================================== macro(getenv_path VAR) - set(ENV_${VAR} $ENV{${VAR}}) - # replace won't work if var is blank - if (ENV_${VAR}) - string(REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}}) - endif () + set(ENV_${VAR} $ENV{${VAR}}) + # replace won't work if var is blank + if(ENV_${VAR}) + string(REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}}) + endif() endmacro() -#=============================================== +# =============================================== # Couple a set of release AND debug libraries -#=============================================== +# =============================================== macro(make_library_set PREFIX) - if (${PREFIX}_RELEASE AND ${PREFIX}_DEBUG) - set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG}) - elseif (${PREFIX}_RELEASE) - set(${PREFIX} ${${PREFIX}_RELEASE}) - elseif (${PREFIX}_DEBUG) - set(${PREFIX} ${${PREFIX}_DEBUG}) - endif () + if(${PREFIX}_RELEASE AND ${PREFIX}_DEBUG) + set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG}) + elseif(${PREFIX}_RELEASE) + set(${PREFIX} ${${PREFIX}_RELEASE}) + elseif(${PREFIX}_DEBUG) + set(${PREFIX} ${${PREFIX}_DEBUG}) + endif() endmacro() - -#============================================================================= -# Now to actually find TBB +# ============================================================================= +# Now to actually find TBB # # Get path, convert backslashes as ${ENV_${var}} @@ -194,237 +202,236 @@ set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT}) set(TBB_INC_SEARCH_PATH "") set(TBB_LIB_SEARCH_PATH "") - # If user built from sources set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX}) -if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT) - getenv_path(TBB_BUILD_DIR) - if (NOT ENV_TBB_BUILD_DIR) - set(ENV_TBB_BUILD_DIR ${ENV_TBB_ROOT}/build) - endif () - - # include directory under ${ENV_TBB_ROOT}/include - list(APPEND TBB_LIB_SEARCH_PATH - ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release - ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug) -endif () - - -# For Windows, let's assume that the user might be using the precompiled -# TBB packages from the main website. These use a rather awkward directory -# structure (at least for automatically finding the right files) depending -# on platform and compiler, but we'll do our best to accommodate it. -# Not adding the same effort for the precompiled linux builds, though. Those -# have different versions for CC compiler versions and linux kernels which -# will never adequately match the user's setup, so there is no feasible way -# to detect the "best" version to use. The user will have to manually -# select the right files. (Chances are the distributions are shipping their -# custom version of tbb, anyway, so the problem is probably nonexistent.) -if (WIN32 AND MSVC) - set(COMPILER_PREFIX "vc7.1") - if (MSVC_VERSION EQUAL 1400) - set(COMPILER_PREFIX "vc8") - elseif (MSVC_VERSION EQUAL 1500) - set(COMPILER_PREFIX "vc9") - elseif (MSVC_VERSION EQUAL 1600) - set(COMPILER_PREFIX "vc10") - elseif (MSVC_VERSION EQUAL 1700) - set(COMPILER_PREFIX "vc11") - elseif (MSVC_VERSION EQUAL 1800) - set(COMPILER_PREFIX "vc12") - elseif (MSVC_VERSION GREATER_EQUAL 1900) - set(COMPILER_PREFIX "vc14") - endif () - - # for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search path - foreach (dir IN LISTS TBB_PREFIX_PATH) - if (CMAKE_CL_64) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX}) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX}) - else () - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX}) - endif () - endforeach () -endif () - -# For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9) -# and above and AppleClang -if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND - NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0) - set(USE_LIBCXX OFF) - cmake_policy(GET CMP0025 POLICY_VAR) - - if (POLICY_VAR STREQUAL "NEW") - if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - set(USE_LIBCXX ON) - endif () - else () - if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(USE_LIBCXX ON) - endif () - endif () - - if (USE_LIBCXX) - foreach (dir IN LISTS TBB_PREFIX_PATH) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib) - endforeach () - endif () -endif () +if(TBB_BUILD_PREFIX AND ENV_TBB_ROOT) + getenv_path(TBB_BUILD_DIR) + if(NOT ENV_TBB_BUILD_DIR) + set(ENV_TBB_BUILD_DIR ${ENV_TBB_ROOT}/build) + endif() + + # include directory under ${ENV_TBB_ROOT}/include + list(APPEND TBB_LIB_SEARCH_PATH + ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release + ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug) +endif() + +# For Windows, let's assume that the user might be using the precompiled TBB +# packages from the main website. These use a rather awkward directory structure +# (at least for automatically finding the right files) depending on platform and +# compiler, but we'll do our best to accommodate it. Not adding the same effort +# for the precompiled linux builds, though. Those have different versions for CC +# compiler versions and linux kernels which will never adequately match the +# user's setup, so there is no feasible way to detect the "best" version to use. +# The user will have to manually select the right files. (Chances are the +# distributions are shipping their custom version of tbb, anyway, so the problem +# is probably nonexistent.) +if(WIN32 AND MSVC) + set(COMPILER_PREFIX "vc7.1") + if(MSVC_VERSION EQUAL 1400) + set(COMPILER_PREFIX "vc8") + elseif(MSVC_VERSION EQUAL 1500) + set(COMPILER_PREFIX "vc9") + elseif(MSVC_VERSION EQUAL 1600) + set(COMPILER_PREFIX "vc10") + elseif(MSVC_VERSION EQUAL 1700) + set(COMPILER_PREFIX "vc11") + elseif(MSVC_VERSION EQUAL 1800) + set(COMPILER_PREFIX "vc12") + elseif(MSVC_VERSION GREATER_EQUAL 1900) + set(COMPILER_PREFIX "vc14") + endif() + + # for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search + # path + foreach(dir IN LISTS TBB_PREFIX_PATH) + if(CMAKE_CL_64) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX}) + else() + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX}) + endif() + endforeach() +endif() + +# For OS X binary distribution, choose libc++ based libraries for Mavericks +# (10.9) and above and AppleClang +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_VERSION + VERSION_LESS 13.0) + set(USE_LIBCXX OFF) + cmake_policy(GET CMP0025 POLICY_VAR) + + if(POLICY_VAR STREQUAL "NEW") + if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(USE_LIBCXX ON) + endif() + else() + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(USE_LIBCXX ON) + endif() + endif() + + if(USE_LIBCXX) + foreach(dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib) + endforeach() + endif() +endif() # check compiler ABI -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(COMPILER_PREFIX) - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - list(APPEND COMPILER_PREFIX "gcc4.8") - endif () - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) - list(APPEND COMPILER_PREFIX "gcc4.7") - endif () - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) - list(APPEND COMPILER_PREFIX "gcc4.4") - endif () - list(APPEND COMPILER_PREFIX "gcc4.1") -elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(COMPILER_PREFIX) - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) # Complete guess - list(APPEND COMPILER_PREFIX "gcc4.8") - endif () - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6) - list(APPEND COMPILER_PREFIX "gcc4.7") - endif () - list(APPEND COMPILER_PREFIX "gcc4.4") -else () # Assume compatibility with 4.4 for other compilers +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(COMPILER_PREFIX) + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + list(APPEND COMPILER_PREFIX "gcc4.8") + endif() + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + list(APPEND COMPILER_PREFIX "gcc4.7") + endif() + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) list(APPEND COMPILER_PREFIX "gcc4.4") -endif () + endif() + list(APPEND COMPILER_PREFIX "gcc4.1") +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(COMPILER_PREFIX) + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) # Complete guess + list(APPEND COMPILER_PREFIX "gcc4.8") + endif() + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6) + list(APPEND COMPILER_PREFIX "gcc4.7") + endif() + list(APPEND COMPILER_PREFIX "gcc4.4") +else() # Assume compatibility with 4.4 for other compilers + list(APPEND COMPILER_PREFIX "gcc4.4") +endif() # if platform architecture is explicitly specified set(TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM}) -if (TBB_ARCH_PLATFORM) - foreach (dir IN LISTS TBB_PREFIX_PATH) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM}) - endforeach () -endif () - -foreach (dir IN LISTS TBB_PREFIX_PATH) - foreach (prefix IN LISTS COMPILER_PREFIX) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix}) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib) - else () - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix}) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib) - endif () - endforeach () -endforeach () +if(TBB_ARCH_PLATFORM) + foreach(dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM}) + endforeach() +endif() + +foreach(dir IN LISTS TBB_PREFIX_PATH) + foreach(prefix IN LISTS COMPILER_PREFIX) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib) + else() + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib) + endif() + endforeach() +endforeach() # add general search paths -foreach (dir IN LISTS TBB_PREFIX_PATH) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb - ${dir}/Libs) - list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include - ${dir}/include/tbb) -endforeach () +foreach(dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb + ${dir}/Libs) + list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include + ${dir}/include/tbb) +endforeach() set(TBB_LIBRARY_NAMES tbb) get_debug_names(TBB_LIBRARY_NAMES) - -find_path(TBB_INCLUDE_DIR - NAMES tbb/tbb.h - PATHS ${TBB_INC_SEARCH_PATH}) - -find_library(TBB_LIBRARY_RELEASE - NAMES ${TBB_LIBRARY_NAMES} - PATHS ${TBB_LIB_SEARCH_PATH}) -find_library(TBB_LIBRARY_DEBUG - NAMES ${TBB_LIBRARY_NAMES_DEBUG} - PATHS ${TBB_LIB_SEARCH_PATH}) +find_path( + TBB_INCLUDE_DIR + NAMES tbb/tbb.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library( + TBB_LIBRARY_RELEASE + NAMES ${TBB_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library( + TBB_LIBRARY_DEBUG + NAMES ${TBB_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) make_library_set(TBB_LIBRARY) findpkg_finish(TBB tbb) -#if we haven't found TBB no point on going any further -if (NOT TBB_FOUND) - return() -endif () +# if we haven't found TBB no point on going any further +if(NOT TBB_FOUND) + return() +endif() -#============================================================================= +# ============================================================================= # Look for TBB's malloc package set(TBB_MALLOC_LIBRARY_NAMES tbbmalloc) get_debug_names(TBB_MALLOC_LIBRARY_NAMES) -find_path(TBB_MALLOC_INCLUDE_DIR - NAMES tbb/tbb.h - PATHS ${TBB_INC_SEARCH_PATH}) - -find_library(TBB_MALLOC_LIBRARY_RELEASE - NAMES ${TBB_MALLOC_LIBRARY_NAMES} - PATHS ${TBB_LIB_SEARCH_PATH}) -find_library(TBB_MALLOC_LIBRARY_DEBUG - NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG} - PATHS ${TBB_LIB_SEARCH_PATH}) +find_path( + TBB_MALLOC_INCLUDE_DIR + NAMES tbb/tbb.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library( + TBB_MALLOC_LIBRARY_RELEASE + NAMES ${TBB_MALLOC_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library( + TBB_MALLOC_LIBRARY_DEBUG + NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) make_library_set(TBB_MALLOC_LIBRARY) findpkg_finish(TBB_MALLOC tbbmalloc) -#============================================================================= +# ============================================================================= # Look for TBB's malloc proxy package set(TBB_MALLOC_PROXY_LIBRARY_NAMES tbbmalloc_proxy) get_debug_names(TBB_MALLOC_PROXY_LIBRARY_NAMES) -find_path(TBB_MALLOC_PROXY_INCLUDE_DIR - NAMES tbb/tbbmalloc_proxy.h - PATHS ${TBB_INC_SEARCH_PATH}) - -find_library(TBB_MALLOC_PROXY_LIBRARY_RELEASE - NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES} - PATHS ${TBB_LIB_SEARCH_PATH}) -find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG - NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG} - PATHS ${TBB_LIB_SEARCH_PATH}) +find_path( + TBB_MALLOC_PROXY_INCLUDE_DIR + NAMES tbb/tbbmalloc_proxy.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library( + TBB_MALLOC_PROXY_LIBRARY_RELEASE + NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library( + TBB_MALLOC_PROXY_LIBRARY_DEBUG + NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) make_library_set(TBB_MALLOC_PROXY_LIBRARY) findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy) +# ============================================================================= +# parse all the version numbers from tbb +if(NOT TBB_VERSION) + if(EXISTS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h") + file(STRINGS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h" TBB_VERSION_CONTENTS + REGEX "VERSION") + else() + # only read the start of the file + file(STRINGS "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h" TBB_VERSION_CONTENTS + REGEX "VERSION") + endif() + + string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" + TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" + TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") + + string(REGEX + REPLACE ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") -#============================================================================= -#parse all the version numbers from tbb -if (NOT TBB_VERSION) - if (EXISTS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h") - file(STRINGS - "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h" - TBB_VERSION_CONTENTS - REGEX "VERSION") - else () - #only read the start of the file - file(STRINGS - "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h" - TBB_VERSION_CONTENTS - REGEX "VERSION") - endif () - - string(REGEX REPLACE - ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" - TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}") - - string(REGEX REPLACE - ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" - TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}") - - string(REGEX REPLACE - ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" - TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") - - string(REGEX REPLACE - ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1" - TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") - -endif () +endif() diff --git a/cmake/FindZ3.cmake b/cmake/FindZ3.cmake index a85b26614..3f2e66561 100644 --- a/cmake/FindZ3.cmake +++ b/cmake/FindZ3.cmake @@ -6,168 +6,177 @@ include(FindPackageHandleStandardArgs) # Function to check Z3's version function(check_z3_version z3_include z3_lib) - if (z3_include AND EXISTS "${z3_include}/z3_version.h") - file(STRINGS "${z3_include}/z3_version.h" z3_version_str - REGEX "^#define[\t ]+Z3_MAJOR_VERSION[\t ]+.*") - string(REGEX REPLACE "^.*Z3_MAJOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MAJOR "${z3_version_str}") - - file(STRINGS "${z3_include}/z3_version.h" z3_version_str - REGEX "^#define[\t ]+Z3_MINOR_VERSION[\t ]+.*") - string(REGEX REPLACE "^.*Z3_MINOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MINOR "${z3_version_str}") - - file(STRINGS "${z3_include}/z3_version.h" z3_version_str - REGEX "^#define[\t ]+Z3_BUILD_NUMBER[\t ]+.*") - string(REGEX REPLACE "^.*Z3_BUILD_NUMBER[\t ]+([0-9]*).*$" "\\1" Z3_BUILD "${z3_version_str}") - - set(z3_version_string ${Z3_MAJOR}.${Z3_MINOR}.${Z3_BUILD}) - endif () - - if (NOT z3_version_string) - message(STATUS "Could not determine Z3 version") - return() - endif () - - find_package_check_version(${z3_version_string} suitable_version RESULT_MESSAGE_VARIABLE reason) - - if (suitable_version) - set(FOUND_SUITABLE_VERSION - TRUE - PARENT_SCOPE) - set(Z3_VERSION_STRING - ${z3_version_string} - PARENT_SCOPE) - else () - message(STATUS "${reason}") - endif () + if(z3_include AND EXISTS "${z3_include}/z3_version.h") + file(STRINGS "${z3_include}/z3_version.h" z3_version_str + REGEX "^#define[\t ]+Z3_MAJOR_VERSION[\t ]+.*") + string(REGEX REPLACE "^.*Z3_MAJOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MAJOR + "${z3_version_str}") + + file(STRINGS "${z3_include}/z3_version.h" z3_version_str + REGEX "^#define[\t ]+Z3_MINOR_VERSION[\t ]+.*") + string(REGEX REPLACE "^.*Z3_MINOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MINOR + "${z3_version_str}") + + file(STRINGS "${z3_include}/z3_version.h" z3_version_str + REGEX "^#define[\t ]+Z3_BUILD_NUMBER[\t ]+.*") + string(REGEX REPLACE "^.*Z3_BUILD_NUMBER[\t ]+([0-9]*).*$" "\\1" Z3_BUILD + "${z3_version_str}") + + set(z3_version_string ${Z3_MAJOR}.${Z3_MINOR}.${Z3_BUILD}) + endif() + + if(NOT z3_version_string) + message(STATUS "Could not determine Z3 version") + return() + endif() + + find_package_check_version(${z3_version_string} suitable_version + RESULT_MESSAGE_VARIABLE reason) + + if(suitable_version) + set(FOUND_SUITABLE_VERSION + TRUE + PARENT_SCOPE) + set(Z3_VERSION_STRING + ${z3_version_string} + PARENT_SCOPE) + else() + message(STATUS "${reason}") + endif() endfunction(check_z3_version) set(Z3_ROOT - "" - CACHE PATH "Root of Z3 distribution.") -if (DEFINED ENV{Z3_ROOT}) - set(Z3_ROOT $ENV{Z3_ROOT}) - message(STATUS "Z3_ROOT from environment: ${Z3_ROOT}") -endif () + "" + CACHE PATH "Root of Z3 distribution.") +if(DEFINED ENV{Z3_ROOT}) + set(Z3_ROOT $ENV{Z3_ROOT}) + message(STATUS "Z3_ROOT from environment: ${Z3_ROOT}") +endif() # if Z3_ROOT is provided, check there first -if (NOT ${Z3_ROOT} STREQUAL "") - find_path( - Z3_CXX_INCLUDE_DIRS - NAMES z3.h z3++.h - NO_DEFAULT_PATH - PATHS ${Z3_ROOT}/include - PATH_SUFFIXES libz3 z3) - - find_library( - Z3_LIBRARIES - NAMES z3 libz3 - NO_DEFAULT_PATH - PATHS ${Z3_ROOT} - PATH_SUFFIXES lib bin) - - if (Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) - message(STATUS "Z3_ROOT provided and includes and libraries found.") - message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") - message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") - check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) - endif () -endif () +if(NOT ${Z3_ROOT} STREQUAL "") + find_path( + Z3_CXX_INCLUDE_DIRS + NAMES z3.h z3++.h + NO_DEFAULT_PATH + PATHS ${Z3_ROOT}/include + PATH_SUFFIXES libz3 z3) + + find_library( + Z3_LIBRARIES + NAMES z3 libz3 + NO_DEFAULT_PATH + PATHS ${Z3_ROOT} + PATH_SUFFIXES lib bin) + + if(Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) + message(STATUS "Z3_ROOT provided and includes and libraries found.") + message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") + message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") + check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) + endif() +endif() # see if a config file is available -if (NOT FOUND_SUITABLE_VERSION) - unset(Z3_CXX_INCLUDE_DIRS CACHE) - unset(Z3_LIBRARIES CACHE) - - find_package(Z3 CONFIG QUIET) - if (Z3_FOUND) - message(STATUS "Found Z3 includes and libraries from config file") - message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") - message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") - check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) - endif () -endif () +if(NOT FOUND_SUITABLE_VERSION) + unset(Z3_CXX_INCLUDE_DIRS CACHE) + unset(Z3_LIBRARIES CACHE) + + find_package(Z3 CONFIG QUIET) + if(Z3_FOUND) + message(STATUS "Found Z3 includes and libraries from config file") + message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") + message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") + check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) + endif() +endif() # if Z3 has not been found yet, look in the system paths -if (NOT FOUND_SUITABLE_VERSION) - unset(Z3_CXX_INCLUDE_DIRS CACHE) - unset(Z3_LIBRARIES CACHE) - - find_path( - Z3_CXX_INCLUDE_DIRS - NAMES z3.h z3++.h - PATH_SUFFIXES libz3 z3) - find_library( - Z3_LIBRARIES - NAMES z3 libz3 - PATH_SUFFIXES lib bin) - - if (Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) - message(STATUS "Found Z3 includes and libraries in system paths.") +if(NOT FOUND_SUITABLE_VERSION) + unset(Z3_CXX_INCLUDE_DIRS CACHE) + unset(Z3_LIBRARIES CACHE) + + find_path( + Z3_CXX_INCLUDE_DIRS + NAMES z3.h z3++.h + PATH_SUFFIXES libz3 z3) + find_library( + Z3_LIBRARIES + NAMES z3 libz3 + PATH_SUFFIXES lib bin) + + if(Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) + message(STATUS "Found Z3 includes and libraries in system paths.") + message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") + message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") + check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) + endif() +endif() + +# if it is still not found, try to find it with Python as a last resort +if(NOT FOUND_SUITABLE_VERSION) + unset(Z3_CXX_INCLUDE_DIRS CACHE) + unset(Z3_LIBRARIES CACHE) + + set(PYTHON_FIND_VIRTUALENV FIRST) + find_package(Python COMPONENTS Interpreter Development.Module) + if(Python_FOUND) + execute_process( + COMMAND ${Python_EXECUTABLE} -c + "import os, z3; print(os.path.dirname(z3.__file__))" + OUTPUT_VARIABLE Z3_PYTHON_ROOT) + string(STRIP ${Z3_PYTHON_ROOT} Z3_PYTHON_ROOT) + message(STATUS "Z3_PYTHON_ROOT: ${Z3_PYTHON_ROOT}") + + if(Z3_PYTHON_ROOT) + find_path( + Z3_CXX_INCLUDE_DIRS + NAMES z3.h z3++.h + NO_DEFAULT_PATH + PATHS ${Z3_PYTHON_ROOT} + PATH_SUFFIXES libz3 z3 include) + + find_library( + Z3_LIBRARIES + NAMES z3 libz3 + NO_DEFAULT_PATH + PATHS ${Z3_PYTHON_ROOT} + PATH_SUFFIXES lib bin) + + if(Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) + message( + STATUS "Found Z3 includes and libraries from Python installation.") message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) - endif () -endif () - -# if it is still not found, try to find it with Python as a last resort -if (NOT FOUND_SUITABLE_VERSION) - unset(Z3_CXX_INCLUDE_DIRS CACHE) - unset(Z3_LIBRARIES CACHE) - - set(PYTHON_FIND_VIRTUALENV FIRST) - find_package(Python COMPONENTS Interpreter Development.Module) - if (Python_FOUND) - execute_process( - COMMAND ${Python_EXECUTABLE} -c "import os, z3; print(os.path.dirname(z3.__file__))" - OUTPUT_VARIABLE Z3_PYTHON_ROOT) - string(STRIP ${Z3_PYTHON_ROOT} Z3_PYTHON_ROOT) - message(STATUS "Z3_PYTHON_ROOT: ${Z3_PYTHON_ROOT}") - - if (Z3_PYTHON_ROOT) - find_path( - Z3_CXX_INCLUDE_DIRS - NAMES z3.h z3++.h - NO_DEFAULT_PATH - PATHS ${Z3_PYTHON_ROOT} - PATH_SUFFIXES libz3 z3 include) - - find_library( - Z3_LIBRARIES - NAMES z3 libz3 - NO_DEFAULT_PATH - PATHS ${Z3_PYTHON_ROOT} - PATH_SUFFIXES lib bin) - - if (Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) - message(STATUS "Found Z3 includes and libraries from Python installation.") - message(VERBOSE "Z3_CXX_INCLUDE_DIRS: ${Z3_CXX_INCLUDE_DIRS}") - message(VERBOSE "Z3_LIBRARIES: ${Z3_LIBRARIES}") - check_z3_version(${Z3_CXX_INCLUDE_DIRS} ${Z3_LIBRARIES}) - endif () - endif () - endif () -endif () - -if (NOT FOUND_SUITABLE_VERSION) - if (Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) - message(STATUS "Found include and library directories but could not find a suitable Z3 version") - endif () - set(Z3_VERSION_STRING "0.0.0") -endif () + endif() + endif() + endif() +endif() + +if(NOT FOUND_SUITABLE_VERSION) + if(Z3_CXX_INCLUDE_DIRS AND Z3_LIBRARIES) + message( + STATUS + "Found include and library directories but could not find a suitable Z3 version" + ) + endif() + set(Z3_VERSION_STRING "0.0.0") +endif() find_package_handle_standard_args( - Z3 - REQUIRED_VARS Z3_LIBRARIES Z3_CXX_INCLUDE_DIRS - VERSION_VAR Z3_VERSION_STRING) - -if (Z3_FOUND) - if (NOT TARGET z3::z3lib) - add_library(z3::z3lib INTERFACE IMPORTED GLOBAL) - target_include_directories(z3::z3lib INTERFACE ${Z3_CXX_INCLUDE_DIRS}) - target_link_libraries(z3::z3lib INTERFACE ${Z3_LIBRARIES}) - endif () - add_compile_definitions(Z3_FOUND) -endif () + Z3 + REQUIRED_VARS Z3_LIBRARIES Z3_CXX_INCLUDE_DIRS + VERSION_VAR Z3_VERSION_STRING) + +if(Z3_FOUND) + if(NOT TARGET z3::z3lib) + add_library(z3::z3lib INTERFACE IMPORTED GLOBAL) + target_include_directories(z3::z3lib INTERFACE ${Z3_CXX_INCLUDE_DIRS}) + target_link_libraries(z3::z3lib INTERFACE ${Z3_LIBRARIES}) + endif() + add_compile_definitions(Z3_FOUND) +endif() mark_as_advanced(Z3_CXX_INCLUDE_DIRS Z3_LIBRARIES Z3_VERSION_STRING) diff --git a/cmake/Hardening.cmake b/cmake/Hardening.cmake index 5b88f9304..95fffdd1a 100644 --- a/cmake/Hardening.cmake +++ b/cmake/Hardening.cmake @@ -1,98 +1,112 @@ include(CheckCXXCompilerFlag) -macro( - fiction_enable_hardening - target - global - ubsan_minimal_runtime) +macro(fiction_enable_hardening target global ubsan_minimal_runtime) - message(STATUS "** Enabling Hardening (Target ${target}) **") + message(STATUS "** Enabling Hardening (Target ${target}) **") - if (MSVC) - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} /sdl /DYNAMICBASE /guard:cf") - message(STATUS "*** MSVC flags: /sdl /DYNAMICBASE /guard:cf /NXCOMPAT /CETCOMPAT") - set(NEW_LINK_OPTIONS "${NEW_LINK_OPTIONS} /NXCOMPAT /CETCOMPAT") + if(MSVC) + set(NEW_COMPILE_OPTIONS + "${NEW_COMPILE_OPTIONS} /sdl /DYNAMICBASE /guard:cf") + message( + STATUS "*** MSVC flags: /sdl /DYNAMICBASE /guard:cf /NXCOMPAT /CETCOMPAT") + set(NEW_LINK_OPTIONS "${NEW_LINK_OPTIONS} /NXCOMPAT /CETCOMPAT") - elseif (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang|GNU") - set(NEW_CXX_DEFINITIONS "${NEW_CXX_DEFINITIONS} -D_GLIBCXX_ASSERTIONS") - message(STATUS "*** GLIBC++ Assertions (vector[], string[], ...) enabled") + elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang|GNU") + set(NEW_CXX_DEFINITIONS "${NEW_CXX_DEFINITIONS} -D_GLIBCXX_ASSERTIONS") + message(STATUS "*** GLIBC++ Assertions (vector[], string[], ...) enabled") - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3") - message(STATUS "*** g++/clang _FORTIFY_SOURCE=3 enabled") + set(NEW_COMPILE_OPTIONS + "${NEW_COMPILE_OPTIONS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3") + message(STATUS "*** g++/clang _FORTIFY_SOURCE=3 enabled") - # check_cxx_compiler_flag(-fpie PIE) - #if(PIE) - # set(NEW_COMPILE_OPTIONS ${NEW_COMPILE_OPTIONS} -fpie) - # set(NEW_LINK_OPTIONS ${NEW_LINK_OPTIONS} -pie) - # - # message(STATUS "*** g++/clang PIE mode enabled") - #else() - # message(STATUS "*** g++/clang PIE mode NOT enabled (not supported)") - #endif() + # check_cxx_compiler_flag(-fpie PIE) if(PIE) set(NEW_COMPILE_OPTIONS + # ${NEW_COMPILE_OPTIONS} -fpie) set(NEW_LINK_OPTIONS ${NEW_LINK_OPTIONS} + # -pie) + # + # message(STATUS "*** g++/clang PIE mode enabled") else() message(STATUS + # "*** g++/clang PIE mode NOT enabled (not supported)") endif() - check_cxx_compiler_flag(-fstack-protector-strong STACK_PROTECTOR) - if (STACK_PROTECTOR) - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fstack-protector-strong") - message(STATUS "*** g++/clang -fstack-protector-strong enabled") - else () - message(STATUS "*** g++/clang -fstack-protector-strong NOT enabled (not supported)") - endif () + check_cxx_compiler_flag(-fstack-protector-strong STACK_PROTECTOR) + if(STACK_PROTECTOR) + set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fstack-protector-strong") + message(STATUS "*** g++/clang -fstack-protector-strong enabled") + else() + message( + STATUS + "*** g++/clang -fstack-protector-strong NOT enabled (not supported)") + endif() - check_cxx_compiler_flag(-fcf-protection CF_PROTECTION) - if (CF_PROTECTION) - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fcf-protection") - message(STATUS "*** g++/clang -fcf-protection enabled") - else () - message(STATUS "*** g++/clang -fcf-protection NOT enabled (not supported)") - endif () + check_cxx_compiler_flag(-fcf-protection CF_PROTECTION) + if(CF_PROTECTION) + set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fcf-protection") + message(STATUS "*** g++/clang -fcf-protection enabled") + else() + message( + STATUS "*** g++/clang -fcf-protection NOT enabled (not supported)") + endif() - check_cxx_compiler_flag(-fstack-clash-protection CLASH_PROTECTION) - if (CLASH_PROTECTION) - if (LINUX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fstack-clash-protection") - message(STATUS "*** g++/clang -fstack-clash-protection enabled") - else () - message(STATUS "*** g++/clang -fstack-clash-protection NOT enabled (clang on non-Linux)") - endif () - else () - message(STATUS "*** g++/clang -fstack-clash-protection NOT enabled (not supported)") - endif () - endif () + check_cxx_compiler_flag(-fstack-clash-protection CLASH_PROTECTION) + if(CLASH_PROTECTION) + if(LINUX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(NEW_COMPILE_OPTIONS + "${NEW_COMPILE_OPTIONS} -fstack-clash-protection") + message(STATUS "*** g++/clang -fstack-clash-protection enabled") + else() + message( + STATUS + "*** g++/clang -fstack-clash-protection NOT enabled (clang on non-Linux)" + ) + endif() + else() + message( + STATUS + "*** g++/clang -fstack-clash-protection NOT enabled (not supported)") + endif() + endif() - if (${ubsan_minimal_runtime}) - check_cxx_compiler_flag("-fsanitize=undefined -fno-sanitize-recover=undefined -fsanitize-minimal-runtime" - MINIMAL_RUNTIME) - if (MINIMAL_RUNTIME) - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fsanitize=undefined -fsanitize-minimal-runtime") - set(NEW_LINK_OPTIONS "${NEW_LINK_OPTIONS} -fsanitize=undefined -fsanitize-minimal-runtime") + if(${ubsan_minimal_runtime}) + check_cxx_compiler_flag( + "-fsanitize=undefined -fno-sanitize-recover=undefined -fsanitize-minimal-runtime" + MINIMAL_RUNTIME) + if(MINIMAL_RUNTIME) + set(NEW_COMPILE_OPTIONS + "${NEW_COMPILE_OPTIONS} -fsanitize=undefined -fsanitize-minimal-runtime" + ) + set(NEW_LINK_OPTIONS + "${NEW_LINK_OPTIONS} -fsanitize=undefined -fsanitize-minimal-runtime") - if (NOT ${global}) - set(NEW_COMPILE_OPTIONS "${NEW_COMPILE_OPTIONS} -fno-sanitize-recover=undefined") - set(NEW_LINK_OPTIONS "${NEW_LINK_OPTIONS} -fno-sanitize-recover=undefined") - else () - message(STATUS "** not enabling -fno-sanitize-recover=undefined for global consumption") - endif () + if(NOT ${global}) + set(NEW_COMPILE_OPTIONS + "${NEW_COMPILE_OPTIONS} -fno-sanitize-recover=undefined") + set(NEW_LINK_OPTIONS + "${NEW_LINK_OPTIONS} -fno-sanitize-recover=undefined") + else() + message( + STATUS + "** not enabling -fno-sanitize-recover=undefined for global consumption" + ) + endif() - message(STATUS "*** ubsan minimal runtime enabled") - else () - message(STATUS "*** ubsan minimal runtime NOT enabled (not supported)") - endif () - else () - message(STATUS "*** ubsan minimal runtime NOT enabled (not requested)") - endif () + message(STATUS "*** ubsan minimal runtime enabled") + else() + message(STATUS "*** ubsan minimal runtime NOT enabled (not supported)") + endif() + else() + message(STATUS "*** ubsan minimal runtime NOT enabled (not requested)") + endif() - message(STATUS "** Hardening Compiler Flags: ${NEW_COMPILE_OPTIONS}") - message(STATUS "** Hardening Linker Flags: ${NEW_LINK_OPTIONS}") - message(STATUS "** Hardening Compiler Defines: ${NEW_CXX_DEFINITIONS}") + message(STATUS "** Hardening Compiler Flags: ${NEW_COMPILE_OPTIONS}") + message(STATUS "** Hardening Linker Flags: ${NEW_LINK_OPTIONS}") + message(STATUS "** Hardening Compiler Defines: ${NEW_CXX_DEFINITIONS}") - if (${global}) - message(STATUS "** Setting hardening options globally for all dependencies") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NEW_COMPILE_OPTIONS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${NEW_LINK_OPTIONS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NEW_CXX_DEFINITIONS}") - else () - target_compile_options(${target} INTERFACE ${NEW_COMPILE_OPTIONS}) - target_link_options(${target} INTERFACE ${NEW_LINK_OPTIONS}) - target_compile_definitions(${target} INTERFACE ${NEW_CXX_DEFINITIONS}) - endif () + if(${global}) + message(STATUS "** Setting hardening options globally for all dependencies") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NEW_COMPILE_OPTIONS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${NEW_LINK_OPTIONS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NEW_CXX_DEFINITIONS}") + else() + target_compile_options(${target} INTERFACE ${NEW_COMPILE_OPTIONS}) + target_link_options(${target} INTERFACE ${NEW_LINK_OPTIONS}) + target_compile_definitions(${target} INTERFACE ${NEW_CXX_DEFINITIONS}) + endif() endmacro() diff --git a/cmake/InterproceduralOptimization.cmake b/cmake/InterproceduralOptimization.cmake index c1da69f77..9f081fceb 100644 --- a/cmake/InterproceduralOptimization.cmake +++ b/cmake/InterproceduralOptimization.cmake @@ -1,9 +1,9 @@ macro(fiction_enable_ipo) - include(CheckIPOSupported) - check_ipo_supported(RESULT result OUTPUT output) - if (result) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) - else () - message(SEND_ERROR "IPO is not supported: ${output}") - endif () + include(CheckIPOSupported) + check_ipo_supported(RESULT result OUTPUT output) + if(result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) + else() + message(SEND_ERROR "IPO is not supported: ${output}") + endif() endmacro() diff --git a/cmake/PackageProject.cmake b/cmake/PackageProject.cmake index 4cb21a889..6179d9005 100644 --- a/cmake/PackageProject.cmake +++ b/cmake/PackageProject.cmake @@ -1,199 +1,210 @@ -# Uses ycm (permissive BSD-3-Clause license) and ForwardArguments (permissive MIT license) +# Uses ycm (permissive BSD-3-Clause license) and ForwardArguments (permissive +# MIT license) function(fiction_package_project) - # if CMake version >= 3.18 - if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18") - cmake_policy(SET CMP0103 NEW) # disallow multiple calls with the same NAME - endif () - - # if CMake version >= 3.23 - if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.23") - cmake_policy(SET CMP0135 NEW) # enable new timestamp checking behavior for fetching content - endif () - - set(_options ARCH_INDEPENDENT # default to false + # if CMake version >= 3.18 + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18") + cmake_policy(SET CMP0103 NEW) # disallow multiple calls with the same NAME + endif() + + # if CMake version >= 3.23 + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.23") + cmake_policy(SET CMP0135 NEW) # enable new timestamp checking behavior for + # fetching content + endif() + + set(_options ARCH_INDEPENDENT # default to false + ) + set(_oneValueArgs + # default to the project_name: + NAME + COMPONENT + # default to project version: + VERSION + # default to semver + COMPATIBILITY + # default to ${CMAKE_BINARY_DIR} + CONFIG_EXPORT_DESTINATION + # default to ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/${NAME} + # suitable for vcpkg, etc. + CONFIG_INSTALL_DESTINATION) + set(_multiValueArgs + # recursively found for the current folder if not specified + TARGETS + # a list of public/interface include directories or files + PUBLIC_INCLUDES + # the names of the INTERFACE/PUBLIC dependencies that are found using + # `CONFIG` + PUBLIC_DEPENDENCIES_CONFIGURED + # the INTERFACE/PUBLIC dependencies that are found by any means using + # `find_dependency`. the arguments must be specified within double quotes + # (e.g. " 1.0.0 EXACT" or " CONFIG"). + PUBLIC_DEPENDENCIES + # the names of the PRIVATE dependencies that are found using `CONFIG`. + # Only included when BUILD_SHARED_LIBS is OFF. + PRIVATE_DEPENDENCIES_CONFIGURED + # PRIVATE dependencies that are only included when BUILD_SHARED_LIBS is + # OFF + PRIVATE_DEPENDENCIES) + + cmake_parse_arguments(_PackageProject "${_options}" "${_oneValueArgs}" + "${_multiValueArgs}" "${ARGN}") + + # Set default options + include(GNUInstallDirs) # Define GNU standard installation directories such as + # CMAKE_INSTALL_DATADIR + + # set default packaged targets + if(NOT _PackageProject_TARGETS) + get_all_installable_targets(_PackageProject_TARGETS) + message( + STATUS + "package_project: considering ${_PackageProject_TARGETS} as the exported targets" ) - set(_oneValueArgs - # default to the project_name: - NAME - COMPONENT - # default to project version: - VERSION - # default to semver - COMPATIBILITY - # default to ${CMAKE_BINARY_DIR} - CONFIG_EXPORT_DESTINATION - # default to ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/${NAME} suitable for vcpkg, etc. - CONFIG_INSTALL_DESTINATION) - set(_multiValueArgs - # recursively found for the current folder if not specified - TARGETS - # a list of public/interface include directories or files - PUBLIC_INCLUDES - # the names of the INTERFACE/PUBLIC dependencies that are found using `CONFIG` - PUBLIC_DEPENDENCIES_CONFIGURED - # the INTERFACE/PUBLIC dependencies that are found by any means using `find_dependency`. - # the arguments must be specified within double quotes (e.g. " 1.0.0 EXACT" or " CONFIG"). - PUBLIC_DEPENDENCIES - # the names of the PRIVATE dependencies that are found using `CONFIG`. Only included when BUILD_SHARED_LIBS is OFF. - PRIVATE_DEPENDENCIES_CONFIGURED - # PRIVATE dependencies that are only included when BUILD_SHARED_LIBS is OFF - PRIVATE_DEPENDENCIES) - - cmake_parse_arguments( - _PackageProject - "${_options}" - "${_oneValueArgs}" - "${_multiValueArgs}" - "${ARGN}") - - # Set default options - include(GNUInstallDirs) # Define GNU standard installation directories such as CMAKE_INSTALL_DATADIR - - # set default packaged targets - if (NOT _PackageProject_TARGETS) - get_all_installable_targets(_PackageProject_TARGETS) - message(STATUS "package_project: considering ${_PackageProject_TARGETS} as the exported targets") - endif () - - # default to the name of the project or the given name - if ("${_PackageProject_NAME}" STREQUAL "") - set(_PackageProject_NAME ${PROJECT_NAME}) - endif () - # ycm args - set(_PackageProject_NAMESPACE "${_PackageProject_NAME}::") - set(_PackageProject_VARS_PREFIX ${_PackageProject_NAME}) - set(_PackageProject_EXPORT ${_PackageProject_NAME}) - - # default version to the project version - if ("${_PackageProject_VERSION}" STREQUAL "") - set(_PackageProject_VERSION ${PROJECT_VERSION}) - endif () - - # default compatibility to SameMajorVersion - if ("${_PackageProject_COMPATIBILITY}" STREQUAL "") - set(_PackageProject_COMPATIBILITY "SameMajorVersion") - endif () - - # default to the build directory - if ("${_PackageProject_CONFIG_EXPORT_DESTINATION}" STREQUAL "") - set(_PackageProject_CONFIG_EXPORT_DESTINATION "${CMAKE_BINARY_DIR}") - endif () - set(_PackageProject_EXPORT_DESTINATION "${_PackageProject_CONFIG_EXPORT_DESTINATION}") - - # use datadir (works better with vcpkg, etc) - if ("${_PackageProject_CONFIG_INSTALL_DESTINATION}" STREQUAL "") - set(_PackageProject_CONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/${_PackageProject_NAME}") - endif () - # ycm args - set(_PackageProject_INSTALL_DESTINATION "${_PackageProject_CONFIG_INSTALL_DESTINATION}") - - # Installation of the public/interface includes - if (NOT - "${_PackageProject_PUBLIC_INCLUDES}" - STREQUAL - "") - foreach (_INC ${_PackageProject_PUBLIC_INCLUDES}) - # make include absolute - if (NOT IS_ABSOLUTE ${_INC}) - set(_INC "${CMAKE_CURRENT_SOURCE_DIR}/${_INC}") - endif () - # install include - if (IS_DIRECTORY ${_INC}) - # the include directories are directly installed to the install destination. If you want an `include` folder in the install destination, name your include directory as `include` (or install it manually using `install()` command). - install(DIRECTORY ${_INC} DESTINATION "./") - else () - install(FILES ${_INC} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") - endif () - endforeach () - endif () - - # Append the configured public dependencies - if (NOT - "${_PackageProject_PUBLIC_DEPENDENCIES_CONFIGURED}" - STREQUAL - "") - set(_PUBLIC_DEPENDENCIES_CONFIG) - foreach (DEP ${_PackageProject_PUBLIC_DEPENDENCIES_CONFIGURED}) - list(APPEND _PUBLIC_DEPENDENCIES_CONFIG "${DEP} CONFIG") - endforeach () - endif () - list(APPEND _PackageProject_PUBLIC_DEPENDENCIES ${_PUBLIC_DEPENDENCIES_CONFIG}) - # ycm arg - set(_PackageProject_DEPENDENCIES ${_PackageProject_PUBLIC_DEPENDENCIES}) - - # Append the configured private dependencies - if (NOT - "${_PackageProject_PRIVATE_DEPENDENCIES_CONFIGURED}" - STREQUAL - "") - set(_PRIVATE_DEPENDENCIES_CONFIG) - foreach (DEP ${_PackageProject_PRIVATE_DEPENDENCIES_CONFIGURED}) - list(APPEND _PRIVATE_DEPENDENCIES_CONFIG "${DEP} CONFIG") - endforeach () - endif () - # ycm arg - list(APPEND _PackageProject_PRIVATE_DEPENDENCIES ${_PRIVATE_DEPENDENCIES_CONFIG}) - - # Installation of package (compatible with vcpkg, etc) - install( - TARGETS ${_PackageProject_TARGETS} - EXPORT ${_PackageProject_EXPORT} - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_PackageProject_NAME}" COMPONENT dev) - - # install the usage file - set(_targets_str "") - foreach (_target ${_PackageProject_TARGETS}) - set(_targets_str "${_targets_str} ${_PackageProject_NAMESPACE}${_target}") - endforeach () - set(USAGE_FILE_CONTENT - "The package ${_PackageProject_NAME} provides CMake targets: + endif() + + # default to the name of the project or the given name + if("${_PackageProject_NAME}" STREQUAL "") + set(_PackageProject_NAME ${PROJECT_NAME}) + endif() + # ycm args + set(_PackageProject_NAMESPACE "${_PackageProject_NAME}::") + set(_PackageProject_VARS_PREFIX ${_PackageProject_NAME}) + set(_PackageProject_EXPORT ${_PackageProject_NAME}) + + # default version to the project version + if("${_PackageProject_VERSION}" STREQUAL "") + set(_PackageProject_VERSION ${PROJECT_VERSION}) + endif() + + # default compatibility to SameMajorVersion + if("${_PackageProject_COMPATIBILITY}" STREQUAL "") + set(_PackageProject_COMPATIBILITY "SameMajorVersion") + endif() + + # default to the build directory + if("${_PackageProject_CONFIG_EXPORT_DESTINATION}" STREQUAL "") + set(_PackageProject_CONFIG_EXPORT_DESTINATION "${CMAKE_BINARY_DIR}") + endif() + set(_PackageProject_EXPORT_DESTINATION + "${_PackageProject_CONFIG_EXPORT_DESTINATION}") + + # use datadir (works better with vcpkg, etc) + if("${_PackageProject_CONFIG_INSTALL_DESTINATION}" STREQUAL "") + set(_PackageProject_CONFIG_INSTALL_DESTINATION + "${CMAKE_INSTALL_DATADIR}/${_PackageProject_NAME}") + endif() + # ycm args + set(_PackageProject_INSTALL_DESTINATION + "${_PackageProject_CONFIG_INSTALL_DESTINATION}") + + # Installation of the public/interface includes + if(NOT "${_PackageProject_PUBLIC_INCLUDES}" STREQUAL "") + foreach(_INC ${_PackageProject_PUBLIC_INCLUDES}) + # make include absolute + if(NOT IS_ABSOLUTE ${_INC}) + set(_INC "${CMAKE_CURRENT_SOURCE_DIR}/${_INC}") + endif() + # install include + if(IS_DIRECTORY ${_INC}) + # the include directories are directly installed to the install + # destination. If you want an `include` folder in the install + # destination, name your include directory as `include` (or install it + # manually using `install()` command). + install(DIRECTORY ${_INC} DESTINATION "./") + else() + install(FILES ${_INC} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + endif() + endforeach() + endif() + + # Append the configured public dependencies + if(NOT "${_PackageProject_PUBLIC_DEPENDENCIES_CONFIGURED}" STREQUAL "") + set(_PUBLIC_DEPENDENCIES_CONFIG) + foreach(DEP ${_PackageProject_PUBLIC_DEPENDENCIES_CONFIGURED}) + list(APPEND _PUBLIC_DEPENDENCIES_CONFIG "${DEP} CONFIG") + endforeach() + endif() + list(APPEND _PackageProject_PUBLIC_DEPENDENCIES + ${_PUBLIC_DEPENDENCIES_CONFIG}) + # ycm arg + set(_PackageProject_DEPENDENCIES ${_PackageProject_PUBLIC_DEPENDENCIES}) + + # Append the configured private dependencies + if(NOT "${_PackageProject_PRIVATE_DEPENDENCIES_CONFIGURED}" STREQUAL "") + set(_PRIVATE_DEPENDENCIES_CONFIG) + foreach(DEP ${_PackageProject_PRIVATE_DEPENDENCIES_CONFIGURED}) + list(APPEND _PRIVATE_DEPENDENCIES_CONFIG "${DEP} CONFIG") + endforeach() + endif() + # ycm arg + list(APPEND _PackageProject_PRIVATE_DEPENDENCIES + ${_PRIVATE_DEPENDENCIES_CONFIG}) + + # Installation of package (compatible with vcpkg, etc) + install( + TARGETS ${_PackageProject_TARGETS} + EXPORT ${_PackageProject_EXPORT} + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin + PUBLIC_HEADER + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_PackageProject_NAME}" + COMPONENT dev) + + # install the usage file + set(_targets_str "") + foreach(_target ${_PackageProject_TARGETS}) + set(_targets_str "${_targets_str} ${_PackageProject_NAMESPACE}${_target}") + endforeach() + set(USAGE_FILE_CONTENT + "The package ${_PackageProject_NAME} provides CMake targets: find_package(${_PackageProject_NAME} CONFIG REQUIRED) target_link_libraries(main PRIVATE ${_targets_str}) ") - install(CODE "MESSAGE(STATUS \"${USAGE_FILE_CONTENT}\")") - file(WRITE "${_PackageProject_EXPORT_DESTINATION}/usage" "${USAGE_FILE_CONTENT}") - install(FILES "${_PackageProject_EXPORT_DESTINATION}/usage" - DESTINATION "${_PackageProject_CONFIG_INSTALL_DESTINATION}") - - unset(_PackageProject_TARGETS) - - # download ForwardArguments - FetchContent_Declare( - _fargs - URL https://github.com/polysquare/cmake-forward-arguments/archive/8c50d1f956172edb34e95efa52a2d5cb1f686ed2.zip) - FetchContent_GetProperties(_fargs) - if (NOT _fargs_POPULATED) - FetchContent_Populate(_fargs) - endif () - include("${_fargs_SOURCE_DIR}/ForwardArguments.cmake") - - # prepare the forward arguments for ycm - set(_FARGS_LIST) - cmake_forward_arguments( - _PackageProject - _FARGS_LIST - OPTION_ARGS - "${_options};" - SINGLEVAR_ARGS - "${_oneValueArgs};EXPORT_DESTINATION;INSTALL_DESTINATION;NAMESPACE;VARS_PREFIX;EXPORT" - MULTIVAR_ARGS - "${_multiValueArgs};DEPENDENCIES;PRIVATE_DEPENDENCIES") - - # download ycm - FetchContent_Declare(_ycm URL https://github.com/robotology/ycm/archive/refs/tags/v0.13.0.zip) - FetchContent_GetProperties(_ycm) - if (NOT _ycm_POPULATED) - FetchContent_Populate(_ycm) - endif () - include("${_ycm_SOURCE_DIR}/modules/InstallBasicPackageFiles.cmake") - - install_basic_package_files(${_PackageProject_NAME} "${_FARGS_LIST}") - - include("${_ycm_SOURCE_DIR}/modules/AddUninstallTarget.cmake") + install(CODE "MESSAGE(STATUS \"${USAGE_FILE_CONTENT}\")") + file(WRITE "${_PackageProject_EXPORT_DESTINATION}/usage" + "${USAGE_FILE_CONTENT}") + install(FILES "${_PackageProject_EXPORT_DESTINATION}/usage" + DESTINATION "${_PackageProject_CONFIG_INSTALL_DESTINATION}") + + unset(_PackageProject_TARGETS) + + # download ForwardArguments + FetchContent_Declare( + _fargs + URL https://github.com/polysquare/cmake-forward-arguments/archive/8c50d1f956172edb34e95efa52a2d5cb1f686ed2.zip + ) + FetchContent_GetProperties(_fargs) + if(NOT _fargs_POPULATED) + FetchContent_Populate(_fargs) + endif() + include("${_fargs_SOURCE_DIR}/ForwardArguments.cmake") + + # prepare the forward arguments for ycm + set(_FARGS_LIST) + cmake_forward_arguments( + _PackageProject + _FARGS_LIST + OPTION_ARGS + "${_options};" + SINGLEVAR_ARGS + "${_oneValueArgs};EXPORT_DESTINATION;INSTALL_DESTINATION;NAMESPACE;VARS_PREFIX;EXPORT" + MULTIVAR_ARGS + "${_multiValueArgs};DEPENDENCIES;PRIVATE_DEPENDENCIES") + + # download ycm + FetchContent_Declare( + _ycm URL https://github.com/robotology/ycm/archive/refs/tags/v0.13.0.zip) + FetchContent_GetProperties(_ycm) + if(NOT _ycm_POPULATED) + FetchContent_Populate(_ycm) + endif() + include("${_ycm_SOURCE_DIR}/modules/InstallBasicPackageFiles.cmake") + + install_basic_package_files(${_PackageProject_NAME} "${_FARGS_LIST}") + + include("${_ycm_SOURCE_DIR}/modules/AddUninstallTarget.cmake") endfunction() diff --git a/cmake/PreventInSourceBuilds.cmake b/cmake/PreventInSourceBuilds.cmake index 9dfd0fba3..d68db68e1 100644 --- a/cmake/PreventInSourceBuilds.cmake +++ b/cmake/PreventInSourceBuilds.cmake @@ -2,18 +2,18 @@ # This function will prevent in-source builds # function(fiction_assure_out_of_source_builds) - # make sure the user doesn't play dirty with symlinks - get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) - get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + # make sure the user doesn't play dirty with symlinks + get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) - # disallow in-source builds - if ("${srcdir}" STREQUAL "${bindir}") - message("######################################################") - message("Warning: in-source builds are disabled") - message("Please create a separate build directory and run cmake from there") - message("######################################################") - message(FATAL_ERROR "Quitting configuration") - endif () + # disallow in-source builds + if("${srcdir}" STREQUAL "${bindir}") + message("######################################################") + message("Warning: in-source builds are disabled") + message("Please create a separate build directory and run cmake from there") + message("######################################################") + message(FATAL_ERROR "Quitting configuration") + endif() endfunction() fiction_assure_out_of_source_builds() diff --git a/cmake/ProjectOptions.cmake b/cmake/ProjectOptions.cmake index 51cd29e52..2db061cb6 100644 --- a/cmake/ProjectOptions.cmake +++ b/cmake/ProjectOptions.cmake @@ -3,149 +3,138 @@ include(CMakeDependentOption) include(CheckCXXCompilerFlag) include(FetchContent) - macro(fiction_supports_sanitizers) - if ((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND NOT WIN32) - set(SUPPORTS_UBSAN ON) - else () - set(SUPPORTS_UBSAN OFF) - endif () - - if ((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND WIN32) - set(SUPPORTS_ASAN OFF) - else () - set(SUPPORTS_ASAN ON) - endif () + if((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES + ".*GNU.*") AND NOT WIN32) + set(SUPPORTS_UBSAN ON) + else() + set(SUPPORTS_UBSAN OFF) + endif() + + if((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES + ".*GNU.*") AND WIN32) + set(SUPPORTS_ASAN OFF) + else() + set(SUPPORTS_ASAN ON) + endif() endmacro() macro(fiction_setup_options) - option(FICTION_ENABLE_HARDENING "Enable hardening" OFF) - option(FICTION_ENABLE_COVERAGE "Enable coverage reporting" OFF) - cmake_dependent_option( - FICTION_ENABLE_GLOBAL_HARDENING - "Attempt to push hardening options to built dependencies" - ON - FICTION_ENABLE_HARDENING - OFF) - - option(FICTION_ENABLE_IPO "Enable IPO/LTO" OFF) - option(FICTION_WARNINGS_AS_ERRORS "Treat Warnings As Errors" OFF) - option(FICTION_ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF) - option(FICTION_ENABLE_SANITIZER_LEAK "Enable leak sanitizer" OFF) - option(FICTION_ENABLE_SANITIZER_UNDEFINED "Enable undefined sanitizer" OFF) - option(FICTION_ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF) - option(FICTION_ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF) - option(FICTION_ENABLE_UNITY_BUILD "Enable unity builds" OFF) - option(FICTION_ENABLE_PCH "Enable precompiled headers" OFF) - option(FICTION_ENABLE_CACHE "Enable ccache" ON) - - if (NOT PROJECT_IS_TOP_LEVEL) - mark_as_advanced( - FICTION_ENABLE_IPO - FICTION_WARNINGS_AS_ERRORS - FICTION_ENABLE_SANITIZER_ADDRESS - FICTION_ENABLE_SANITIZER_LEAK - FICTION_ENABLE_SANITIZER_UNDEFINED - FICTION_ENABLE_SANITIZER_THREAD - FICTION_ENABLE_SANITIZER_MEMORY - FICTION_ENABLE_UNITY_BUILD - FICTION_ENABLE_COVERAGE - FICTION_ENABLE_PCH - FICTION_ENABLE_CACHE) - endif () + option(FICTION_ENABLE_HARDENING "Enable hardening" OFF) + option(FICTION_ENABLE_COVERAGE "Enable coverage reporting" OFF) + cmake_dependent_option( + FICTION_ENABLE_GLOBAL_HARDENING + "Attempt to push hardening options to built dependencies" ON + FICTION_ENABLE_HARDENING OFF) + + option(FICTION_ENABLE_IPO "Enable IPO/LTO" OFF) + option(FICTION_WARNINGS_AS_ERRORS "Treat Warnings As Errors" OFF) + option(FICTION_ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF) + option(FICTION_ENABLE_SANITIZER_LEAK "Enable leak sanitizer" OFF) + option(FICTION_ENABLE_SANITIZER_UNDEFINED "Enable undefined sanitizer" OFF) + option(FICTION_ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF) + option(FICTION_ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF) + option(FICTION_ENABLE_UNITY_BUILD "Enable unity builds" OFF) + option(FICTION_ENABLE_PCH "Enable precompiled headers" OFF) + option(FICTION_ENABLE_CACHE "Enable ccache" ON) + + if(NOT PROJECT_IS_TOP_LEVEL) + mark_as_advanced( + FICTION_ENABLE_IPO + FICTION_WARNINGS_AS_ERRORS + FICTION_ENABLE_SANITIZER_ADDRESS + FICTION_ENABLE_SANITIZER_LEAK + FICTION_ENABLE_SANITIZER_UNDEFINED + FICTION_ENABLE_SANITIZER_THREAD + FICTION_ENABLE_SANITIZER_MEMORY + FICTION_ENABLE_UNITY_BUILD + FICTION_ENABLE_COVERAGE + FICTION_ENABLE_PCH + FICTION_ENABLE_CACHE) + endif() endmacro() macro(fiction_global_options) - if (FICTION_ENABLE_IPO) - include(cmake/InterproceduralOptimization.cmake) - fiction_enable_ipo() - endif () - - fiction_supports_sanitizers() - - if (FICTION_ENABLE_HARDENING AND FICTION_ENABLE_GLOBAL_HARDENING) - include(cmake/Hardening.cmake) - if (NOT SUPPORTS_UBSAN - OR FICTION_ENABLE_SANITIZER_UNDEFINED - OR FICTION_ENABLE_SANITIZER_ADDRESS - OR FICTION_ENABLE_SANITIZER_THREAD - OR FICTION_ENABLE_SANITIZER_LEAK) - set(ENABLE_UBSAN_MINIMAL_RUNTIME FALSE) - else () - set(ENABLE_UBSAN_MINIMAL_RUNTIME TRUE) - endif () - fiction_enable_hardening(fiction_options ON ${ENABLE_UBSAN_MINIMAL_RUNTIME}) - endif () + if(FICTION_ENABLE_IPO) + include(cmake/InterproceduralOptimization.cmake) + fiction_enable_ipo() + endif() + + fiction_supports_sanitizers() + + if(FICTION_ENABLE_HARDENING AND FICTION_ENABLE_GLOBAL_HARDENING) + include(cmake/Hardening.cmake) + if(NOT SUPPORTS_UBSAN + OR FICTION_ENABLE_SANITIZER_UNDEFINED + OR FICTION_ENABLE_SANITIZER_ADDRESS + OR FICTION_ENABLE_SANITIZER_THREAD + OR FICTION_ENABLE_SANITIZER_LEAK) + set(ENABLE_UBSAN_MINIMAL_RUNTIME FALSE) + else() + set(ENABLE_UBSAN_MINIMAL_RUNTIME TRUE) + endif() + fiction_enable_hardening(fiction_options ON ${ENABLE_UBSAN_MINIMAL_RUNTIME}) + endif() endmacro() macro(fiction_local_options) - if (PROJECT_IS_TOP_LEVEL) - include(cmake/StandardProjectSettings.cmake) - endif () - - add_library(fiction_warnings INTERFACE) - add_library(fiction_options INTERFACE) - - include(cmake/CompilerWarnings.cmake) - fiction_set_project_warnings( - fiction_warnings - ${FICTION_WARNINGS_AS_ERRORS} - "" - "" - "" - "") - - include(cmake/Sanitizers.cmake) - fiction_enable_sanitizers( - fiction_options - ${FICTION_ENABLE_SANITIZER_ADDRESS} - ${FICTION_ENABLE_SANITIZER_LEAK} - ${FICTION_ENABLE_SANITIZER_UNDEFINED} - ${FICTION_ENABLE_SANITIZER_THREAD} - ${FICTION_ENABLE_SANITIZER_MEMORY}) - - set_target_properties(fiction_options PROPERTIES UNITY_BUILD ${FICTION_ENABLE_UNITY_BUILD}) - - if (FICTION_ENABLE_PCH) - target_precompile_headers( - fiction_options - INTERFACE - - - ) - endif () - - if (FICTION_ENABLE_CACHE) - include(cmake/Cache.cmake) - fiction_enable_cache() - endif () - - if (FICTION_ENABLE_COVERAGE) - include(cmake/Coverage.cmake) - fiction_enable_coverage(fiction_options) - endif () - - if (FICTION_WARNINGS_AS_ERRORS) - check_cxx_compiler_flag("-Wl,--fatal-warnings" LINKER_FATAL_WARNINGS) - if (LINKER_FATAL_WARNINGS) - # This is not working consistently, so disabling for now - # target_link_options(fiction_options INTERFACE -Wl,--fatal-warnings) - endif () - endif () - - if (FICTION_ENABLE_HARDENING AND NOT FICTION_ENABLE_GLOBAL_HARDENING) - include(cmake/Hardening.cmake) - if (NOT SUPPORTS_UBSAN - OR FICTION_ENABLE_SANITIZER_UNDEFINED - OR FICTION_ENABLE_SANITIZER_ADDRESS - OR FICTION_ENABLE_SANITIZER_THREAD - OR FICTION_ENABLE_SANITIZER_LEAK) - set(ENABLE_UBSAN_MINIMAL_RUNTIME FALSE) - else () - set(ENABLE_UBSAN_MINIMAL_RUNTIME TRUE) - endif () - fiction_enable_hardening(fiction_options OFF ${ENABLE_UBSAN_MINIMAL_RUNTIME}) - endif () + if(PROJECT_IS_TOP_LEVEL) + include(cmake/StandardProjectSettings.cmake) + endif() + + add_library(fiction_warnings INTERFACE) + add_library(fiction_options INTERFACE) + + include(cmake/CompilerWarnings.cmake) + fiction_set_project_warnings(fiction_warnings ${FICTION_WARNINGS_AS_ERRORS} + "" "" "" "") + + include(cmake/Sanitizers.cmake) + fiction_enable_sanitizers( + fiction_options ${FICTION_ENABLE_SANITIZER_ADDRESS} + ${FICTION_ENABLE_SANITIZER_LEAK} ${FICTION_ENABLE_SANITIZER_UNDEFINED} + ${FICTION_ENABLE_SANITIZER_THREAD} ${FICTION_ENABLE_SANITIZER_MEMORY}) + + set_target_properties(fiction_options + PROPERTIES UNITY_BUILD ${FICTION_ENABLE_UNITY_BUILD}) + + if(FICTION_ENABLE_PCH) + target_precompile_headers(fiction_options INTERFACE + ) + endif() + + if(FICTION_ENABLE_CACHE) + include(cmake/Cache.cmake) + fiction_enable_cache() + endif() + + if(FICTION_ENABLE_COVERAGE) + include(cmake/Coverage.cmake) + fiction_enable_coverage(fiction_options) + endif() + + if(FICTION_WARNINGS_AS_ERRORS) + check_cxx_compiler_flag("-Wl,--fatal-warnings" LINKER_FATAL_WARNINGS) + if(LINKER_FATAL_WARNINGS) + # This is not working consistently, so disabling for now + # target_link_options(fiction_options INTERFACE -Wl,--fatal-warnings) + endif() + endif() + + if(FICTION_ENABLE_HARDENING AND NOT FICTION_ENABLE_GLOBAL_HARDENING) + include(cmake/Hardening.cmake) + if(NOT SUPPORTS_UBSAN + OR FICTION_ENABLE_SANITIZER_UNDEFINED + OR FICTION_ENABLE_SANITIZER_ADDRESS + OR FICTION_ENABLE_SANITIZER_THREAD + OR FICTION_ENABLE_SANITIZER_LEAK) + set(ENABLE_UBSAN_MINIMAL_RUNTIME FALSE) + else() + set(ENABLE_UBSAN_MINIMAL_RUNTIME TRUE) + endif() + fiction_enable_hardening(fiction_options OFF + ${ENABLE_UBSAN_MINIMAL_RUNTIME}) + endif() endmacro() diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake index 954f1e7f0..c88c085b3 100644 --- a/cmake/Sanitizers.cmake +++ b/cmake/Sanitizers.cmake @@ -1,87 +1,93 @@ function( - fiction_enable_sanitizers - project_name - ENABLE_SANITIZER_ADDRESS - ENABLE_SANITIZER_LEAK - ENABLE_SANITIZER_UNDEFINED_BEHAVIOR - ENABLE_SANITIZER_THREAD - ENABLE_SANITIZER_MEMORY) + fiction_enable_sanitizers + project_name + ENABLE_SANITIZER_ADDRESS + ENABLE_SANITIZER_LEAK + ENABLE_SANITIZER_UNDEFINED_BEHAVIOR + ENABLE_SANITIZER_THREAD + ENABLE_SANITIZER_MEMORY) - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - set(SANITIZERS "") + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES + ".*Clang") + set(SANITIZERS "") - if (${ENABLE_SANITIZER_ADDRESS}) - list(APPEND SANITIZERS "address") - endif () + if(${ENABLE_SANITIZER_ADDRESS}) + list(APPEND SANITIZERS "address") + endif() - if (${ENABLE_SANITIZER_LEAK}) - list(APPEND SANITIZERS "leak") - endif () + if(${ENABLE_SANITIZER_LEAK}) + list(APPEND SANITIZERS "leak") + endif() - if (${ENABLE_SANITIZER_UNDEFINED_BEHAVIOR}) - list(APPEND SANITIZERS "undefined") - endif () + if(${ENABLE_SANITIZER_UNDEFINED_BEHAVIOR}) + list(APPEND SANITIZERS "undefined") + endif() - if (${ENABLE_SANITIZER_THREAD}) - if ("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) - message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") - else () - list(APPEND SANITIZERS "thread") - endif () - endif () + if(${ENABLE_SANITIZER_THREAD}) + if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) + message( + WARNING + "Thread sanitizer does not work with Address and Leak sanitizer enabled" + ) + else() + list(APPEND SANITIZERS "thread") + endif() + endif() - if (${ENABLE_SANITIZER_MEMORY} AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - message( - WARNING - "Memory sanitizer requires all the code (including libc++) to be MSan-instrumented otherwise it reports false positives" - ) - if ("address" IN_LIST SANITIZERS - OR "thread" IN_LIST SANITIZERS - OR "leak" IN_LIST SANITIZERS) - message(WARNING "Memory sanitizer does not work with Address, Thread or Leak sanitizer enabled") - else () - list(APPEND SANITIZERS "memory") - endif () - endif () - elseif (MSVC) - if (${ENABLE_SANITIZER_ADDRESS}) - list(APPEND SANITIZERS "address") - endif () - if (${ENABLE_SANITIZER_LEAK} - OR ${ENABLE_SANITIZER_UNDEFINED_BEHAVIOR} - OR ${ENABLE_SANITIZER_THREAD} - OR ${ENABLE_SANITIZER_MEMORY}) - message(WARNING "MSVC only supports address sanitizer") - endif () - endif () + if(${ENABLE_SANITIZER_MEMORY} AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + message( + WARNING + "Memory sanitizer requires all the code (including libc++) to be MSan-instrumented otherwise it reports false positives" + ) + if("address" IN_LIST SANITIZERS + OR "thread" IN_LIST SANITIZERS + OR "leak" IN_LIST SANITIZERS) + message( + WARNING + "Memory sanitizer does not work with Address, Thread or Leak sanitizer enabled" + ) + else() + list(APPEND SANITIZERS "memory") + endif() + endif() + elseif(MSVC) + if(${ENABLE_SANITIZER_ADDRESS}) + list(APPEND SANITIZERS "address") + endif() + if(${ENABLE_SANITIZER_LEAK} + OR ${ENABLE_SANITIZER_UNDEFINED_BEHAVIOR} + OR ${ENABLE_SANITIZER_THREAD} + OR ${ENABLE_SANITIZER_MEMORY}) + message(WARNING "MSVC only supports address sanitizer") + endif() + endif() - list( - JOIN - SANITIZERS - "," - LIST_OF_SANITIZERS) + list(JOIN SANITIZERS "," LIST_OF_SANITIZERS) - if (LIST_OF_SANITIZERS) - if (NOT - "${LIST_OF_SANITIZERS}" - STREQUAL - "") - if (NOT MSVC) - target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) - target_link_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) - else () - string(FIND "$ENV{PATH}" "$ENV{VSINSTALLDIR}" index_of_vs_install_dir) - if ("${index_of_vs_install_dir}" STREQUAL "-1") - message( - SEND_ERROR - "Using MSVC sanitizers requires setting the MSVC environment before building the project. Please manually open the MSVC command prompt and rebuild the project." - ) - endif () - target_compile_options(${project_name} INTERFACE /fsanitize=${LIST_OF_SANITIZERS} /Zi /INCREMENTAL:NO) - target_compile_definitions(${project_name} INTERFACE _DISABLE_VECTOR_ANNOTATION _DISABLE_STRING_ANNOTATION) - target_link_options(${project_name} INTERFACE /INCREMENTAL:NO) - endif () - endif () - endif () + if(LIST_OF_SANITIZERS) + if(NOT "${LIST_OF_SANITIZERS}" STREQUAL "") + if(NOT MSVC) + target_compile_options(${project_name} + INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) + target_link_options(${project_name} INTERFACE + -fsanitize=${LIST_OF_SANITIZERS}) + else() + string(FIND "$ENV{PATH}" "$ENV{VSINSTALLDIR}" index_of_vs_install_dir) + if("${index_of_vs_install_dir}" STREQUAL "-1") + message( + SEND_ERROR + "Using MSVC sanitizers requires setting the MSVC environment before building the project. Please manually open the MSVC command prompt and rebuild the project." + ) + endif() + target_compile_options( + ${project_name} INTERFACE /fsanitize=${LIST_OF_SANITIZERS} /Zi + /INCREMENTAL:NO) + target_compile_definitions( + ${project_name} INTERFACE _DISABLE_VECTOR_ANNOTATION + _DISABLE_STRING_ANNOTATION) + target_link_options(${project_name} INTERFACE /INCREMENTAL:NO) + endif() + endif() + endif() endfunction() diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index a469e89df..83b815497 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -1,49 +1,48 @@ # Set a default build type if none was specified -if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Release' as none was specified.") - set(CMAKE_BUILD_TYPE - Release - CACHE STRING "Choose the type of build." FORCE) - # Set the possible values of build type for cmake-gui, ccmake - set_property( - CACHE CMAKE_BUILD_TYPE - PROPERTY STRINGS - "Debug" - "Release" - "MinSizeRel" - "RelWithDebInfo") -endif () +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'Release' as none was specified.") + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui, ccmake + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" + "MinSizeRel" "RelWithDebInfo") +endif() -# Generate compile_commands.json to make it easier to work with clang based tools +# Generate compile_commands.json to make it easier to work with clang based +# tools set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Enhance error reporting and compiler messages -if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - if (WIN32) - # On Windows cuda nvcc uses cl and not clang - add_compile_options($<$:-fcolor-diagnostics> $<$:-fcolor-diagnostics>) - else () - add_compile_options(-fcolor-diagnostics) - endif () -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if (WIN32) - # On Windows cuda nvcc uses cl and not gcc - add_compile_options($<$:-fdiagnostics-color=always> - $<$:-fdiagnostics-color=always>) - else () - add_compile_options(-fdiagnostics-color=always) - endif () -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER 1900) - add_compile_options(/diagnostics:column) -else () - message(STATUS "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler.") -endif () +if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + if(WIN32) + # On Windows cuda nvcc uses cl and not clang + add_compile_options($<$:-fcolor-diagnostics> + $<$:-fcolor-diagnostics>) + else() + add_compile_options(-fcolor-diagnostics) + endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(WIN32) + # On Windows cuda nvcc uses cl and not gcc + add_compile_options($<$:-fdiagnostics-color=always> + $<$:-fdiagnostics-color=always>) + else() + add_compile_options(-fdiagnostics-color=always) + endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER 1900) + add_compile_options(/diagnostics:column) +else() + message( + STATUS + "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler." + ) +endif() # Use bigobj for MSVC due to many inline and template functions -if (MSVC) - add_compile_options(/bigobj) -endif () - +if(MSVC) + add_compile_options(/bigobj) +endif() # run vcvarsall when msvc is used include(${CMAKE_CURRENT_LIST_DIR}/VCEnvironment.cmake) diff --git a/cmake/SystemLink.cmake b/cmake/SystemLink.cmake index e3adf7b24..3a90a0772 100644 --- a/cmake/SystemLink.cmake +++ b/cmake/SystemLink.cmake @@ -1,83 +1,65 @@ # Include a system directory (which suppresses its warnings). function(target_include_system_directories target) - set(multiValueArgs INTERFACE PUBLIC PRIVATE) - cmake_parse_arguments( - ARG - "" - "" - "${multiValueArgs}" - ${ARGN}) + set(multiValueArgs INTERFACE PUBLIC PRIVATE) + cmake_parse_arguments(ARG "" "" "${multiValueArgs}" ${ARGN}) - foreach (scope IN ITEMS INTERFACE PUBLIC PRIVATE) - foreach (lib_include_dirs IN LISTS ARG_${scope}) - if (NOT MSVC) - # system includes do not work in MSVC - # awaiting https://gitlab.kitware.com/cmake/cmake/-/issues/18272# - # awaiting https://gitlab.kitware.com/cmake/cmake/-/issues/17904 - set(_SYSTEM SYSTEM) - endif () - if (${scope} STREQUAL "INTERFACE" OR ${scope} STREQUAL "PUBLIC") - target_include_directories( - ${target} - ${_SYSTEM} - ${scope} - "$" - "$") - else () - target_include_directories( - ${target} - ${_SYSTEM} - ${scope} - ${lib_include_dirs}) - endif () - endforeach () - endforeach () + foreach(scope IN ITEMS INTERFACE PUBLIC PRIVATE) + foreach(lib_include_dirs IN LISTS ARG_${scope}) + if(NOT MSVC) + # system includes do not work in MSVC awaiting + # https://gitlab.kitware.com/cmake/cmake/-/issues/18272# awaiting + # https://gitlab.kitware.com/cmake/cmake/-/issues/17904 + set(_SYSTEM SYSTEM) + endif() + if(${scope} STREQUAL "INTERFACE" OR ${scope} STREQUAL "PUBLIC") + target_include_directories( + ${target} ${_SYSTEM} ${scope} + "$" + "$") + else() + target_include_directories(${target} ${_SYSTEM} ${scope} + ${lib_include_dirs}) + endif() + endforeach() + endforeach() endfunction() -# Include the directories of a library target as system directories (which suppresses their warnings). -function( - target_include_system_library - target - scope - lib) - # check if this is a target - if (TARGET ${lib}) - get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES) - if (lib_include_dirs) - target_include_system_directories(${target} ${scope} ${lib_include_dirs}) - else () - message(TRACE "${lib} library does not have the INTERFACE_INCLUDE_DIRECTORIES property.") - endif () - endif () +# Include the directories of a library target as system directories (which +# suppresses their warnings). +function(target_include_system_library target scope lib) + # check if this is a target + if(TARGET ${lib}) + get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES) + if(lib_include_dirs) + target_include_system_directories(${target} ${scope} ${lib_include_dirs}) + else() + message( + TRACE + "${lib} library does not have the INTERFACE_INCLUDE_DIRECTORIES property." + ) + endif() + endif() endfunction() # Link a library target as a system library (which suppresses its warnings). -function( - target_link_system_library - target - scope - lib) - # Include the directories in the library - target_include_system_library(${target} ${scope} ${lib}) +function(target_link_system_library target scope lib) + # Include the directories in the library + target_include_system_library(${target} ${scope} ${lib}) - # Link the library - target_link_libraries(${target} ${scope} ${lib}) + # Link the library + target_link_libraries(${target} ${scope} ${lib}) endfunction() -# Link multiple library targets as system libraries (which suppresses their warnings). +# Link multiple library targets as system libraries (which suppresses their +# warnings). function(target_link_system_libraries target) - set(multiValueArgs INTERFACE PUBLIC PRIVATE) - cmake_parse_arguments( - ARG - "" - "" - "${multiValueArgs}" - ${ARGN}) + set(multiValueArgs INTERFACE PUBLIC PRIVATE) + cmake_parse_arguments(ARG "" "" "${multiValueArgs}" ${ARGN}) - foreach (scope IN ITEMS INTERFACE PUBLIC PRIVATE) - foreach (lib IN LISTS ARG_${scope}) - target_link_system_library(${target} ${scope} ${lib}) - endforeach () - endforeach () + foreach(scope IN ITEMS INTERFACE PUBLIC PRIVATE) + foreach(lib IN LISTS ARG_${scope}) + target_link_system_library(${target} ${scope} ${lib}) + endforeach() + endforeach() endfunction() diff --git a/cmake/Utilities.cmake b/cmake/Utilities.cmake index ae2a1b4d2..9fc325c0e 100644 --- a/cmake/Utilities.cmake +++ b/cmake/Utilities.cmake @@ -1,139 +1,101 @@ # find a substring from a string by a given prefix such as VCVARSALL_ENV_START -function( - find_substring_by_prefix - output - prefix - input) - # find the prefix - string(FIND "${input}" "${prefix}" prefix_index) - if ("${prefix_index}" STREQUAL "-1") - message(SEND_ERROR "Could not find ${prefix} in ${input}") - endif () - # find the start index - string(LENGTH "${prefix}" prefix_length) - math(EXPR start_index "${prefix_index} + ${prefix_length}") +function(find_substring_by_prefix output prefix input) + # find the prefix + string(FIND "${input}" "${prefix}" prefix_index) + if("${prefix_index}" STREQUAL "-1") + message(SEND_ERROR "Could not find ${prefix} in ${input}") + endif() + # find the start index + string(LENGTH "${prefix}" prefix_length) + math(EXPR start_index "${prefix_index} + ${prefix_length}") - string( - SUBSTRING "${input}" - "${start_index}" - "-1" - _output) - set("${output}" - "${_output}" - PARENT_SCOPE) + string(SUBSTRING "${input}" "${start_index}" "-1" _output) + set("${output}" + "${_output}" + PARENT_SCOPE) endfunction() -# A function to set environment variables of CMake from the output of `cmd /c set` +# A function to set environment variables of CMake from the output of `cmd /c +# set` function(set_env_from_string env_string) - # replace ; in paths with __sep__ so we can split on ; - string( - REGEX - REPLACE ";" - "__sep__" - env_string_sep_added - "${env_string}") + # replace ; in paths with __sep__ so we can split on ; + string(REGEX REPLACE ";" "__sep__" env_string_sep_added "${env_string}") - # the variables are separated by \r?\n - string( - REGEX - REPLACE "\r?\n" - ";" - env_list - "${env_string_sep_added}") + # the variables are separated by \r?\n + string(REGEX REPLACE "\r?\n" ";" env_list "${env_string_sep_added}") - foreach (env_var ${env_list}) - # split by = - string( - REGEX - REPLACE "=" - ";" - env_parts - "${env_var}") + foreach(env_var ${env_list}) + # split by = + string(REGEX REPLACE "=" ";" env_parts "${env_var}") - list(LENGTH env_parts env_parts_length) - if ("${env_parts_length}" EQUAL "2") - # get the variable name and value - list( - GET - env_parts - 0 - env_name) - list( - GET - env_parts - 1 - env_value) + list(LENGTH env_parts env_parts_length) + if("${env_parts_length}" EQUAL "2") + # get the variable name and value + list(GET env_parts 0 env_name) + list(GET env_parts 1 env_value) - # recover ; in paths - string( - REGEX - REPLACE "__sep__" - ";" - env_value - "${env_value}") + # recover ; in paths + string(REGEX REPLACE "__sep__" ";" env_value "${env_value}") - # set env_name to env_value - set(ENV{${env_name}} "${env_value}") + # set env_name to env_value + set(ENV{${env_name}} "${env_value}") - # update cmake program path - if ("${env_name}" EQUAL "PATH") - list(APPEND CMAKE_PROGRAM_PATH ${env_value}) - endif () - endif () - endforeach () + # update cmake program path + if("${env_name}" EQUAL "PATH") + list(APPEND CMAKE_PROGRAM_PATH ${env_value}) + endif() + endif() + endforeach() endfunction() function(get_all_targets var) - set(targets) - get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR}) - set(${var} - ${targets} - PARENT_SCOPE) + set(targets) + get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR}) + set(${var} + ${targets} + PARENT_SCOPE) endfunction() function(get_all_installable_targets var) - set(targets) - get_all_targets(targets) - foreach (_target ${targets}) - get_target_property(_target_type ${_target} TYPE) - if (NOT - ${_target_type} - MATCHES - ".*LIBRARY|EXECUTABLE") - list(REMOVE_ITEM targets ${_target}) - endif () - endforeach () - set(${var} - ${targets} - PARENT_SCOPE) + set(targets) + get_all_targets(targets) + foreach(_target ${targets}) + get_target_property(_target_type ${_target} TYPE) + if(NOT ${_target_type} MATCHES ".*LIBRARY|EXECUTABLE") + list(REMOVE_ITEM targets ${_target}) + endif() + endforeach() + set(${var} + ${targets} + PARENT_SCOPE) endfunction() macro(get_all_targets_recursive targets dir) - get_property( - subdirectories - DIRECTORY ${dir} - PROPERTY SUBDIRECTORIES) - foreach (subdir ${subdirectories}) - get_all_targets_recursive(${targets} ${subdir}) - endforeach () + get_property( + subdirectories + DIRECTORY ${dir} + PROPERTY SUBDIRECTORIES) + foreach(subdir ${subdirectories}) + get_all_targets_recursive(${targets} ${subdir}) + endforeach() - get_property( - current_targets - DIRECTORY ${dir} - PROPERTY BUILDSYSTEM_TARGETS) - list(APPEND ${targets} ${current_targets}) + get_property( + current_targets + DIRECTORY ${dir} + PROPERTY BUILDSYSTEM_TARGETS) + list(APPEND ${targets} ${current_targets}) endmacro() function(is_verbose var) - if ("CMAKE_MESSAGE_LOG_LEVEL" STREQUAL "VERBOSE" - OR "CMAKE_MESSAGE_LOG_LEVEL" STREQUAL "DEBUG" - OR "CMAKE_MESSAGE_LOG_LEVEL" STREQUAL "TRACE") - set(${var} - ON - PARENT_SCOPE) - else () - set(${var} - OFF - PARENT_SCOPE) - endif () + if("CMAKE_MESSAGE_LOG_LEVEL" STREQUAL "VERBOSE" + OR "CMAKE_MESSAGE_LOG_LEVEL" STREQUAL "DEBUG" + OR "CMAKE_MESSAGE_LOG_LEVEL" STREQUAL "TRACE") + set(${var} + ON + PARENT_SCOPE) + else() + set(${var} + OFF + PARENT_SCOPE) + endif() endfunction() diff --git a/cmake/VCEnvironment.cmake b/cmake/VCEnvironment.cmake index be5410631..a58ff8247 100644 --- a/cmake/VCEnvironment.cmake +++ b/cmake/VCEnvironment.cmake @@ -1,69 +1,78 @@ macro(detect_architecture) - # detect the architecture - string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CMAKE_SYSTEM_PROCESSOR_LOWER) - if (CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL x86 OR CMAKE_SYSTEM_PROCESSOR_LOWER MATCHES "^i[3456]86$") - set(VCVARSALL_ARCH x86) - elseif ( - CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL x64 - OR CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL x86_64 - OR CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL amd64) - set(VCVARSALL_ARCH x64) - elseif (CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL arm) - set(VCVARSALL_ARCH arm) - elseif (CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL arm64 OR CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL aarch64) - set(VCVARSALL_ARCH arm64) - else () - if (CMAKE_HOST_SYSTEM_PROCESSOR) - set(VCVARSALL_ARCH ${CMAKE_HOST_SYSTEM_PROCESSOR}) - else () - set(VCVARSALL_ARCH x64) - message(STATUS "Unkown architecture CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR_LOWER} - using x64") - endif () - endif () + # detect the architecture + string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CMAKE_SYSTEM_PROCESSOR_LOWER) + if(CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL x86 OR CMAKE_SYSTEM_PROCESSOR_LOWER + MATCHES "^i[3456]86$") + set(VCVARSALL_ARCH x86) + elseif( + CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL x64 + OR CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL x86_64 + OR CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL amd64) + set(VCVARSALL_ARCH x64) + elseif(CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL arm) + set(VCVARSALL_ARCH arm) + elseif(CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL arm64 + OR CMAKE_SYSTEM_PROCESSOR_LOWER STREQUAL aarch64) + set(VCVARSALL_ARCH arm64) + else() + if(CMAKE_HOST_SYSTEM_PROCESSOR) + set(VCVARSALL_ARCH ${CMAKE_HOST_SYSTEM_PROCESSOR}) + else() + set(VCVARSALL_ARCH x64) + message( + STATUS + "Unkown architecture CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR_LOWER} - using x64" + ) + endif() + endif() endmacro() # Run vcvarsall.bat and set CMake environment variables function(run_vcvarsall) - # if MSVC but VSCMD_VER is not set, which means vcvarsall has not run - if (MSVC AND "$ENV{VSCMD_VER}" STREQUAL "" AND NOT CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + # if MSVC but VSCMD_VER is not set, which means vcvarsall has not run + if(MSVC + AND "$ENV{VSCMD_VER}" STREQUAL "" + AND NOT CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - # find vcvarsall.bat - get_filename_component(MSVC_DIR ${CMAKE_CXX_COMPILER} DIRECTORY) - find_file( - VCVARSALL_FILE - NAMES vcvarsall.bat - PATHS "${MSVC_DIR}" - "${MSVC_DIR}/.." - "${MSVC_DIR}/../.." - "${MSVC_DIR}/../../../../../../../.." - "${MSVC_DIR}/../../../../../../.." - PATH_SUFFIXES "VC/Auxiliary/Build" "Common7/Tools" "Tools") + # find vcvarsall.bat + get_filename_component(MSVC_DIR ${CMAKE_CXX_COMPILER} DIRECTORY) + find_file( + VCVARSALL_FILE + NAMES vcvarsall.bat + PATHS "${MSVC_DIR}" "${MSVC_DIR}/.." "${MSVC_DIR}/../.." + "${MSVC_DIR}/../../../../../../../.." + "${MSVC_DIR}/../../../../../../.." + PATH_SUFFIXES "VC/Auxiliary/Build" "Common7/Tools" "Tools") - if (EXISTS ${VCVARSALL_FILE}) - # detect the architecture - detect_architecture() + if(EXISTS ${VCVARSALL_FILE}) + # detect the architecture + detect_architecture() - # run vcvarsall and print the environment variables - message(STATUS "Running `${VCVARSALL_FILE} ${VCVARSALL_ARCH}` to set up the MSVC environment") - execute_process( - COMMAND - "cmd" "/c" ${VCVARSALL_FILE} ${VCVARSALL_ARCH} # - "&&" "call" "echo" "VCVARSALL_ENV_START" # - "&" "set" # - OUTPUT_VARIABLE VCVARSALL_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE) + # run vcvarsall and print the environment variables + message( + STATUS + "Running `${VCVARSALL_FILE} ${VCVARSALL_ARCH}` to set up the MSVC environment" + ) + execute_process( + COMMAND + "cmd" "/c" ${VCVARSALL_FILE} ${VCVARSALL_ARCH} # + "&&" "call" "echo" "VCVARSALL_ENV_START" # + "&" "set" # + OUTPUT_VARIABLE VCVARSALL_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE) - # parse the output and get the environment variables string - find_substring_by_prefix(VCVARSALL_ENV "VCVARSALL_ENV_START" "${VCVARSALL_OUTPUT}") + # parse the output and get the environment variables string + find_substring_by_prefix(VCVARSALL_ENV "VCVARSALL_ENV_START" + "${VCVARSALL_OUTPUT}") - # set the environment variables - set_env_from_string("${VCVARSALL_ENV}") + # set the environment variables + set_env_from_string("${VCVARSALL_ENV}") - else () - message( - WARNING - "Could not find `vcvarsall.bat` for automatic MSVC environment preparation. Please manually open the MSVC command prompt and rebuild the project. + else() + message( + WARNING + "Could not find `vcvarsall.bat` for automatic MSVC environment preparation. Please manually open the MSVC command prompt and rebuild the project. ") - endif () - endif () + endif() + endif() endfunction() diff --git a/experiments/CMakeLists.txt b/experiments/CMakeLists.txt index 810861006..d787a793d 100644 --- a/experiments/CMakeLists.txt +++ b/experiments/CMakeLists.txt @@ -1,46 +1,54 @@ # largely based on mockturtle/experiments/CMakeLists.txt add_library(fiction_experiments INTERFACE) -target_include_directories(fiction_experiments INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/libs/mockturtle/experiments/) +target_include_directories( + fiction_experiments + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/libs/mockturtle/experiments/) target_link_libraries(fiction_experiments INTERFACE libfiction) -if (ENABLE_MATPLOTLIB) - target_link_libraries(fiction_experiments INTERFACE matplot) -endif () +if(ENABLE_MATPLOTLIB) + target_link_libraries(fiction_experiments INTERFACE matplot) +endif() # check for git revision -if (EXISTS ${PROJECT_SOURCE_DIR}/.git) - find_package(Git) - if (GIT_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - OUTPUT_VARIABLE "GIT_SHORT_REVISION" - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - target_compile_definitions(fiction_experiments INTERFACE "GIT_SHORT_REVISION=\"${GIT_SHORT_REVISION}\"") - endif () -endif () +if(EXISTS ${PROJECT_SOURCE_DIR}/.git) + find_package(Git) + if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE "GIT_SHORT_REVISION" + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + target_compile_definitions( + fiction_experiments + INTERFACE "GIT_SHORT_REVISION=\"${GIT_SHORT_REVISION}\"") + endif() +endif() # path to the experiments cpp files and EPFL benchmarks -target_compile_definitions(fiction_experiments INTERFACE "EXPERIMENTS_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}/\"") +target_compile_definitions( + fiction_experiments + INTERFACE "EXPERIMENTS_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}/\"") file(GLOB_RECURSE FILENAMES *.cpp) -foreach (filename ${FILENAMES}) - get_filename_component(expname ${filename} NAME_WE) - add_executable(${expname} ${filename}) - target_link_libraries(${expname} PUBLIC fiction_experiments) +foreach(filename ${FILENAMES}) + get_filename_component(expname ${filename} NAME_WE) + add_executable(${expname} ${filename}) + target_link_libraries(${expname} PUBLIC fiction_experiments) - # Strip the executable if we are in Release mode - if (CMAKE_BUILD_TYPE STREQUAL "Release") - if (CMAKE_STRIP) - add_custom_command( - TARGET ${expname} - POST_BUILD - COMMAND ${CMAKE_STRIP} $ - ) - else () - message(WARNING "Strip command is not available. The executables will not be stripped.") - endif () - endif () -endforeach () + # Strip the executable if we are in Release mode + if(CMAKE_BUILD_TYPE STREQUAL "Release") + if(CMAKE_STRIP) + add_custom_command( + TARGET ${expname} + POST_BUILD + COMMAND ${CMAKE_STRIP} $) + else() + message( + WARNING + "Strip command is not available. The executables will not be stripped." + ) + endif() + endif() +endforeach() diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 2a250275d..e223e9bdc 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,16 +1,19 @@ add_library(libfiction INTERFACE) -target_include_directories(libfiction INTERFACE ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include/) +target_include_directories(libfiction INTERFACE ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include/) target_compile_features(libfiction INTERFACE cxx_std_${CMAKE_CXX_STANDARD}) -target_link_libraries(libfiction INTERFACE fiction::fiction_options fiction::fiction_warnings) +target_link_libraries(libfiction INTERFACE fiction::fiction_options + fiction::fiction_warnings) set_target_properties( - libfiction - PROPERTIES VERSION ${PROJECT_VERSION} - CXX_VISIBILITY_PRESET hidden - VISIBILITY_INLINES_HIDDEN YES) + libfiction + PROPERTIES VERSION ${PROJECT_VERSION} + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN YES) # Add configuration file -configure_file(${PROJECT_SOURCE_DIR}/include/fiction/utils/version_info.hpp.in utils/version_info.hpp) +configure_file(${PROJECT_SOURCE_DIR}/include/fiction/utils/version_info.hpp.in + utils/version_info.hpp) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 96fabc87a..74b8725ea 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,22 +1,29 @@ # Benchmarking (depends on Catch2) -option(FICTION_BENCHMARK "Build fiction benchmarks, which can evaluate the performance of certain code fragments" OFF) -if (FICTION_BENCHMARK) - message(STATUS "Building fiction benchmarks") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/benchmark) -endif () +option( + FICTION_BENCHMARK + "Build fiction benchmarks, which can evaluate the performance of certain code fragments" + OFF) +if(FICTION_BENCHMARK) + message(STATUS "Building fiction benchmarks") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/benchmark) +endif() include_directories(.) file(GLOB_RECURSE FILENAMES */*.cpp) list(FILTER FILENAMES EXCLUDE REGEX "benchmark/.*$") -foreach (FILE IN LISTS FILENAMES) - get_filename_component(NAME ${FILE} NAME_WE) - set(TEST_NAME test_${NAME}) - add_executable(${TEST_NAME} ${FILE}) - target_compile_definitions(${TEST_NAME} INTERFACE CATCH_CONFIG_NO_POSIX_SIGNALS) # make catch2 ignore SIGTERMs sent to applications when timeouts are reached - target_link_libraries(${TEST_NAME} PRIVATE libfiction Catch2::Catch2WithMain) +foreach(FILE IN LISTS FILENAMES) + get_filename_component(NAME ${FILE} NAME_WE) + set(TEST_NAME test_${NAME}) + add_executable(${TEST_NAME} ${FILE}) + target_compile_definitions( + ${TEST_NAME} INTERFACE CATCH_CONFIG_NO_POSIX_SIGNALS) # make catch2 ignore + # SIGTERMs sent to + # applications when + # timeouts are reached + target_link_libraries(${TEST_NAME} PRIVATE libfiction Catch2::Catch2WithMain) - add_test(NAME ${NAME} COMMAND ${TEST_NAME}) # group tests by file - # catch_discover_tests(${TEST_NAME}) -endforeach () + add_test(NAME ${NAME} COMMAND ${TEST_NAME}) # group tests by file + # catch_discover_tests(${TEST_NAME}) +endforeach() diff --git a/test/benchmark/CMakeLists.txt b/test/benchmark/CMakeLists.txt index 2fd432fd9..f3576ea1b 100644 --- a/test/benchmark/CMakeLists.txt +++ b/test/benchmark/CMakeLists.txt @@ -1,20 +1,26 @@ file(GLOB_RECURSE FILENAMES *.cpp) -foreach (FILE IN LISTS FILENAMES) - get_filename_component(NAME ${FILE} NAME_WE) - set(BENCH_NAME bench_${NAME}) - add_executable(${BENCH_NAME} ${FILE}) - target_compile_definitions(${BENCH_NAME} INTERFACE CATCH_CONFIG_NO_POSIX_SIGNALS) # make catch2 ignore SIGTERMs sent to applications when timeouts are reached - target_link_libraries(${BENCH_NAME} PRIVATE fiction::fiction_warnings fiction::fiction_options libfiction Catch2::Catch2WithMain) +foreach(FILE IN LISTS FILENAMES) + get_filename_component(NAME ${FILE} NAME_WE) + set(BENCH_NAME bench_${NAME}) + add_executable(${BENCH_NAME} ${FILE}) + target_compile_definitions( + ${BENCH_NAME} INTERFACE CATCH_CONFIG_NO_POSIX_SIGNALS) # make catch2 ignore + # SIGTERMs sent to + # applications when + # timeouts are + # reached + target_link_libraries( + ${BENCH_NAME} PRIVATE fiction::fiction_warnings fiction::fiction_options + libfiction Catch2::Catch2WithMain) - add_test(NAME ${NAME} COMMAND ${BENCH_NAME}) # group tests by file - # catch_discover_tests(${BENCH_NAME}) + add_test(NAME ${NAME} COMMAND ${BENCH_NAME}) # group tests by file + # catch_discover_tests(${BENCH_NAME}) - if (CMAKE_BUILD_TYPE STREQUAL "Release") - add_custom_command( - TARGET ${BENCH_NAME} - POST_BUILD - COMMAND ${CMAKE_STRIP} $ - ) - endif () -endforeach () + if(CMAKE_BUILD_TYPE STREQUAL "Release") + add_custom_command( + TARGET ${BENCH_NAME} + POST_BUILD + COMMAND ${CMAKE_STRIP} $) + endif() +endforeach()