From 8740e5a322972a1145c165c19853812c23fd66cc Mon Sep 17 00:00:00 2001
From: thorstenhater <24411438+thorstenhater@users.noreply.github.com>
Date: Thu, 25 Feb 2021 13:35:56 +0100
Subject: [PATCH] Use test programs to enable ``std::filesystem`` (#1392)

* Use CMake check_cxx_source_compiles and check_cxx_source_runs to detect how std::filesystem
is enabled. The probes are executed first, if none succeeds, we use link-only to cover the possibility that we
are cross-compiling.
---
 cmake/CompilerOptions.cmake   | 70 +++++++++++++++++++++++++++++------
 mechanisms/BuildModules.cmake |  2 +
 test/unit/CMakeLists.txt      |  3 +-
 3 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake
index cf8b248f..d303b18f 100644
--- a/cmake/CompilerOptions.cmake
+++ b/cmake/CompilerOptions.cmake
@@ -1,5 +1,8 @@
-# Compiler-aware compiler options
+include(CheckCXXSourceCompiles)
+include(CheckCXXSourceRuns)
+include(CMakePushCheckState)
 
+# Compiler-aware compiler options
 set(CXXOPT_DEBUG "-g")
 set(CXXOPT_CXX11 "-std=c++11")
 
@@ -18,20 +21,63 @@ if(${ARBDEV_COLOR})
 endif()
 
 # A library to collect compiler-specific linking adjustments.
-
 add_library(arbor-compiler-compat INTERFACE)
-# TODO Remove when upgrading GCC.
-if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
-    target_link_libraries(arbor-compiler-compat INTERFACE stdc++fs)
-  endif()
-endif()
-# TODO Remove when upgrading Clang
-if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
-    target_link_libraries(arbor-compiler-compat INTERFACE stdc++fs)
+
+cmake_push_check_state()
+# Check how to use std::filesystem
+string(CONFIGURE [[
+  #include <cstdio>
+  #include <filesystem>
+  int main() {
+    auto cwd = std::filesystem::current_path();
+    std::printf("%s %d", cwd.c_str(), std::filesystem::exists(cwd));
+  }
+  ]] arb_cxx_fs_test @ONLY)
+
+# Remember some state to avoid constant push/pop
+set(arb_req_libs ${CMAKE_REQUIRED_LIBRARIES})
+
+# Test whether we can run probes
+set(STD_FS_LIB "")
+set(CMAKE_REQUIRED_FLAGS -std=c++17 ${CMAKE_REQUIRED_FLAGS})
+check_cxx_source_runs("${arb_cxx_fs_test}" STD_FS_PLAIN_RUN)
+
+if(NOT STD_FS_PLAIN_RUN)
+  set(STD_FS_LIB -lstdc++fs)
+  set(CMAKE_REQUIRED_LIBRARIES ${arb_req_libs} ${STD_FS_LIB})
+  check_cxx_source_runs("${arb_cxx_fs_test}" STD_FS_STDCXX_RUN)
+
+  if(NOT STD_FS_STDCXX_RUN)
+    set(STD_FS_LIB -lc++fs)
+    set(CMAKE_REQUIRED_LIBRARIES ${arb_req_libs} ${STD_FS_LIB})
+    check_cxx_source_runs("${arb_cxx_fs_test}" STD_FS_CXX_RUN)
+
+    # If running is not ok, we are possibly cross-compiling, so check linking as a fallback
+    if(NOT STD_FS_CXX_RUN)
+      check_cxx_source_compiles("${arb_cxx_fs_test}" STD_FS_PLAIN_LNK)
+
+      if(NOT STD_FS_PLAIN_LNK)
+        set(STD_FS_LIB -lstdc++fs)
+        set(CMAKE_REQUIRED_LIBRARIES ${arb_req_libs} ${STD_FS_LIB})
+        check_cxx_source_compiles("${arb_cxx_fs_test}" STD_FS_STDCXX_LNK)
+
+        if(NOT STD_FS_STDCXX_LNK)
+          set(STD_FS_LIB -lc++fs)
+          set(CMAKE_REQUIRED_LIBRARIES ${arb_req_libs} ${STD_FS_LIB})
+          check_cxx_source_compiles("${arb_cxx_fs_test}" STD_FS_CXX_LNK)
+
+          if(NOT STD_FS_CXX_LNK)
+            message(FATAL_ERROR "Could not enable support for std::filesystem")
+          endif()
+        endif()
+      endif()
+    endif()
   endif()
 endif()
+cmake_pop_check_state()
+
+target_link_libraries(arbor-compiler-compat INTERFACE ${STD_FS_LIB})
+
 install(TARGETS arbor-compiler-compat EXPORT arbor-targets)
 
 # Warning options: disable specific spurious warnings as required.
diff --git a/mechanisms/BuildModules.cmake b/mechanisms/BuildModules.cmake
index 94c494ae..b1770356 100644
--- a/mechanisms/BuildModules.cmake
+++ b/mechanisms/BuildModules.cmake
@@ -75,6 +75,8 @@ function("make_catalogue")
     message("Arbor source tree:    ${MK_CAT_ARBOR}")
     message("Build as standalone:  ${MK_CAT_STANDALONE}")
     message("Arbor arch:           ${ARB_CXXOPT_ARCH}")
+    message("Arbor cxx compiler:   ${ARB_CXX}")
+    message("Current cxx compiler: ${CMAKE_CXX_COMPILER}")
   endif()
 
   file(MAKE_DIRECTORY "${MK_CAT_OUT_DIR}")
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index dde25eb7..7e649daa 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -214,7 +214,8 @@ if(${CMAKE_POSITION_INDEPENDENT_CODE})
     OUTPUT "CAT_DUMMY_SOURCES"
     MECHS dummy
     ARBOR "${PROJECT_SOURCE_DIR}"
-    STANDALONE ON)
+    STANDALONE ON
+    VERBOSE ON)
   target_compile_definitions(unit PRIVATE USE_DYNAMIC_CATALOGUES)
   add_dependencies(unit dummy-catalogue)
 endif()
-- 
GitLab