From 59f6e93ed1b57c39efdd39156913baefef6d8dd3 Mon Sep 17 00:00:00 2001 From: doodspav Date: Sat, 18 Mar 2023 10:46:51 +0000 Subject: [PATCH] GHI #13 Fix Windows PATH issues for tests Signed-off-by: doodspav --- test/CMakeLists.txt | 34 ++++++++++++++++++++++++ test/cmake/OptionVariables.cmake | 13 +++++++++ test/cmake/WindowsDependenciesPath.cmake | 30 +++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 test/cmake/OptionVariables.cmake create mode 100644 test/cmake/WindowsDependenciesPath.cmake diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ba3f3131f..a2f8aa142 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,6 +7,8 @@ project( LANGUAGES CXX ) +include(cmake/OptionVariables.cmake) + # ---- Dependencies ---- @@ -17,6 +19,8 @@ if(PROJECT_IS_TOP_LEVEL) enable_testing() endif() +# for Windows: prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) find_package(GTest REQUIRED) include(GoogleTest) @@ -45,3 +49,33 @@ gtest_add_tests( TARGET patomic_test TEST_LIST patomic_test_TESTS ) + + +# ---- Windows Path Issues ---- + +include(cmake/WindowsDependenciesPath.cmake) +windows_deps_path( + deps_path + patomic::patomic + GTest::gtest_main +) + +# check we're on Windows, and we have SHARED_LIBRARY dependencies +if(NOT deps_path STREQUAL "" AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + + # set environment variable for each test ctest works automatically + if(patomic_test_SET_CTEST_PATH_ENV_WINDOWS) + foreach(test IN LISTS patomic_test_TESTS) + set_property( + TEST "${test}" + PROPERTY ENVIRONMENT "PATH=${deps_path}" + ) + endforeach() + endif() + + # create file with PATH contents for when not running tests through CMake + file(GENERATE + OUTPUT "${PROJECT_BINARY_DIR}/windows_dependencies_path.txt" + CONTENT "${deps_path}" + ) +endif() diff --git a/test/cmake/OptionVariables.cmake b/test/cmake/OptionVariables.cmake new file mode 100644 index 000000000..8a57b9f5f --- /dev/null +++ b/test/cmake/OptionVariables.cmake @@ -0,0 +1,13 @@ +# ---- Windows Tests Path ---- + +# By default we set PATH for tests run with CTest on Windows in order to prevent +# linker errors. +# Due to limitations in CMake, we can only completely override the PATH, rather +# than prepend to it. +# This gives users the option to disable this behaviour. +option( + patomic_test_SET_CTEST_PATH_ENV_WINDOWS + "Set PATH environment variable for tests when run using CTest on Windows" + ON +) +mark_as_advanced(patomic_test_SET_CTEST_PATH_ENV_WINDOWS) diff --git a/test/cmake/WindowsDependenciesPath.cmake b/test/cmake/WindowsDependenciesPath.cmake new file mode 100644 index 000000000..bfe1b8f78 --- /dev/null +++ b/test/cmake/WindowsDependenciesPath.cmake @@ -0,0 +1,30 @@ +# ---- Windows Path Prefix ---- + +# Windows doesn't support rpath, so when linking dynamically the libraries need +# to either be in the same directory or on PATH. +# This function sets a variable to a GENERATOR string that may be prepended to +# path in order to find linked dependencies +# See: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order +# Usage: windows_deps_path( ...) +function(windows_deps_path VAR) + if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(${VAR} "" PARENT_SCOPE) + return() + endif() + + set(path "") + set(glue "") + foreach(target IN LISTS ARGN) + get_target_property(type "${target}" TYPE) + if(type STREQUAL "SHARED_LIBRARY") + set(path "${path}${glue}$") + set(glue "\;") # backslash is important + endif() + endforeach() + + if(NOT path STREQUAL "") + set(${VAR} "${path}" PARENT_SCOPE) + else() + set(${VAR} "" PARENT_SCOPE) + endif() +endfunction()