Commit a7ef0225 authored by Chuck Atkins's avatar Chuck Atkins Committed by Brad King

Cray: Refactor the Cray platform files to use compiler wrapper checks

This is an extensive refactoring of the Cray compiler wrapper usage.
Using the new compiler wrapper checks, the CrayPrgEnv info files have
been moved from Platform/ to Compiler/.  The adjusted naming convention
allows the compiler-wrapper information files to be loaded for both the
CrayLinuxEnvironment platform when cross-compiling and the Linux
platform if building natively on the Cray compute nodes.  It also
creates a separation of common arguments for compiler id and language
information used to perform the appropriate introspection of implicit
arguments and libraries used by the compiler wrappers based on the
loaded module environment.
parent 0763a836
if(__craylinux_crayprgenv_c)
return()
endif()
set(__craylinux_crayprgenv_c 1)
include(Compiler/CrayPrgEnv)
macro(__CrayPrgEnv_setup_C compiler_cmd link_cmd)
__CrayPrgEnv_setup(C
${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c
${compiler_cmd} ${link_cmd})
endmacro()
if(__craylinux_crayprgenv_cxx)
return()
endif()
set(__craylinux_crayprgenv_cxx 1)
include(Compiler/CrayPrgEnv)
macro(__CrayPrgEnv_setup_CXX compiler_cmd link_cmd)
__CrayPrgEnv_setup(CXX
${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp
${compiler_cmd} ${link_cmd})
endmacro()
if(__craylinux_crayprgenv_cray_c)
return()
endif()
set(__craylinux_crayprgenv_cray_c 1)
include(Compiler/CrayPrgEnv-C)
__CrayPrgEnv_setup_C("/opt/cray/cce/.*/ccfe" "/opt/cray/cce/.*/ld")
if(__craylinux_crayprgenv_cray_cxx)
return()
endif()
set(__craylinux_crayprgenv_cray_cxx 1)
include(Compiler/CrayPrgEnv-CXX)
__CrayPrgEnv_setup_CXX("/opt/cray/cce/.*/ccfe" "/opt/cray/cce/.*/ld")
if(__craylinux_crayprgenv_cray_fortran)
return()
endif()
set(__craylinux_crayprgenv_cray_fortran 1)
include(Compiler/CrayPrgEnv-Fortran)
__CrayPrgEnv_setup_Fortran("/opt/cray/cce/.*/ftnfe" "/opt/cray/cce/.*/ld")
if(__craylinux_crayprgenv_fortran)
return()
endif()
set(__craylinux_crayprgenv_fortran 1)
include(Compiler/CrayPrgEnv)
macro(__CrayPrgEnv_setup_Fortran compiler_cmd link_cmd)
__CrayPrgEnv_setup(Fortran
${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F
${compiler_cmd} ${link_cmd})
endmacro()
if(__craylinux_crayprgenv_gnu_c)
return()
endif()
set(__craylinux_crayprgenv_gnu_c 1)
include(Compiler/CrayPrgEnv-C)
__CrayPrgEnv_setup_C("/opt/gcc/.*/cc1" "/opt/gcc/.*/collect2")
if(__craylinux_crayprgenv_gnu_cxx)
return()
endif()
set(__craylinux_crayprgenv_gnu_cxx 1)
include(Compiler/CrayPrgEnv-CXX)
__CrayPrgEnv_setup_CXX("/opt/gcc/.*/cc1plus" "/opt/gcc/.*/collect2")
if(__craylinux_crayprgenv_gnu_fortran)
return()
endif()
set(__craylinux_crayprgenv_gnu_fortran 1)
include(Compiler/CrayPrgEnv-Fortran)
__CrayPrgEnv_setup_Fortran("/opt/gcc/.*/f951" "/opt/gcc/.*/collect2")
if(__craylinux_crayprgenv_intel_c)
return()
endif()
set(__craylinux_crayprgenv_intel_c 1)
include(Compiler/CrayPrgEnv-C)
__CrayPrgEnv_setup_C("/opt/intel/.*/mcpcom" "^ld ")
if(__craylinux_crayprgenv_intel_cxx)
return()
endif()
set(__craylinux_crayprgenv_intel_cxx 1)
include(Compiler/CrayPrgEnv-CXX)
__CrayPrgEnv_setup_CXX("/opt/intel/.*/mcpcom" "^ld ")
if(__craylinux_crayprgenv_intel_fortran)
return()
endif()
set(__craylinux_crayprgenv_intel_fortran 1)
include(Compiler/CrayPrgEnv-Fortran)
__CrayPrgEnv_setup_Fortran("/opt/intel/.*/fortcom" "^ld ")
if(__craylinux_crayprgenv_pgi_c)
return()
endif()
set(__craylinux_crayprgenv_pgi_c 1)
include(Compiler/CrayPrgEnv-C)
__CrayPrgEnv_setup_C("/opt/pgi/[^ ]*/pgc" "/usr/bin/ld")
if(__craylinux_crayprgenv_pgi_cxx)
return()
endif()
set(__craylinux_crayprgenv_pgi_cxx 1)
include(Compiler/CrayPrgEnv-CXX)
__CrayPrgEnv_setup_CXX("/opt/pgi/[^ ]*/pgcpp" "/usr/bin/ld")
if(__craylinux_crayprgenv_pgi_fortran)
return()
endif()
set(__craylinux_crayprgenv_pgi_fortran 1)
include(Compiler/CrayPrgEnv-Fortran)
__CrayPrgEnv_setup_Fortran("/opt/pgi/[^ ]*/pgf" "/usr/bin/ld")
# Guard against multiple inclusions
if(__craylinux_crayprgenv)
return()
endif()
set(__craylinux_crayprgenv 1)
macro(__cray_extract_args cmd tag_regex out_var)
string(REGEX MATCHALL "${tag_regex}" args "${cmd}")
foreach(arg IN LISTS args)
string(REGEX REPLACE "^${tag_regex}$" "\\2" param "${arg}")
get_filename_component(param_abs "${param}" ABSOLUTE)
list(APPEND ${out_var} ${param_abs})
endforeach()
endmacro()
function(__cray_extract_implicit src compiler_cmd link_cmd lang include_dirs_var link_dirs_var link_libs_var)
execute_process(
COMMAND ${CMAKE_${lang}_COMPILER}
${CMAKE_${lang}_VERBOSE_FLAG} -o cray_extract_implicit_${lang} ${src}
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE error
)
string(REGEX REPLACE "\r?\n" ";" output_lines "${output}\n${error}")
foreach(line IN LISTS output_lines)
if("${line}" MATCHES "${compiler_cmd}")
__cray_extract_args("${line}" " -(I ?|isystem )([^ ]*)" include_dirs)
set(processed_include 1)
endif()
if("${line}" MATCHES "${link_cmd}")
__cray_extract_args("${line}" " -(L ?)([^ ]*)" link_dirs)
__cray_extract_args("${line}" " -(l ?)([^ ]*)" link_libs)
set(processed_link 1)
endif()
if(processed_include AND processed_link)
break()
endif()
endforeach()
set(${include_dirs_var} "${include_dirs}" PARENT_SCOPE)
set(${link_dirs_var} "${link_dirs}" PARENT_SCOPE)
set(${link_libs_var} "${link_libs}" PARENT_SCOPE)
set(CRAY_${lang}_EXTRACTED_IMPLICIT 1 CACHE INTERNAL "" FORCE)
endfunction()
macro(__CrayPrgEnv_setup lang test_src compiler_cmd link_cmd)
if(DEFINED ENV{CRAYPE_VERSION})
message(STATUS "Cray Programming Environment $ENV{CRAYPE_VERSION} ${lang}")
elseif(DEFINED ENV{ASYNCPE_VERSION})
message(STATUS "Cray XT Programming Environment $ENV{ASYNCPE_VERSION} ${lang}")
endif()
# Flags for the Cray wrappers
set(CMAKE_STATIC_LIBRARY_LINK_${lang}_FLAGS "-static")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
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 staticly 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($| )")))))
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()
if(NOT CRAY_${lang}_EXTRACTED_IMPLICIT)
__cray_extract_implicit(
${test_src} ${compiler_cmd} ${link_cmd} ${lang}
CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES
CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES
CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES
)
endif()
endmacro()
......@@ -2,12 +2,6 @@
# needs to be custom. We use the variables defined through Cray's environment
# modules to set up the right paths for things.
# Guard against multiple inclusions
if(__CrayLinuxEnvironment)
return()
endif()
set(__CrayLinuxEnvironment 1)
set(UNIX 1)
if(DEFINED ENV{CRAYOS_VERSION})
......@@ -17,7 +11,12 @@ elseif(DEFINED ENV{XTOS_VERSION})
else()
message(FATAL_ERROR "Neither the CRAYOS_VERSION or XTOS_VERSION environment variables are defined. This platform file should be used inside the Cray Linux Environment for targeting compute nodes (NIDs)")
endif()
message(STATUS "Cray Linux Environment ${CMAKE_SYSTEM_VERSION}")
# Guard against multiple messages
if(NOT __CrayLinuxEnvironment_message)
set(__CrayLinuxEnvironment_message 1)
message(STATUS "Cray Linux Environment ${CMAKE_SYSTEM_VERSION}")
endif()
# All cray systems are x86 CPUs and have been for quite some time
# Note: this may need to change in the future with 64-bit ARM
......@@ -29,8 +28,13 @@ set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
# 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)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
endif()
set(CMAKE_DL_LIBS dl)
......@@ -42,7 +46,6 @@ set(CMAKE_DL_LIBS dl)
get_filename_component(__cmake_install_dir "${CMAKE_ROOT}" PATH)
get_filename_component(__cmake_install_dir "${__cmake_install_dir}" PATH)
# Note: Some Cray's have the SYSROOT_DIR variable defined, pointing to a copy
# of the NIDs userland. If so, then we'll use it. Otherwise, just assume
# the userland from the login node is ok
......@@ -78,35 +81,63 @@ list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
$ENV{SYSROOT_DIR}/usr/lib64
$ENV{SYSROOT_DIR}/lib64
)
list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
$ENV{SYSROOT_DIR}/usr/local/lib64
$ENV{SYSROOT_DIR}/usr/lib64
$ENV{SYSROOT_DIR}/lib64
)
list(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES
$ENV{SYSROOT_DIR}/usr/include
)
list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
$ENV{SYSROOT_DIR}/usr/include
)
list(APPEND CMAKE_Fortran_IMPLICIT_INCLUDE_DIRECTORIES
$ENV{SYSROOT_DIR}/usr/include
)
# Enable use of lib64 search path variants by default.
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
# 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()
# Check to see if we're using the cray compiler wrappers and load accordingly
# if we are
if(DEFINED ENV{CRAYPE_DIR})
set(_CRAYPE_ROOT "$ENV{CRAYPE_DIR}")
elseif(DEFINED ENV{ASYNCPE_DIR})
set(_CRAYPE_ROOT "$ENV{ASYNCPE_DIR}")
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(_CRAYPE_ROOT AND
((CMAKE_C_COMPILER MATCHES "${_CRAYPE_ROOT}") OR
(CMAKE_CXX_COMPILER MATCHES "${_CRAYPE_ROOT}") OR
(CMAKE_Fortran_COMPILER MATCHES "${_CRAYPE_ROOT}")))
include(Platform/CrayPrgEnv)
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)
# Guard against multiple inclusions
if(__CrayPrgEnv)
return()
endif()
set(__CrayPrgEnv 1)
if(DEFINED ENV{CRAYPE_VERSION})
message(STATUS "Cray Programming Environment $ENV{CRAYPE_VERSION}")
set(__verbose_flag "-craype-verbose")
elseif(DEFINED ENV{ASYNCPE_VERSION})
message(STATUS "Cray Programming Environment $ENV{ASYNCPE_VERSION}")
set(__verbose_flag "-v")
else()
message(STATUS "Cray Programming Environment")
endif()
if(NOT __CrayLinuxEnvironment)
message(FATAL_ERROR "The CrayPrgEnv platform file must not be used on its own and is intented to be included by the CrayLinuxEnvironment platform file")
endif()
# Flags for the Cray wrappers
foreach(__lang C CXX Fortran)
set(CMAKE_STATIC_LIBRARY_LINK_${__lang}_FLAGS "-static")
set(CMAKE_SHARED_LIBRARY_${__lang}_FLAGS "")
set(CMAKE_SHARED_LIBRARY_CREATE_${__lang}_FLAGS "-shared")
set(CMAKE_SHARED_LIBRARY_LINK_${__lang}_FLAGS "-dynamic")
endforeach()
# If the link type is not explicitly specified in the environment then
# the Cray wrappers assume that the code will be built staticly 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_C_FLAGS MATCHES "(^| )-dynamic($| )") OR
(CMAKE_CXX_FLAGS MATCHES "(^| )-dynamic($| )") OR
(CMAKE_Fortran_FLAGS MATCHES "(^| )-dynamic($| )") OR
(CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-dynamic($| )"))
OR
(("$ENV{CRAYPE_LINK_TYPE}" STREQUAL "dynamic") AND
NOT ((CMAKE_C_FLAGS MATCHES "(^| )-static($| )") OR
(CMAKE_CXX_FLAGS MATCHES "(^| )-static($| )") OR
(CMAKE_Fortran_FLAGS MATCHES "(^| )-static($| )") OR
(CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-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()
function(__cray_parse_flags_with_sep OUTPUT FLAG_TAG SEP INPUT)
string(REGEX MATCHALL "${SEP}${FLAG_TAG}([^${SEP}]+)" FLAG_ARGS "${INPUT}")
foreach(FLAG_ARG IN LISTS FLAG_ARGS)
string(REGEX REPLACE
"^${SEP}${FLAG_TAG}([^${SEP}]+)" "\\1" FLAG_VALUE
"${FLAG_ARG}")
list(APPEND ${OUTPUT} ${FLAG_VALUE})
endforeach()
set(${OUTPUT} ${${OUTPUT}} PARENT_SCOPE)
endfunction()
macro(__cray_parse_flags OUTPUT FLAG_TAG INPUT)
__cray_parse_flags_with_sep(${OUTPUT} ${FLAG_TAG} " " "${INPUT}")
endmacro()
# Remove duplicates in a list
macro(__cray_list_remove_duplicates VAR)
if(${VAR})
list(REMOVE_DUPLICATES ${VAR})
endif()
endmacro()
# 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()
# Parse the implicit directories used by the wrappers
get_property(__langs GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(__lang IN LISTS __langs)
if(__lang STREQUAL "C")
set(__empty empty.c)
elseif(__lang STREQUAL CXX)
set(__empty empty.cxx)
elseif(__lang STREQUAL Fortran)
set(__empty empty.f90)
else()
continue()
endif()
execute_process(
COMMAND ${CMAKE_${__lang}_COMPILER} ${__verbose_flag} ${__empty}
OUTPUT_VARIABLE __cmd_out
ERROR_QUIET
)
string(REGEX MATCH "(^|\n)[^\n]*${__empty}[^\n]*" __driver "${__cmd_out}")
# Parse include paths
set(__cray_flag_args)
__cray_parse_flags(__cray_flag_args "-I" "${__driver}")
__cray_parse_flags(__cray_flag_args "-isystem " "${__driver}")
list(APPEND CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES ${__cray_flag_args})
__cray_list_remove_duplicates(CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES)
# Parse library paths
set(__cray_flag_args)
__cray_parse_flags(__cray_flag_args "-L" "${__driver}")
list(APPEND CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES ${__cray_flag_args})
__cray_list_remove_duplicates(CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
# Parse libraries
set(__cray_flag_args)
__cray_parse_flags(__cray_flag_args "-l" "${__driver}")
__cray_parse_flags(__cray_linker_flags "-Wl" "${__driver}")
foreach(F IN LISTS __cray_linker_flags)
__cray_parse_flags_with_sep(__cray_flag_args "-l" "," "${F}")
endforeach()
list(APPEND CMAKE_${__lang}_IMPLICIT_LINK_LIBRARIES ${__cray_flag_args})
__cray_list_remove_duplicates(CMAKE_${__lang}_IMPLICIT_LINK_LIBRARIES)
endforeach()
# Determine the common directories between all languages and add them
# as system search paths
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(CMAKE_SYSTEM_INCLUDE_PATH ${__cray_inc_path_vars})
endif()
if(__cray_lib_path_vars)
__cray_list_intersect(CMAKE_SYSTEM_LIBRARY_PATH ${__cray_lib_path_vars})
endif()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment