Merge topic 'cray-cleanup'

d59159afdb Cray: clean up CrayPrgEnv and CrayLinuxEnvironment modules

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2945
diff --git a/Modules/Compiler/CrayPrgEnv.cmake b/Modules/Compiler/CrayPrgEnv.cmake
index 6c1c770..e55e587 100644
--- a/Modules/Compiler/CrayPrgEnv.cmake
+++ b/Modules/Compiler/CrayPrgEnv.cmake
@@ -1,8 +1,93 @@
 # Guard against multiple inclusions
-if(__craylinux_crayprgenv)
+if(__cmake_craype_crayprgenv)
   return()
 endif()
-set(__craylinux_crayprgenv 1)
+set(__cmake_craype_crayprgenv 1)
+
+# CrayPrgEnv: loaded when compiling through the Cray compiler wrapper.
+# The compiler wrapper can run on a front-end node or a compute node.
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW)  # if IN_LIST
+
+# One-time setup of the craype environment.  First, check the wrapper config.
+# The wrapper's selection of a compiler (gcc, clang, intel, etc.) and
+# default include/library paths is selected using the "module" command.
+# The CRAYPE_LINK_TYPE environment variable partly controls if static
+# or dynamic binaries are generated (see __cmake_craype_linktype below).
+# Running cmake and then changing module and/or linktype configuration
+# may cause build problems (since the data in the cmake cache may no
+# longer be correct after the change).  We can look for this and warn
+# the user about it.  Second, use the "module" provided PKG_CONFIG_PATH-like
+# environment variable to add additional prefixes to the system prefix
+# path.
+function(__cmake_craype_setupenv)
+  if(NOT DEFINED __cmake_craype_setupenv_done)  # only done once per run
+    set(__cmake_craype_setupenv_done 1 PARENT_SCOPE)
+    unset(__cmake_check)
+    set(CMAKE_CRAYPE_LINKTYPE "$ENV{CRAYPE_LINK_TYPE}" CACHE STRING
+        "saved value of CRAYPE_LINK_TYPE environment variable")
+    set(CMAKE_CRAYPE_LOADEDMODULES "$ENV{LOADEDMODULES}" CACHE STRING
+        "saved value of LOADEDMODULES environment variable")
+    mark_as_advanced(CMAKE_CRAYPE_LINKTYPE CMAKE_CRAYPE_LOADEDMODULES)
+    if (NOT "${CMAKE_CRAYPE_LINKTYPE}" STREQUAL "$ENV{CRAYPE_LINK_TYPE}")
+      string(APPEND __cmake_check "CRAYPE_LINK_TYPE ")
+    endif()
+    if (NOT "${CMAKE_CRAYPE_LOADEDMODULES}" STREQUAL "$ENV{LOADEDMODULES}")
+      string(APPEND __cmake_check "LOADEDMODULES ")
+    endif()
+    if(DEFINED __cmake_check)
+      message(STATUS "NOTE: ${__cmake_check}changed since initial config!")
+      message(STATUS "NOTE: this may cause unexpected build errors.")
+    endif()
+    # loop over variables of interest
+    foreach(pkgcfgvar PKG_CONFIG_PATH PKG_CONFIG_PATH_DEFAULT
+            PE_PKG_CONFIG_PATH)
+      file(TO_CMAKE_PATH "$ENV{${pkgcfgvar}}" pkgcfg)
+      foreach(path ${pkgcfg})
+        string(REGEX REPLACE "(.*)/lib[^/]*/pkgconfig$" "\\1" path "${path}")
+        if(NOT "${path}" STREQUAL "" AND
+           NOT "${path}" IN_LIST CMAKE_SYSTEM_PREFIX_PATH)
+          list(APPEND CMAKE_SYSTEM_PREFIX_PATH "${path}")
+        endif()
+      endforeach()
+    endforeach()
+    # push it up out of this function into the parent scope
+    set(CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_SYSTEM_PREFIX_PATH}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+# The wrapper disables dynamic linking by default.  Dynamic linking is
+# enabled either by setting $ENV{CRAYPE_LINK_TYPE} to "dynamic" or by
+# specifying "-dynamic" to the wrapper when linking.  Specifying "-static"
+# to the wrapper when linking takes priority over $ENV{CRAYPE_LINK_TYPE}.
+# Furthermore, if you specify multiple "-dynamic" and "-static" flags to
+# the wrapper when linking, the last one will win.  In this case, the
+# wrapper will also print a warning like:
+#  Warning: -dynamic was already seen on command line, overriding with -static.
+#
+# note that cmake applies both CMAKE_${lang}_FLAGS and CMAKE_EXE_LINKER_FLAGS
+# (in that order) to the linking command, so -dynamic can appear in either
+# variable.
+function(__cmake_craype_linktype lang rv)
+  # start with ENV, but allow flags to override
+  if("$ENV{CRAYPE_LINK_TYPE}" STREQUAL "dynamic")
+    set(linktype dynamic)
+  else()
+    set(linktype static)
+  endif()
+  # combine flags and convert to a list so we can apply the flags in order
+  set(linkflags "${CMAKE_${lang}_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
+  string(REPLACE " " ";" linkflags "${linkflags}")
+  foreach(flag IN LISTS linkflags)
+    if("${flag}" STREQUAL "-dynamic")
+      set(linktype dynamic)
+    elseif("${flag}" STREQUAL "-static")
+      set(linktype static)
+    endif()
+  endforeach()
+  set(${rv} ${linktype} PARENT_SCOPE)
+endfunction()
 
 macro(__CrayPrgEnv_setup lang)
   if(DEFINED ENV{CRAYPE_VERSION})
@@ -13,25 +98,25 @@
     message(STATUS "Cray Programming Environment (unknown version) ${lang}")
   endif()
 
+  # setup the craype environment
+  __cmake_craype_setupenv()
+
   # Flags for the Cray wrappers
   set(CMAKE_STATIC_LIBRARY_LINK_${lang}_FLAGS "-static")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-dynamic")
 
-  # If the link type is not explicitly specified in the environment then
-  # the Cray wrappers assume that the code will be built statically so
-  # we check the following condition(s) are NOT met
-  #  Compiler flags are explicitly dynamic
-  #  Env var is dynamic and compiler flags are not explicitly static
-  if(NOT (((CMAKE_${lang}_FLAGS MATCHES "(^| )-dynamic($| )") OR
-         (CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-dynamic($| )"))
-         OR
-         (("$ENV{CRAYPE_LINK_TYPE}" STREQUAL "dynamic") AND
-          NOT ((CMAKE_${lang}_FLAGS MATCHES "(^| )-static($| )") OR
-               (CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-static($| )")))))
+  # determine linktype from environment and compiler flags
+  __cmake_craype_linktype(${lang} __cmake_craype_${lang}_linktype)
+
+  # switch off shared libs if we get a static linktype
+  if("${__cmake_craype_${lang}_linktype}" STREQUAL "static")
     set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
     set(BUILD_SHARED_LIBS FALSE CACHE BOOL "")
     set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
     set(CMAKE_LINK_SEARCH_START_STATIC TRUE)
   endif()
+
 endmacro()
+
+cmake_policy(POP)
diff --git a/Modules/Platform/CrayLinuxEnvironment.cmake b/Modules/Platform/CrayLinuxEnvironment.cmake
index a1a3d3f..f2aaf3f 100644
--- a/Modules/Platform/CrayLinuxEnvironment.cmake
+++ b/Modules/Platform/CrayLinuxEnvironment.cmake
@@ -1,6 +1,5 @@
-# Compute Node Linux doesn't quite work the same as native Linux so all of this
-# needs to be custom.  We use the variables defined through Cray's environment
-# modules to set up the right paths for things.
+# CrayLinuxEnvironment: loaded by users cross-compiling on a Cray front-end
+# node by specifying "-DCMAKE_SYSTEM_NAME=CrayLinuxEnvironment" to cmake
 
 set(UNIX 1)
 
@@ -30,13 +29,6 @@
 # Note: this may need to change in the future with 64-bit ARM
 set(CMAKE_SYSTEM_PROCESSOR "x86_64")
 
-set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
-set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
-set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
-set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
-
-set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
-
 # Don't override shared lib support if it's already been set and possibly
 # overridden elsewhere by the CrayPrgEnv module
 if(NOT CMAKE_FIND_LIBRARY_SUFFIXES)
@@ -44,12 +36,9 @@
   set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
 endif()
 
-set(CMAKE_DL_LIBS dl)
+# The rest of this file is based on UnixPaths.cmake, adjusted for Cray
 
-# Note: Much of this is pulled from UnixPaths.cmake but adjusted to the Cray
-# environment accordingly
-
-# Get the install directory of the running cmake to the search directories
+# add the install directory of the running cmake to the search directories
 # CMAKE_ROOT is CMAKE_INSTALL_PREFIX/share/cmake, so we need to go two levels up
 get_filename_component(__cmake_install_dir "${CMAKE_ROOT}" PATH)
 get_filename_component(__cmake_install_dir "${__cmake_install_dir}" PATH)
@@ -81,7 +70,6 @@
 endif()
 
 list(APPEND CMAKE_SYSTEM_INCLUDE_PATH
-  $ENV{SYSROOT_DIR}/usr/include
   $ENV{SYSROOT_DIR}/usr/include/X11
 )
 list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
@@ -95,57 +83,5 @@
   $ENV{SYSROOT_DIR}/lib64
 )
 
-# Compute the intersection of several lists
-function(__cray_list_intersect OUTPUT INPUT0)
-  if(ARGC EQUAL 2)
-    list(APPEND ${OUTPUT} ${${INPUT0}})
-  else()
-    foreach(I IN LISTS ${INPUT0})
-      set(__is_common 1)
-      foreach(L IN LISTS ARGN)
-        list(FIND ${L} "${I}" __idx)
-        if(__idx EQUAL -1)
-          set(__is_common 0)
-          break()
-        endif()
-      endforeach()
-      if(__is_common)
-        list(APPEND ${OUTPUT}  "${I}")
-      endif()
-    endforeach()
-  endif()
-  set(${OUTPUT} ${${OUTPUT}} PARENT_SCOPE)
-endfunction()
-
-macro(__list_clean_dupes var)
-  if(${var})
-    list(REMOVE_DUPLICATES ${var})
-  endif()
-endmacro()
-
-get_property(__langs GLOBAL PROPERTY ENABLED_LANGUAGES)
-set(__cray_inc_path_vars)
-set(__cray_lib_path_vars)
-foreach(__lang IN LISTS __langs)
-  list(APPEND __cray_inc_path_vars CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES)
-  list(APPEND __cray_lib_path_vars CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
-endforeach()
-if(__cray_inc_path_vars)
-  __cray_list_intersect(__cray_implicit_include_dirs ${__cray_inc_path_vars})
-  if(__cray_implicit_include_dirs)
-    list(INSERT CMAKE_SYSTEM_INCLUDE_PATH 0 ${__cray_implicit_include_dirs})
-  endif()
-endif()
-if(__cray_lib_path_vars)
-  __cray_list_intersect(__cray_implicit_library_dirs ${__cray_lib_path_vars})
-  if(__cray_implicit_library_dirs)
-    list(INSERT CMAKE_SYSTEM_LIBRARY_PATH 0 ${__cray_implicit_library_dirs})
-  endif()
-endif()
-__list_clean_dupes(CMAKE_SYSTEM_PREFIX_PATH)
-__list_clean_dupes(CMAKE_SYSTEM_INCLUDE_PATH)
-__list_clean_dupes(CMAKE_SYSTEM_LIBRARY_PATH)
-__list_clean_dupes(CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES)
-
 # Enable use of lib64 search path variants by default.
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)