diff --git a/.mp-units.imp b/.mp-units.imp new file mode 100644 index 00000000..27b7864d --- /dev/null +++ b/.mp-units.imp @@ -0,0 +1,7 @@ +[ + { include: ["", "public", "", "public"] }, + { include: ["", "public", "", "public"] }, + { include: ["", "public", "", "public"] }, + { include: ["", "public", "", "public"] }, + { symbol: ["abs", "private", "", public]} +] diff --git a/CMakeLists.txt b/CMakeLists.txt index e003679a..93a07dcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,9 +34,23 @@ set_warnings() # set all contracts checking in a Debug build add_compile_definitions($<$:gsl_CONFIG_CONTRACT_CHECKING_AUDIT>) -# enable static analysis +# enable include-what-you-use +option(UNITS_IWYU "Enables include-what-you-use" OFF) +if(UNITS_IWYU) + include(include-what-you-use) + set_iwyu( + MAPPING_FILE "${PROJECT_SOURCE_DIR}/.mp-units.imp" + NO_FORWARD_DECLARATIONS + QUOTED_INCLUDES_FIRST + MAX_LINE_LENGTH 120 + NO_COMMENTS + ) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(UNITS_AS_SYSTEM_HEADERS ON) + endif() +endif() + #enable_clang_tidy() -#enable_iwyu() # add project code add_subdirectory(src) diff --git a/cmake/include-what-you-use.cmake b/cmake/include-what-you-use.cmake new file mode 100644 index 00000000..8c0f81c5 --- /dev/null +++ b/cmake/include-what-you-use.cmake @@ -0,0 +1,142 @@ +# The MIT License (MIT) +# +# Copyright (c) 2017 Mateusz Pusz +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +cmake_minimum_required(VERSION 3.7) + +if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # run IWYU only for clang compiler + # other compilers will generate i.e. unknown compilation flags warnings + return() +endif() + +set(IWYU_VERBOSITY_LEVEL 3 CACHE STRING "IWYU verbosity level (the higher the level, the more output)") + +macro(_find_iwyu) + find_program(_iwyu_path NAMES "include-what-you-use") + if(NOT _iwyu_path) + message(WARNING "'include-what-you-use' executable not found!") + return() + endif() +endmacro() + +macro(_iwyu_args_append arg) + list(APPEND _iwyu_args "-Xiwyu" "${arg}") +endmacro() + +macro(_iwyu_args_append_if_present option arg) + if(_set_iwyu_${option}) + _iwyu_args_append("${arg}") + endif() +endmacro() + +macro(_process_iwyu_arguments offset) + set(_options NO_DEFAULT_MAPPINGS PCH_IN_CODE TRANSITIVE_INCLUDES_ONLY NO_COMMENTS NO_FORWARD_DECLARATIONS CXX17_NAMESPACES QUOTED_INCLUDES_FIRST) + set(_one_value_args MAPPING_FILE MAX_LINE_LENGTH) + set(_multi_value_args KEEP) + cmake_parse_arguments(PARSE_ARGV ${offset} _set_iwyu "${_options}" "${_one_value_args}" "${_multi_value_args}") + + # validate and process arguments + if(${prefix}_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid arguments '${${prefix}_UNPARSED_ARGUMENTS}'") + endif() + + if(_set_iwyu_KEEP) + foreach(_pattern ${_set_iwyu_KEEP}) + _iwyu_args_append("--keep=${_pattern}") + endforeach() + endif() + + if(_set_iwyu_MAPPING_FILE) + if(NOT EXISTS ${_set_iwyu_MAPPING_FILE}) + message(FATAL_ERROR "IWYU: Mapping file '${_set_iwyu_MAPPING_FILE}' does not exist") + endif() + _iwyu_args_append("--mapping_file=${_set_iwyu_MAPPING_FILE}") + endif() + + if(_set_iwyu_MAX_LINE_LENGTH) + if(NOT _set_iwyu_MAX_LINE_LENGTH GREATER 0) + message(FATAL_ERROR "IWYU: Invalid MAX_LINE_LENGTH value = '${_set_iwyu_MAX_LINE_LENGTH}") + endif() + _iwyu_args_append("--max_line_length=${_set_iwyu_MAX_LINE_LENGTH}") + endif() + + _iwyu_args_append_if_present(NO_DEFAULT_MAPPINGS "--no_default_mappings") + _iwyu_args_append_if_present(PCH_IN_CODE "--pch_in_code") + _iwyu_args_append_if_present(TRANSITIVE_INCLUDES_ONLY "--transitive_includes_only") + _iwyu_args_append_if_present(NO_COMMENTS "--no_comments") + _iwyu_args_append_if_present(NO_FORWARD_DECLARATIONS "--no_fwd_decls") + _iwyu_args_append_if_present(CXX17_NAMESPACES "--cxx17ns") + _iwyu_args_append_if_present(QUOTED_INCLUDES_FIRST "--quoted_includes_first") + + _iwyu_args_append("--verbose=${IWYU_VERBOSITY_LEVEL}") +endmacro() + +# +# set_target_iwyu(TargetName +# [KEEP pattern...] +# [MAPPING_FILE file] +# [NO_DEFAULT_MAPPINGS] +# [PCH_IN_CODE] +# [TRANSITIVE_INCLUDES_ONLY] +# [MAX_LINE_LENGTH length] +# [NO_COMMENTS] +# [NO_FORWARD_DECLARATIONS] +# [CXX17_NAMESPACES] +# [QUOTED_INCLUDES_FIRST]) +# +function(set_target_iwyu target) + _find_iwyu() + _process_iwyu_arguments(1) + + message(STATUS "Setting include-what-you-use for '${target}'") + message(STATUS " Path: ${_iwyu_path}") + message(STATUS " Arguments: ${_iwyu_args}") + message(STATUS "Setting include-what-you-use for '${target}' - done") + + set_target_properties(${target} PROPERTIES + CXX_INCLUDE_WHAT_YOU_USE "${_iwyu_path};${_iwyu_args}" + ) +endfunction() + +# +# set_target_iwyu([KEEP patterns...] +# [MAPPING_FILE file] +# [NO_DEFAULT_MAPPINGS] +# [PCH_IN_CODE] +# [TRANSITIVE_INCLUDES_ONLY] +# [MAX_LINE_LENGTH length] +# [NO_COMMENTS] +# [NO_FORWARD_DECLARATIONS] +# [CXX17_NAMESPACES] +# [QUOTED_INCLUDES_FIRST]) +# +function(set_iwyu) + _find_iwyu() + _process_iwyu_arguments(0) + + message(STATUS "Setting include-what-you-use") + message(STATUS " Path: ${_iwyu_path}") + message(STATUS " Arguments: ${_iwyu_args}") + message(STATUS "Setting include-what-you-use - done") + + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${_iwyu_path};${_iwyu_args}" PARENT_SCOPE) +endfunction() diff --git a/cmake/static_analysis.cmake b/cmake/static_analysis.cmake index 28b4001c..28f00e9c 100644 --- a/cmake/static_analysis.cmake +++ b/cmake/static_analysis.cmake @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -cmake_minimum_required(VERSION 3.2) +cmake_minimum_required(VERSION 3.3) macro(enable_clang_tidy) find_program(clang_tidy_cmd NAMES "clang-tidy") @@ -33,13 +33,3 @@ macro(enable_clang_tidy) set(CMAKE_CXX_CLANG_TIDY "${clang_tidy_cmd}") endif() endmacro() - - -macro(enable_iwyu) - find_program(iwyu_cmd NAMES "include-what-you-use") - if(NOT iwyu_cmd) - message(WARNING "include-what-you-use not found!") - else() - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${iwyu_cmd}") - endif() -endmacro() diff --git a/docs/usage.rst b/docs/usage.rst index f75d00be..2fef1d3d 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -159,6 +159,16 @@ UNITS_DOWNCAST_MODE Equivalent to `downcast_mode`_. +UNITS_AS_SYSTEM_HEADERS ++++++++++++++++++++++++ + +**Values**: ``ON``/``OFF`` + +**Defaulted to**: ``OFF`` + +Exports library as system headers. + + UNITS_BUILD_DOCS ++++++++++++++++ @@ -169,6 +179,17 @@ UNITS_BUILD_DOCS Enables project documentation generation. +UNITS_IWYU +++++++++++ + +**Values**: ``ON``/``OFF`` + +**Defaulted to**: ``OFF`` + +Enables include-what-you-use when compiling with a clang compiler. +Additionally turns on `UNITS_AS_SYSTEM_HEADERS`. + + Installation and Reuse ---------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 446c6a1e..23119f18 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,11 @@ project(mp-units LANGUAGES CXX ) +option(UNITS_AS_SYSTEM_HEADERS "Exports library as system headers" OFF) +if(UNITS_AS_SYSTEM_HEADERS) + set(units_as_system SYSTEM) +endif() + list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") include(AddUnitsModule) diff --git a/src/cmake/AddUnitsModule.cmake b/src/cmake/AddUnitsModule.cmake index 9d51c582..a9c9a83c 100644 --- a/src/cmake/AddUnitsModule.cmake +++ b/src/cmake/AddUnitsModule.cmake @@ -28,7 +28,7 @@ cmake_minimum_required(VERSION 3.15) function(add_units_module name) add_library(mp-units-${name} INTERFACE) target_link_libraries(mp-units-${name} INTERFACE ${ARGN}) - target_include_directories(mp-units-${name} INTERFACE + target_include_directories(mp-units-${name} ${units_as_system} INTERFACE $ $ ) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ede16080..d4f4f06c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -39,7 +39,7 @@ target_compile_features(mp-units-core INTERFACE cxx_std_20) target_link_libraries(mp-units-core INTERFACE gsl::gsl-lite ) -target_include_directories(mp-units-core INTERFACE +target_include_directories(mp-units-core ${units_as_system} INTERFACE $ $ )