From af15856d944937d008f08b2d1e6a0b69a926c8bc Mon Sep 17 00:00:00 2001
From: Sam Yates <yates@cscs.ch>
Date: Tue, 27 Nov 2018 16:18:35 +0100
Subject: [PATCH] Workaround for CMake 3.12 bug passing -thread to nvcc (#649)

CMake wants to run a device link pass with nvcc despite
there being no CUDA seperable compilation enabled anywhere,
and then passes on -pthread to that unnecessary nvcc
invocation when we use the Threads dependency. The latter,
at least, is fixed in CMake 3.13.

We used the prefer -pthread option for compatibility with
our earlier build configuration; turning it off will
hopefully have no consequence.

We also enable device linking on the arbor library. Which
is not needed, but if they are going to insist on doing it,
it should be on the library rather than the executable.

CMake then goes and does it on the executable anyway. Great.

Fixes #645.
---
 CMakeLists.txt              | 26 ++++++++++++++++++++++++--
 arbor/CMakeLists.txt        |  1 +
 cmake/arbor-config.cmake.in | 17 +++++++++++++++++
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index eeafe753..6a3063f0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,8 +66,9 @@ if (NOT CMAKE_BUILD_TYPE)
     set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "debug" "release")
 endif()
 
-# When we find threads, prefer -pthread option.
-set(THREADS_PREFER_PTHREAD_FLAG ON)
+# When we find threads, prefer not to use the -pthread option
+# in order to avoid a CMake 3.12 issue.
+set(THREADS_PREFER_PTHREAD_FLAG OFF)
 
 # Add CUDA as a language if GPU support requested.
 # (This has to be set early so as to enable CUDA tests in generator
@@ -329,6 +330,27 @@ write_basic_package_version_file(
 # Template file will use contents of arbor_export_dependencies to include the
 # required `find_dependency` statements, and arbor_supported_components will
 # be used to check feature support.
+#
+# To avoid CMake users of the installed arbor library conditionally requiring
+# that they add CUDA to their project language, explicitly munge the import
+# language and library dependencies on the installed target if ARB_WITH_GPU
+# is set, via the variables arbor_override_import_lang and arbor_add_import_libs.
+# arbor_build_config records our build type in a way compatible with the
+# generated export cmake files.
+
+set(arbor_build_config NOCONFIG)
+if(CMAKE_BUILD_TYPE)
+    string(TOUPPER "${CMAKE_BUILD_TYPE}" arbor_build_config)
+endif()
+
+set(arbor_override_import_lang)
+set(arbor_add_import_libs)
+
+if(ARB_WITH_GPU)
+    set(arbor_override_import_lang CXX)
+    find_package(CUDA REQUIRED)
+    set(arbor_add_import_libs ${CUDA_LIBRARIES})
+endif()
 
 configure_file(
     cmake/arbor-config.cmake.in
diff --git a/arbor/CMakeLists.txt b/arbor/CMakeLists.txt
index 6664cb56..b8d199bc 100644
--- a/arbor/CMakeLists.txt
+++ b/arbor/CMakeLists.txt
@@ -111,6 +111,7 @@ add_library(arbor ${arbor_sources} ${arbor_mechanism_sources})
 add_dependencies(arbor build_all_mods)
 target_link_libraries(arbor PRIVATE arbor-private-deps arbor-private-headers)
 target_link_libraries(arbor PUBLIC arbor-public-deps arbor-public-headers)
+set_target_properties(arbor PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
 
 install(TARGETS arbor EXPORT arbor-targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
diff --git a/cmake/arbor-config.cmake.in b/cmake/arbor-config.cmake.in
index 71448ec5..2d8a3cb6 100644
--- a/cmake/arbor-config.cmake.in
+++ b/cmake/arbor-config.cmake.in
@@ -15,3 +15,20 @@ foreach(component ${arbor_FIND_COMPONENTS})
     endif()
 endforeach()
 
+# Patch properties to remove unnecessary external CUDA dependencies.
+
+set(_override_lang @arbor_override_import_lang@)
+if(_override_lang)
+    set_target_properties(arbor::arbor PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_@arbor_build_config@ "${_override_lang}")
+endif()
+
+set(_add_libs @arbor_add_import_libs@)
+if(_add_libs)
+    get_target_property(_arbor_interface_libs arbor::arbor INTERFACE_LINK_LIBRARIES)
+    if(_arbor_interface_libs)
+        list(APPEND _arbor_interface_libs ${_add_libs})
+    else()
+        set(_arbor_interface_libs ${_add_libs})
+    endif()
+    set_target_properties(arbor::arbor PROPERTIES INTERFACE_LINK_LIBRARIES "${_arbor_interface_libs}")
+endif()
-- 
GitLab