diff --git a/.github/workflows/test-on-windows.yml b/.github/workflows/test-on-windows.yml index 6df63b00..7d7e5820 100644 --- a/.github/workflows/test-on-windows.yml +++ b/.github/workflows/test-on-windows.yml @@ -20,20 +20,23 @@ jobs: fail-fast: false matrix: config: - - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Debug, cxx_standard: 17} - - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Release, cxx_standard: 17} - - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Debug} - - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Release} - - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Debug, cxx_standard: 17} - - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Release, cxx_standard: 17} - - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Debug} - - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Release} + - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, multi_config: true, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Debug, cxx_standard: 17} + - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, multi_config: true, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Release, cxx_standard: 17} + - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, multi_config: false, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Debug, cxx_standard: 17} + - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, multi_config: false, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Release, cxx_standard: 17} + - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, multi_config: false, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Debug} + - {runs_on: windows-2022, msvc_version_year: 2022, msvc_version: 17, multi_config: false, python_path: "C:\\Python39", msvc_program_files: "C:\\Program Files", config: Release} + - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, multi_config: false, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Debug, cxx_standard: 17} + - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, multi_config: false, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Release, cxx_standard: 17} + - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, multi_config: false, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Debug} + - {runs_on: windows-2019, msvc_version_year: 2019, msvc_version: 16, multi_config: false, python_path: "C:\\Python36", msvc_program_files: "C:\\Program Files (x86)", config: Release} env: PYTHON3_PATH: ${{matrix.config.python_path}} CMAKE_GENERATOR: "Visual Studio ${{matrix.config.msvc_version}} ${{matrix.config.msvc_version_year}}" ADDITIONAL_CMAKE_ARGS: -DFRUIT_USES_BOOST=False -T host=x64 CONFIGURATION: ${{matrix.config.config}} VCVARSALL_DIR: "${{matrix.config.msvc_program_files}}\\Microsoft Visual Studio\\${{matrix.config.msvc_version_year}}\\Enterprise\\VC\\Auxiliary\\Build" + FRUIT_ALLOW_MULTI_CONFIG: ${{matrix.config.multi_config}} steps: - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 @@ -57,6 +60,10 @@ jobs: if: matrix.config.msvc_version >= 16 shell: bash run: echo "ADDITIONAL_CMAKE_ARGS=$ADDITIONAL_CMAKE_ARGS -A x64" >> $GITHUB_ENV + - name: set-fruit-allow-multi-config + if: matrix.config.multi_config + shell: bash + run: echo "ADDITIONAL_CMAKE_ARGS=$ADDITIONAL_CMAKE_ARGS -DFRUIT_ALLOW_MULTI_CONFIG=True" >> $GITHUB_ENV - uses: actions/checkout@v3 - name: install shell: cmd diff --git a/CMakeLists.txt b/CMakeLists.txt index 61681902..7660f0b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,21 @@ if(NOT "${CMAKE_BUILD_TYPE}" MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel) message(FATAL_ERROR "Please re-run CMake, specifying -DCMAKE_BUILD_TYPE=Debug , -DCMAKE_BUILD_TYPE=Release , -DCMAKE_BUILD_TYPE=RelWithDebInfo or -DCMAKE_BUILD_TYPE=MinSizeRel .") endif() -option(BUILD_SHARED_LIBS "Build shared library" ON) +option(FRUIT_ALLOW_MULTI_CONFIG "Allow multi-configuration generator. If this option is OFF, enforces that a single configuration is used." OFF) +if(FRUIT_ALLOW_MULTI_CONFIG) + if(GENERATOR_IS_MULTI_CONFIG) + message(STATUS "${CMAKE_PROJECT_NAME} supports the CMake multi-configuration generator," + " but is optimized for the `CMAKE_BUILD_TYPE` specified in the CMake configuration step," + " and tests will only work in this configuration.") + endif() +else() + # For backward compatibility, only `CMAKE_BUILD_TYPE` configurations can be + # used with the multi-configuration generator. This makes it look like + # single-configuration generator. + set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}") +endif() -# The Visual Studio CMake generators default to multiple configurations, but Fruit doesn't support multi-configuration build directories. -set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}") +option(BUILD_SHARED_LIBS "Build shared library" ON) set(FRUIT_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX compiler flags." FORCE) @@ -43,23 +54,34 @@ if(NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "^(GNU|Clang|AppleClang|MSVC)$") endif() option(FRUIT_ADD_WNO_UNKNOWN_WARNING_OPTION "Add -Wno-unknown-warning-option to the compiler options for GCC, Clang, ICC and AppleClang" ON) - -if("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(GNU|Clang|Intel|AppleClang)$") - set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} -std=c++11 -W -Wall -Wno-missing-braces") - if(${FRUIT_ADD_WNO_UNKNOWN_WARNING_OPTION}) - set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} -Wno-unknown-warning-option") - endif() -elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(MSVC)$") - # TODO: we currently disable the warning C4709 because MSVC emits it even when there is no reason to. Re-enable it when possible. - # TODO: the warning C4141 is disabled, because MSVC emits it ("'inline': used more than once") when a function/method is marked with both __forceinline and inline. - # TODO: the warning C4714 is disabled, MSVC emits it when it decides not to inline a __forceinline function/method. - # The warning C4577 is disabled because we don't need a termination guarantee on exceptions for functions marked with - # 'noexcept'. - # The warning C4530 is disabled because it's triggered by MSVC's STL. - # The warning C5205 is disabled, MSVC emits it for abstract classes in example code with non-virtual destructors, but we never call delete on those (even though std::default_delete is instantiated for those types). - set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} /nologo /FS /W4 /wd4324 /wd4709 /wd4459 /wd4141 /wd4714 /wd4577 /wd4530 /wd5205 /D_SCL_SECURE_NO_WARNINGS") +if (${FRUIT_ADD_WNO_UNKNOWN_WARNING_OPTION}) + set(FRUIT_NO_UNKNOWN_WARNING_FLAGS -Wno-unknown-warning-option) endif() +# Get C++ standard flags. +set(FRUIT_CXX_STANDARD_FLAGS ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}) + +set(FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS}) +set(FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS}) +set(FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS}) +set(FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS}) + +# TODO: we currently disable the warning C4709 because MSVC emits it even when there is no reason to. Re-enable it when possible. +# TODO: the warning C4141 is disabled, because MSVC emits it ("'inline': used more than once") when a function/method is marked with both __forceinline and inline. +# TODO: the warning C4714 is disabled, MSVC emits it when it decides not to inline a __forceinline function/method. +# The warning C4577 is disabled because we don't need a termination guarantee on exceptions for functions marked with +# 'noexcept'. +# The warning C4530 is disabled because it's triggered by MSVC's STL. +# The warning C5205 is disabled, MSVC emits it for abstract classes in example code with non-virtual destructors, but we never call delete on those (even though std::default_delete is instantiated for those types). +set(FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC /nologo /FS /W4 /wd4324 /wd4709 /wd4459 /wd4141 /wd4714 /wd4577 /wd4530 /wd5205 /D_SCL_SECURE_NO_WARNINGS) + +list(APPEND FRUIT_ADDITIONAL_COMPILE_FLAGS + $<$:${FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU}> + $<$:${FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang}> + $<$:${FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel}> + $<$:${FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang}> + $<$:${FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC}>) + option(FRUIT_ENABLE_COVERAGE "Enable collection of test coverage. This is meant to be used by Fruit developers. It's only supported when using GCC on Linux." OFF) if("${FRUIT_ENABLE_COVERAGE}") # We also disable exceptions because otherwise GCC considers every function/method call that could throw as an @@ -80,9 +102,7 @@ if(${FRUIT_USES_BOOST}) endif() find_package(Boost) - if(Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - else() + if(NOT Boost_FOUND) message(FATAL_ERROR "Please re-run CMake, specifying the boost library path as Boost_INCLUDE_DIR, e.g. -DBoost_INCLUDE_DIR=C:\\boost\\boost_1_62_0, or specify -DFRUIT_USES_BOOST=False to not use boost.") endif() endif() @@ -95,17 +115,10 @@ endif() # Unsafe, only for debugging/benchmarking. #set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} -DFRUIT_NO_LOOP_CHECK=1") -add_definitions(${FRUIT_ADDITIONAL_COMPILE_FLAGS}) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FRUIT_ADDITIONAL_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FRUIT_ADDITIONAL_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FRUIT_ADDITIONAL_LINKER_FLAGS}") -if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") - set(FRUIT_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${FRUIT_ADDITIONAL_COMPILE_FLAGS}") -else() - set(FRUIT_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${FRUIT_ADDITIONAL_COMPILE_FLAGS}") -endif() - set(FRUIT_CLANG_TIDY_CHECKS bugprone*,-bugprone-reserved-identifier,-bugprone-exception-escape,clang-analyzer*,performance*,google*,-google-readability*,-google-runtime-references,clang-diagnostic-unused-command-line-argument,misc-macro-parentheses,-clang-diagnostic-dtor-name) @@ -118,8 +131,9 @@ if(${FRUIT_ENABLE_CLANG_TIDY}) -warnings-as-errors=*;) endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) +set(FRUIT_INCLUDE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_BINARY_DIR}/include") # (debug-only) compile switch to get deep template instantiation stacktraces for errors (instead # of the user-friendly default that hides Fruit internals). diff --git a/configuration/CMakeLists.txt b/configuration/CMakeLists.txt index 11d8445f..22950323 100644 --- a/configuration/CMakeLists.txt +++ b/configuration/CMakeLists.txt @@ -1,7 +1,28 @@ include(CheckCXXSourceCompiles) -set(CMAKE_REQUIRED_FLAGS "${FRUIT_COMPILE_FLAGS}") +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "^Clang$") + set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") + set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang") + set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC}) +endif() + +# `CMAKE_REQUIRED_FLAGS` does not accept variables of type list, convert to string. +foreach(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST_ITEM IN LISTS FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST) + set(FRUIT_ADDITIONAL_REQUIRED_FLAGS "${FRUIT_ADDITIONAL_REQUIRED_FLAGS} ${FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST_ITEM}") +endforeach() + +if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${FRUIT_ADDITIONAL_REQUIRED_FLAGS} ${FRUIT_CXX_STANDARD_FLAGS}") +else() + set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${FRUIT_ADDITIONAL_REQUIRED_FLAGS} ${FRUIT_CXX_STANDARD_FLAGS}") +endif() CHECK_CXX_SOURCE_COMPILES(" int main() {} diff --git a/extras/scripts/postsubmit.bat b/extras/scripts/postsubmit.bat index 677cf9b6..6cea3c49 100644 --- a/extras/scripts/postsubmit.bat +++ b/extras/scripts/postsubmit.bat @@ -35,7 +35,7 @@ IF "%CMAKE_GENERATOR%"=="MinGW Makefiles" ( mingw32-make -j12 || exit /b 1 ) ELSE ( type ALL_BUILD.vcxproj - msbuild ALL_BUILD.vcxproj || exit /b 1 + msbuild ALL_BUILD.vcxproj /p:Configuration=%CONFIGURATION% || exit /b 1 ) pip3 install absl-py diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e328cf6..7cee6624 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,27 +1,33 @@ set(FRUIT_SOURCES - memory_pool.cpp -binding_normalization.cpp -demangle_type_name.cpp -component.cpp -fixed_size_allocator.cpp -injector_storage.cpp -normalized_component_storage.cpp -normalized_component_storage_holder.cpp -semistatic_map.cpp -semistatic_graph.cpp) + memory_pool.cpp + binding_normalization.cpp + demangle_type_name.cpp + component.cpp + fixed_size_allocator.cpp + injector_storage.cpp + normalized_component_storage.cpp + normalized_component_storage_holder.cpp + semistatic_map.cpp + semistatic_graph.cpp) -if("${BUILD_SHARED_LIBS}") +if(BUILD_SHARED_LIBS) add_library(fruit SHARED ${FRUIT_SOURCES}) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set_target_properties(fruit PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) - endif() + set_target_properties(fruit PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) else() add_library(fruit STATIC ${FRUIT_SOURCES}) endif() +target_include_directories(fruit PUBLIC ${FRUIT_INCLUDE_DIRS}) +target_compile_options(fruit PUBLIC ${FRUIT_ADDITIONAL_COMPILE_FLAGS}) + +if(FRUIT_USES_BOOST) + find_package(Boost REQUIRED) + target_include_directories(fruit PRIVATE ${Boost_INCLUDE_DIRS}) +endif() + install(TARGETS fruit - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/tests/BUILD b/tests/BUILD index e89f1443..61ca6aec 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -78,7 +78,7 @@ genrule( + "CXX='$(CC)'\n" + "CXX_COMPILER_NAME='GNU'\n" + "CXX_COMPILER_VERSION='5.0.0'\n" - + "FRUIT_COMPILE_FLAGS='$(CC_FLAGS) -std=c++0x -W -Wall -Wno-missing-braces -g -Werror'\n" + + "FRUIT_TEST_COMPILE_FLAGS='$(CC_FLAGS) -std=c++0x -W -Wall -Wno-missing-braces -g -Werror'\n" + "ADDITIONAL_INCLUDE_DIRS=''\n" + "CMAKE_BUILD_TYPE=None\n" + "PATH_TO_COMPILED_FRUIT='third_party/fruit/tests'\n" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 095d3dbb..7b243a33 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,13 +36,38 @@ if(NOT "${WIN32}") endfunction(check_all_python_tests_listed) endif() +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + set(FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS ${FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "^Clang$") + set(FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS ${FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") + set(FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS ${FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang") + set(FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS ${FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang}) +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + set(FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS ${FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC}) +endif() + +# Convert CMake list variable `FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS` to string variable. +# CMake list variable becomes ";" delimiter when expanded. +# Expand list items one by one into a string variable and separate them by spaces. +foreach(FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS_ITEM IN LISTS FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS) + set(FRUIT_TEST_COMPILE_FLAGS "${FRUIT_TEST_COMPILE_FLAGS} ${FRUIT_ADDITIONAL_TEST_COMPILE_FLAGS_ITEM}") +endforeach() + +if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + set(FRUIT_TEST_COMPILE_FLAGS "${FRUIT_TEST_COMPILE_FLAGS} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${FRUIT_CXX_STANDARD_FLAGS}") +else() + set(FRUIT_TEST_COMPILE_FLAGS "${FRUIT_TEST_COMPILE_FLAGS} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${FRUIT_CXX_STANDARD_FLAGS}") +endif() + if ("${FRUIT_TESTS_USE_PRECOMPILED_HEADERS}") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") add_custom_command( OUTPUT test_common-precompiled.h.gch WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS test_common.h fruit - COMMAND bash -c "${CMAKE_CXX_COMPILER} -x c++-header ${FRUIT_COMPILE_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/test_common.h -o test_common-precompiled.h.gch") + COMMAND bash -c "${CMAKE_CXX_COMPILER} -x c++-header ${FRUIT_TEST_COMPILE_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/test_common.h -o test_common-precompiled.h.gch") add_custom_target(test-common-precompiled-header ALL DEPENDS test_common-precompiled.h.gch) # Note that the "test_common-precompiled.h" header doesn't exist, but it's ok because GCC looks for # test_common-precompiled.h.gch first. We don't call the precompiled header test_common.h.gch so that if GCC doesn't @@ -54,7 +79,7 @@ if ("${FRUIT_TESTS_USE_PRECOMPILED_HEADERS}") OUTPUT test_common.pch WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS test_common.h fruit - COMMAND bash -c "${CMAKE_CXX_COMPILER} -x c++-header ${FRUIT_COMPILE_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/test_common.h -o test_common.pch") + COMMAND bash -c "${CMAKE_CXX_COMPILER} -x c++-header ${FRUIT_TEST_COMPILE_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/test_common.h -o test_common.pch") add_custom_target(test-common-precompiled-header ALL DEPENDS test_common.pch) set(FRUIT_TESTONLY_CXXFLAGS "-include-pch ${CMAKE_CURRENT_BINARY_DIR}/test_common.pch") else() @@ -84,15 +109,26 @@ endif() add_library(test_headers_copy STATIC test_common.cpp) target_link_libraries(test_headers_copy fruit) +if(FRUIT_USES_BOOST) + find_package(Boost REQUIRED) + target_include_directories(test_headers_copy PRIVATE ${Boost_INCLUDE_DIRS}) +endif() + # Escape the backslash which is a Windows path separator. string(REPLACE "\\" "\\\\" ADDITIONAL_INCLUDE_DIRS "${Boost_INCLUDE_DIRS}") -file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/fruit_test_config.py" +# `file(GENERATE)` generates a file for each configuration (CMAKE_BUILD_TYPE) +# supported by the current CMake Generator. If you generate a file with an +# absolute path, only the file generated by the first configuration (often +# `Debug` configuration) will remain. +# To support CMake multi-configuration generator, output files in configuration +# subdirectories. +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$/fruit_test_config.py" CONTENT " CXX='${CMAKE_CXX_COMPILER}' CXX_COMPILER_NAME='${CMAKE_CXX_COMPILER_ID}' CXX_COMPILER_VERSION='${CMAKE_CXX_COMPILER_VERSION}' -FRUIT_COMPILE_FLAGS='${FRUIT_COMPILE_FLAGS} ${FRUIT_TESTONLY_CXXFLAGS}' +FRUIT_TEST_COMPILE_FLAGS='${FRUIT_TEST_COMPILE_FLAGS} ${FRUIT_TESTONLY_CXXFLAGS}' ADDITIONAL_INCLUDE_DIRS='${ADDITIONAL_INCLUDE_DIRS}' ADDITIONAL_LINKER_FLAGS='${CMAKE_EXE_LINKER_FLAGS}' RUN_TESTS_UNDER_VALGRIND='${RUN_TESTS_UNDER_VALGRIND_FLAG}' @@ -109,6 +145,12 @@ PATH_TO_FRUIT_TEST_HEADERS='${CMAKE_CURRENT_SOURCE_DIR}' ENABLE_COVERAGE=${FRUIT_ENABLE_COVERAGE_PYTHON_BOOL} ") +add_custom_target(copy_fruit_test_config ALL + BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/fruit_test_config.py" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/fruit_test_config.py" "${CMAKE_CURRENT_BINARY_DIR}/fruit_test_config.py" + VERBATIM + COMMAND_EXPAND_LISTS) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pytest.ini" CONTENT " [pytest] diff --git a/tests/fruit_test_common.py b/tests/fruit_test_common.py index 36e5b20f..88b21b70 100644 --- a/tests/fruit_test_common.py +++ b/tests/fruit_test_common.py @@ -142,7 +142,7 @@ def compile_and_link(self, source, include_dirs, output_file_name, args=[]): def _compile(self, include_dirs, args): include_flags = ['-I%s' % include_dir for include_dir in include_dirs] args = ( - FRUIT_COMPILE_FLAGS.split() + FRUIT_TEST_COMPILE_FLAGS.split() + include_flags + ['-g0', '-Werror'] + args @@ -181,7 +181,7 @@ def compile_and_link(self, source, include_dirs, output_file_name, args=[]): def _compile(self, include_dirs, args): include_flags = ['-I%s' % include_dir for include_dir in include_dirs] args = ( - FRUIT_COMPILE_FLAGS.split() + FRUIT_TEST_COMPILE_FLAGS.split() + include_flags + ['/WX'] + args