Merge topic 'add-cray-linux-platform'

31d52139 Cray: Added documentation for cross compiling on a Cray
c54a621b Cray: New platform file for Cray Linux Environment and PrgEnv
This commit is contained in:
Brad King 2015-11-16 09:22:43 -05:00 committed by CMake Topic Stage
commit 166a61c729
4 changed files with 276 additions and 0 deletions

View File

@ -151,6 +151,36 @@ target system prefixes, whereas executables which must be run as part of the bui
should be found only on the host and not on the target. This is the purpose of should be found only on the host and not on the target. This is the purpose of
the ``CMAKE_FIND_ROOT_PATH_MODE_*`` variables. the ``CMAKE_FIND_ROOT_PATH_MODE_*`` variables.
.. _`Cray Cross-Compile`:
Cross Compiling for the Cray Linux Environment
----------------------------------------------
Cross compiling for compute nodes in the Cray Linux Environment can be done
without needing a separate toolchain file. Specifying
``-DCMAKE_SYSTEM_NAME=CrayLinuxEnvironment`` on the CMake command line will
ensure that the appropriate build settings and search paths are configured.
The platform will pull its configuration from the current environment
variables and will configure a project to use the compiler wrappers from the
Cray Programming Environment's ``PrgEnv-*`` modules if present and loaded.
The default configuration of the Cray Programming Environment is to only
support static libraries. This can be overridden and shared libraries
enabled by setting the ``CRAYPE_LINK_TYPE`` environment variable to
``dynamic``.
Running CMake without specifying :variable:`CMAKE_SYSTEM_NAME` will
run the configure step in host mode assuming a standard Linux environment.
If not overridden, the ``PrgEnv-*`` compiler wrappers will end up getting used,
which if targeting the either the login node or compute node, is likely not the
desired behavior. The exception to this would be if you are building directly
on a NID instead of cross-compiling from a login node. If trying to build
software for a login node, you will need to either first unload the
currently loaded ``PrgEnv-*`` module or explicitly tell CMake to use the
system compilers in ``/usr/bin`` instead of the Cray wrappers. If instead
targeting a compute node is desired, just specify the
:variable:`CMAKE_SYSTEM_NAME` as mentioned above.
Cross Compiling using Clang Cross Compiling using Clang
--------------------------- ---------------------------

View File

@ -0,0 +1,7 @@
add-cray-linux-platform
-----------------------
* A new platform file for cross-compiling in the Cray Linux Environment to
target compute nodes was added. See
:ref:`Cross Compiling for the Cray Linux Environment <Cray Cross-Compile>`
for usage details.

View File

@ -0,0 +1,112 @@
# 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.
# Guard against multiple inclusions
if(__CrayLinuxEnvironment)
return()
endif()
set(__CrayLinuxEnvironment 1)
set(UNIX 1)
if(DEFINED ENV{CRAYOS_VERSION})
set(CMAKE_SYSTEM_VERSION "$ENV{CRAYOS_VERSION}")
elseif(DEFINED ENV{XTOS_VERSION})
set(CMAKE_SYSTEM_VERSION "$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}")
# 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
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")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
set(CMAKE_DL_LIBS dl)
# 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
# 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)
# 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
# List common installation prefixes. These will be used for all
# search types.
list(APPEND CMAKE_SYSTEM_PREFIX_PATH
# Standard
$ENV{SYSROOT_DIR}/usr/local $ENV{SYSROOT_DIR}/usr $ENV{SYSROOT_DIR}/
# CMake install location
"${__cmake_install_dir}"
)
if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
list(APPEND CMAKE_SYSTEM_PREFIX_PATH
# Project install destination.
"${CMAKE_INSTALL_PREFIX}"
)
if(CMAKE_STAGING_PREFIX)
list(APPEND CMAKE_SYSTEM_PREFIX_PATH
# User-supplied staging prefix.
"${CMAKE_STAGING_PREFIX}"
)
endif()
endif()
list(APPEND CMAKE_SYSTEM_INCLUDE_PATH
$ENV{SYSROOT_DIR}/usr/include
$ENV{SYSROOT_DIR}/usr/include/X11
)
list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
$ENV{SYSROOT_DIR}/usr/local/lib64
$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)
# 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}")
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)
endif()

View File

@ -0,0 +1,127 @@
# 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
if(NOT ((CMAKE_C_FLAGS MATCHES "(^| )-dynamic($| )") OR
(CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-dynamic($| )") OR
("$ENV{CRAYPE_LINK_TYPE}" STREQUAL "dynamic")))
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()
# 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_fname empty.c)
elseif(__lang STREQUAL CXX)
set(__empty_fname empty.cxx)
elseif(__lang STREQUAL Fortran)
set(__empty_fname empty.f90)
else()
continue()
endif()
execute_process(
COMMAND ${CMAKE_${__lang}_COMPILER} ${__verbose_flag} ${__empty_fname}
OUTPUT_VARIABLE __cray_output
ERROR_QUIET
)
string(REGEX MATCH "(^|\n)[^\n]*${__empty_fname}[^\n]*" __cray_driver_cmd "${__cray_output}")
# Parse include paths
string(REGEX MATCHALL " -I([^ ]+)" __cray_include_flags "${__cray_driver_cmd}")
foreach(_flag IN LISTS __cray_include_flags)
string(REGEX REPLACE "^ -I([^ ]+)" "\\1" _dir "${_flag}")
list(APPEND CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES ${_dir})
endforeach()
if(CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES)
list(REMOVE_DUPLICATES CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES)
endif()
# Parse library paths
string(REGEX MATCHALL " -L([^ ]+)" __cray_library_dir_flags "${__cray_driver_cmd}")
foreach(_flag IN LISTS __cray_library_dir_flags)
string(REGEX REPLACE "^ -L([^ ]+)" "\\1" _dir "${_flag}")
list(APPEND CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES ${_dir})
endforeach()
if(CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
list(REMOVE_DUPLICATES CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
endif()
# Parse library paths
string(REGEX MATCHALL " -l([^ ]+)" __cray_library_flags "${__cray_driver_cmd}")
foreach(_flag IN LISTS __cray_library_flags)
string(REGEX REPLACE "^ -l([^ ]+)" "\\1" _dir "${_flag}")
list(APPEND CMAKE_${__lang}_IMPLICIT_LINK_LIBRARIES ${_dir})
endforeach()
if(CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
list(REMOVE_DUPLICATES CMAKE_${__lang}_IMPLICIT_LINK_LIBRARIES)
endif()
endforeach()
# Compute the intersection of several lists
macro(__list_intersection L_OUT L0)
if(ARGC EQUAL 2)
list(APPEND ${L_OUT} ${${L0}})
else()
foreach(I IN LISTS ${L0})
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 ${L_OUT} "${I}")
endif()
endforeach()
endif()
if(${L_OUT})
list(REMOVE_DUPLICATES ${L_OUT})
endif()
endmacro()
# Determine the common directories between all languages and add them
# as system search paths
set(__cray_include_path_vars)
set(__cray_library_path_vars)
foreach(__lang IN LISTS __langs)
list(APPEND __cray_include_path_vars CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES)
list(APPEND __cray_library_path_vars CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
endforeach()
if(__cray_include_path_vars)
__list_intersection(CMAKE_SYSTEM_INCLUDE_PATH ${__cray_include_path_vars})
endif()
if(__cray_library_path_vars)
__list_intersection(CMAKE_SYSTEM_LIBRARY_PATH ${__cray_library_path_vars})
endif()