From 6e270958a216821676998e8f6d8f524900156d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Fri, 21 Feb 2020 21:15:45 +0100 Subject: [PATCH] Add development build option to CMake and enable it on CI Development build enables warnings and and `Werror` or equivalent. --- .travis.yml | 4 +- CMake/MiscFunctions.cmake | 66 +++++++++++++++++++ CMakeLists.txt | 19 ++++-- examples/CMakeLists.txt | 17 ++--- src/CMakeLists.txt | 28 +++++++- tests/CMakeLists.txt | 25 +------ tests/ExtraTests/CMakeLists.txt | 7 ++ .../misc/appveyorBuildConfigurationScript.bat | 6 +- 8 files changed, 124 insertions(+), 48 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3644cb08..fe13d3af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -185,9 +185,9 @@ before_script: fi # Use Debug builds for running Valgrind and building examples - - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE} -DCATCH_BUILD_EXTRA_TESTS=${EXTRAS} -DCMAKE_CXX_STANDARD=${CPP_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=On -DCMAKE_CXX_EXTENSIONS=OFF + - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE} -DCATCH_BUILD_EXTRA_TESTS=${EXTRAS} -DCMAKE_CXX_STANDARD=${CPP_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=On -DCMAKE_CXX_EXTENSIONS=OFF -DCATCH_DEVELOPMENT_BUILD=ON # Don't bother with release build for coverage build - - cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DCMAKE_CXX_STANDARD=${CPP_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=On -DCMAKE_CXX_EXTENSIONS=OFF + - cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DCMAKE_CXX_STANDARD=${CPP_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=On -DCMAKE_CXX_EXTENSIONS=OFF -DCATCH_DEVELOPMENT_BUILD=ON script: diff --git a/CMake/MiscFunctions.cmake b/CMake/MiscFunctions.cmake index 262f7cd8..0e95517a 100644 --- a/CMake/MiscFunctions.cmake +++ b/CMake/MiscFunctions.cmake @@ -24,3 +24,69 @@ function(CheckFileListRec LIST_VAR FOLDER) message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}") endforeach() endfunction() + +include(CheckCXXCompilerFlag) +function(add_cxx_flag_if_supported_to_targets flagname targets) + check_cxx_compiler_flag("${flagname}" HAVE_FLAG_${flagname}) + + if (HAVE_FLAG_${flagname}) + foreach(target ${targets}) + target_compile_options(${target} PUBLIC ${flagname}) + endforeach() + endif() +endfunction() + +# Assumes that it is only called for development builds, where warnings +# and Werror is desired, so it also enables Werror. +function(add_warnings_to_targets targets) + LIST(LENGTH targets TARGETS_LEN) + # For now we just assume 2 possibilities: msvc and msvc-like compilers, + # and other. + if (MSVC) + foreach(target ${targets}) + # Force MSVC to consider everything as encoded in utf-8 + target_compile_options( ${target} PRIVATE /utf-8 ) + # Enable Werror equivalent + if (CATCH_ENABLE_WERROR) + target_compile_options( ${target} PRIVATE /WX ) + endif() + + # MSVC is currently handled specially + if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) + STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level + target_compile_options( ${target} PRIVATE /w44265 /w44061 /w44062 /w45038 ) + endif() + endforeach() + + endif() + + if (NOT MSVC) + set(CHECKED_WARNING_FLAGS + "-Wall" + "-Wextra" + "-Wpedantic" + "-Wweak-vtables" + "-Wunreachable-code" + "-Wmissing-declarations" + "-Wexit-time-destructors" + "-Wglobal-constructors" + "-Wmissing-noreturn" + "-Wparentheses" + "-Wextra-semi-stmt" + "-Wunreachable-code" + "-Wstrict-aliasing" + "-Wreturn-std-move" + "-Wmissing-braces" + ) + foreach(warning ${CHECKED_WARNING_FLAGS}) + add_cxx_flag_if_supported_to_targets(${warning} "${targets}") + endforeach() + + if (CATCH_ENABLE_WERROR) + foreach(target ${targets}) + # Enable Werror equivalent + target_compile_options( ${target} PRIVATE -Werror ) + endforeach() + endif() + endif() +endfunction() diff --git a/CMakeLists.txt b/CMakeLists.txt index 98785d57..37a930ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,17 +6,19 @@ if(NOT DEFINED PROJECT_NAME) set(NOT_SUBPROJECT ON) endif() -option(CATCH_BUILD_TESTING "Build SelfTest project" ON) -option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF) -option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF) -option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF) option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON) option(CATCH_INSTALL_EXTRAS "Install extras alongside library" ON) +option(CATCH_DEVELOPMENT_BUILD "Build tests, enable warnings, enable Werror, etc" ON) +include(CMakeDependentOption) +cmake_dependent_option(CATCH_BUILD_TESTING "Build the SelfTest project" ON "CATCH_DEVELOPMENT_BUILD" OFF) +cmake_dependent_option(CATCH_BUILD_EXAMPLES "Build code examples" OFF "CATCH_DEVELOPMENT_BUILD" OFF) +cmake_dependent_option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF "CATCH_DEVELOPMENT_BUILD" OFF) +cmake_dependent_option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF "CATCH_DEVELOPMENT_BUILD" OFF) +cmake_dependent_option(CATCH_ENABLE_WERROR "Enables Werror during build" ON "CATCH_DEVELOPMENT_BUILD" OFF) set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2") - # Catch2's build breaks if done in-tree. You probably should not build # things in tree anyway, but we can allow projects that include Catch2 # as a subproject to build in-tree as long as it is not in our tree. @@ -29,7 +31,6 @@ project(Catch2 LANGUAGES CXX VERSION 3.0.0) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") - include(GNUInstallDirs) include(CMakePackageConfigHelpers) include(CTest) @@ -61,6 +62,12 @@ if(CATCH_BUILD_EXTRA_TESTS) add_subdirectory(tests/ExtraTests) endif() + +if (CATCH_DEVELOPMENT_BUILD) + add_warnings_to_targets("${CATCH_WARNING_TARGETS}") +endif() + + #option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF) #option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON) # diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ecc14b8f..ac68e664 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -56,17 +56,8 @@ foreach( name ${ALL_EXAMPLE_TARGETS} ) target_link_libraries( ${name} Catch2 ) set_property(TARGET ${name} PROPERTY CXX_STANDARD 14) set_property(TARGET ${name} PROPERTY CXX_EXTENSIONS OFF) - - # Add desired warnings - if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" ) - target_compile_options( ${name} PRIVATE -Wall -Wextra -Wunreachable-code ) - endif() - # Clang specific warning go here - if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) - # Actually keep these - target_compile_options( ${name} PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn ) - endif() - if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) - target_compile_options( ${name} PRIVATE /W4 /w44265 /WX ) - endif() endforeach() + + +list(APPEND CATCH_WARNING_TARGETS ${ALL_EXAMPLE_TARGETS}) +set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d08e2e9c..43f9c63d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -233,7 +233,6 @@ add_library(Catch2 STATIC ${BENCHMARK_HEADERS} ${BENCHMARK_SOURCES} ) -add_library(Catch2::Catch2 ALIAS Catch2) if (ANDROID) target_link_libraries(Catch2 INTERFACE log) @@ -278,7 +277,6 @@ add_library(Catch2::Catch2Main ALIAS Catch2Main) target_link_libraries(Catch2Main PUBLIC Catch2) - if (NOT_SUBPROJECT) # create and install an export set for catch target as Catch2::Catch install( @@ -320,4 +318,30 @@ if (CATCH_BUILD_EXAMPLES OR CATCH_BUILD_EXTRA_TESTS) $ $ ) + target_compile_features(Catch2_buildall_interface + INTERFACE + cxx_alignas + cxx_alignof + cxx_attributes + cxx_auto_type + cxx_constexpr + cxx_defaulted_functions + cxx_deleted_functions + cxx_final + cxx_lambdas + cxx_noexcept + cxx_override + cxx_range_for + cxx_rvalue_references + cxx_static_assert + cxx_strong_enums + cxx_trailing_return_types + cxx_unicode_literals + cxx_user_literals + cxx_variable_templates + cxx_variadic_macros + ) endif() + +list(APPEND CATCH_WARNING_TARGETS Catch2 Catch2Main) +set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7dcb819f..f285ea31 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -97,28 +97,6 @@ if (CATCH_ENABLE_COVERAGE) coverage_evaluate() endif() -# Add per compiler options -if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" ) - target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations ) - if (CATCH_ENABLE_WERROR) - target_compile_options( SelfTest PRIVATE -Werror ) - endif() -endif() -# Clang specific options go here -if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) - target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn ) -endif() -if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) - STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level - target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 /w45038 ) - if (CATCH_ENABLE_WERROR) - target_compile_options( SelfTest PRIVATE /WX) - endif() - # Force MSVC to consider everything as encoded in utf-8 - target_compile_options( SelfTest PRIVATE /utf-8 ) -endif() - - # configure unit tests via CTest add_test(NAME RunTests COMMAND $) set_tests_properties(RunTests PROPERTIES @@ -241,3 +219,6 @@ if (CATCH_USE_VALGRIND) add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $ --list-tags) set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks") endif() + +list(APPEND CATCH_WARNING_TARGETS SelfTest) +set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE) diff --git a/tests/ExtraTests/CMakeLists.txt b/tests/ExtraTests/CMakeLists.txt index b89af55e..8f391e48 100644 --- a/tests/ExtraTests/CMakeLists.txt +++ b/tests/ExtraTests/CMakeLists.txt @@ -128,6 +128,7 @@ if (MSVC) set_property( TARGET WindowsHeader PROPERTY CXX_EXTENSIONS OFF ) target_link_libraries( WindowsHeader Catch2 ) add_test(NAME WindowsHeader COMMAND WindowsHeader -r compact) + list(APPEND CATCH_WARNING_TARGETS ${EXTRA_TEST_BINARIES} WindowsHeader) endif() #add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp) @@ -155,3 +156,9 @@ foreach( test ${EXTRA_TEST_BINARIES} ) set_property( TARGET ${test} PROPERTY CXX_STANDARD_REQUIRED ON ) set_property( TARGET ${test} PROPERTY CXX_EXTENSIONS OFF ) endforeach() + +# Notice that we are modifying EXTRA_TEST_BINARIES destructively, do not +# use it after this point! +list(FILTER EXTRA_TEST_BINARIES EXCLUDE REGEX "DisabledExceptions.*") +list(APPEND CATCH_WARNING_TARGETS ${EXTRA_TEST_BINARIES}) +set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE) diff --git a/tools/misc/appveyorBuildConfigurationScript.bat b/tools/misc/appveyorBuildConfigurationScript.bat index 6241b781..1a01a6af 100644 --- a/tools/misc/appveyorBuildConfigurationScript.bat +++ b/tools/misc/appveyorBuildConfigurationScript.bat @@ -10,12 +10,12 @@ if "%CONFIGURATION%"=="Debug" ( @REM # coverage needs to build the special helper as well as the main cmake -Htools/misc -Bbuild-misc -A%PLATFORM% || exit /b !ERRORLEVEL! cmake --build build-misc || exit /b !ERRORLEVEL! - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% || exit /b !ERRORLEVEL! + cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% -DCATCH_DEVELOPMENT_BUILD=ON || exit /b !ERRORLEVEL! ) else ( @REM # We know that coverage is 0 - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% || exit /b !ERRORLEVEL! + cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% -DCATCH_DEVELOPMENT_BUILD=ON || exit /b !ERRORLEVEL! ) ) if "%CONFIGURATION%"=="Release" ( - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% || exit /b !ERRORLEVEL! + cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_DEVELOPMENT_BUILD=ON || exit /b !ERRORLEVEL! )