XL: Add support for Ninja and XL Fortran

The Ninja generator's support for Fortran requires that source files
be preprocessed explicitly first.  However, the `xlf` compiler does
not have a simple `-E` option or equivalent to do preprocessing.
The only documented way to get preprocessed output is to use `-d`
to leave it behind, but only at an inflexible location.

Instead, create our own `cpp` wrapper script and substitute it for the
real preprocessor using `-tF -B ...`.  Teach the wrapper to map the
`cpp` output to the location we need and then invoke the real `cpp`
underneath.

Fixes: #19450
This commit is contained in:
Brad King
2019-11-21 14:38:35 -05:00
parent 52accc779e
commit 19f267c75e
6 changed files with 54 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
xlf-ninja
---------
* The IBM XL Fortran compiler is now supported by the :generator:`Ninja`
generator.

View File

@@ -182,6 +182,10 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
message(STATUS "The ${lang} compiler identification is unknown") message(STATUS "The ${lang} compiler identification is unknown")
endif() endif()
if(lang STREQUAL "Fortran" AND CMAKE_${lang}_COMPILER_ID STREQUAL "XL")
set(CMAKE_${lang}_XL_CPP "${CMAKE_${lang}_COMPILER_ID_CPP}" PARENT_SCOPE)
endif()
set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE) set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE) set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE) set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE)
@@ -542,6 +546,12 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
) )
if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "exec: [^\n]*\\((/[^,\n]*/cpp),CMakeFortranCompilerId.F")
set(_cpp "${CMAKE_MATCH_1}")
if(EXISTS "${_cpp}")
set(CMAKE_${lang}_COMPILER_ID_CPP "${_cpp}" PARENT_SCOPE)
endif()
endif()
endif() endif()
# Check the result of compilation. # Check the result of compilation.

View File

@@ -271,6 +271,11 @@ include(CMakeFindBinUtils)
include(Compiler/${CMAKE_Fortran_COMPILER_ID}-FindBinUtils OPTIONAL) include(Compiler/${CMAKE_Fortran_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE) unset(_CMAKE_PROCESSING_LANGUAGE)
if(CMAKE_Fortran_XL_CPP)
set(_SET_CMAKE_Fortran_XL_CPP
"set(CMAKE_Fortran_XL_CPP \"${CMAKE_Fortran_XL_CPP}\")")
endif()
if(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID) if(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID)
set(_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID set(_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID
"set(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID ${CMAKE_Fortran_COMPILER_ARCHITECTURE_ID})") "set(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID ${CMAKE_Fortran_COMPILER_ARCHITECTURE_ID})")

View File

@@ -6,6 +6,7 @@ set(CMAKE_Fortran_COMPILER_WRAPPER "@CMAKE_Fortran_COMPILER_WRAPPER@")
set(CMAKE_Fortran_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@") set(CMAKE_Fortran_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@")
set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@") set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@")
set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@") set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
@_SET_CMAKE_Fortran_XL_CPP@
@_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID@ @_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID@
@SET_MSVC_Fortran_ARCHITECTURE_ID@ @SET_MSVC_Fortran_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@") set(CMAKE_AR "@CMAKE_AR@")

View File

@@ -18,3 +18,7 @@ string(APPEND CMAKE_Fortran_FLAGS_INIT " -qthreaded -qhalt=e")
# xlf: 1501-214 (W) command option E reserved for future use - ignored # xlf: 1501-214 (W) command option E reserved for future use - ignored
set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
set(CMAKE_Fortran_PREPROCESS_SOURCE
"<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -qpreprocess -qnoobject -qsuppress=1517-020 -tF -B \"${CMAKE_CURRENT_LIST_DIR}/XL-Fortran/\" -WF,--cpp,\"${CMAKE_Fortran_XL_CPP}\",--out,<PREPROCESSED_SOURCE> <SOURCE>"
)

29
Modules/Compiler/XL-Fortran/cpp Executable file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Source file.
src="$(printf %q "$1")"
shift
# Output file the compiler expects.
out="$(printf %q "$1")"
shift
# Create the file the compiler expects. It will check syntax.
>"$out"
cpp='cpp'
opts=''
while test "$#" != 0; do
case "$1" in
# Extract the option for the path to cpp.
--cpp) shift; cpp="$(printf %q "$1")" ;;
# Extract the option for our own output file.
--out) shift; out="$(printf %q "$1")" ;;
# Collect the rest of the command line.
*) opts="$opts $(printf %q "$1")" ;;
esac
shift
done
# Execute the real preprocessor tool.
eval "exec $cpp $src $out $opts"