From 53ee40359fe5e94910a5ce82cf20764b78c7230f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6=20Fahlke?= <jorrit@jorrit.de>
Date: Tue, 27 Sep 2016 10:45:20 +0200
Subject: [PATCH] [cmake][Vc] Use the HAVE/ENABLE trick for Vc.

This solves a problem that is introduced by unconditionally setting
`HAVE_VC=1` in config.h:

If a compilation unit is compiled without the `-fabi-version=6` or similar
then the compilers vector types (which are used by Vc under the hood if
available) will mangle to the same string, irrespective of the number of lanes
they actually use.  This makes certain overloaded function definitions in the
Vc headers clash, since their only difference is whether they apply to
e.g. AVX types (4 lanes) or SSE types (2 lanes).

This is normally not a problem, since any program that uses Vc needs to have a
call to `add_dune_vc_flags()` in `CMakeLists.txt`.  However, since I now want
to put support for vectorized types into the `fmatrix.hh`, any compilation
unit that uses a `FieldMatrix` will automatically include the Vc headers
because `config.h` unconditionally sets `HAVE_VC=1`.

Using the HAVE/ENABLE-trick makes sure that the value of `HAVE_VC` is in sync
with the compilation flags.

Note: I tried using `COMPILE_DEFINITION` for `ENABLE_VC=1` in
      `dune_register_package_flags()`, but that will always add
      `-DENABLE_VC=1` to the compiler command line, even when
      `add_dune_vc_flags()` hasn't been called for that target, and
      `dune_enable_all_packages()` isn't in use.  Using `COMPILE_OPTIONS`
      instead seems inappropriate, but does work.
---
 cmake/modules/AddVcFlags.cmake | 3 ++-
 config.h.cmake                 | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/cmake/modules/AddVcFlags.cmake b/cmake/modules/AddVcFlags.cmake
index 0ca689adb..01d2494a9 100644
--- a/cmake/modules/AddVcFlags.cmake
+++ b/cmake/modules/AddVcFlags.cmake
@@ -18,13 +18,14 @@ function(add_dune_vc_flags _targets)
     foreach(_target ${_targets})
       target_link_libraries(${_target} ${Vc_LIBRARIES})
       target_compile_options(${_target} PUBLIC ${Vc_ALL_FLAGS})
+      target_compile_definitions(${_target} PUBLIC ENABLE_VC=1)
       target_include_directories(${_target} SYSTEM PUBLIC ${Vc_INCLUDE_DIR})
     endforeach(_target ${_targets})
   endif(Vc_FOUND)
 endfunction(add_dune_vc_flags)
 
 if(Vc_FOUND)
-  dune_register_package_flags(COMPILE_OPTIONS "${Vc_ALL_FLAGS}"
+  dune_register_package_flags(COMPILE_OPTIONS "${Vc_ALL_FLAGS} -DENABLE_VC=1"
                               LIBRARIES "${Vc_LIBRARIES}"
                               INCLUDE_DIRS "${Vc_INCLUDE_DIR}")
 endif(Vc_FOUND)
diff --git a/config.h.cmake b/config.h.cmake
index 6e1fd357d..75a78ecc8 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -45,8 +45,9 @@
    to facilitate activating and deactivating GMP using compile flags. */
 #cmakedefine HAVE_GMP ENABLE_GMP
 
-/* Define to 1 if you have the Vc library. */
-#cmakedefine HAVE_VC 1
+/* Define if you have the Vc library. The value should be ENABLE_VC
+   to facilitate activating and deactivating Vc using compile flags. */
+#cmakedefine HAVE_VC ENABLE_VC
 
 /* Define to 1 if you have the symbol mprotect. */
 #cmakedefine HAVE_MPROTECT 1
-- 
GitLab