nag: added external detection capabilities (#18153)

This commit is contained in:
Massimiliano Culpo 2020-10-19 06:12:05 +02:00 committed by GitHub
parent 9471e9cb03
commit 008b77a2a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,9 +2,11 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
import os
import re
import spack.compiler
import llnl.util.tty as tty
class Nag(Package):
@ -41,3 +43,60 @@ def install(self, spec, prefix):
def setup_run_environment(self, env):
env.set('F77', self.prefix.bin.nagfor)
env.set('FC', self.prefix.bin.nagfor)
executables = ['^nagfor$']
@classmethod
def determine_version(cls, exe):
version_regex = re.compile(r'NAG Fortran Compiler Release ([0-9.]+)')
# NAG does not support a flag that would enable verbose output and
# compilation/linking at the same time (with either '-#' or '-dryrun'
# the compiler only prints the commands but does not run them).
# Therefore, the only thing we can do is to pass the '-v' argument to
# the underlying GCC. In order to get verbose output from the latter
# at both compile and linking stages, we need to call NAG with two
# additional flags: '-Wc,-v' and '-Wl,-v'. However, we return only
# '-Wl,-v' for the following reasons:
# 1) the interface of this method does not support multiple flags in
# the return value and, at least currently, verbose output at the
# linking stage has a higher priority for us;
# 2) NAG is usually mixed with GCC compiler, which also accepts
# '-Wl,-v' and produces meaningful result with it: '-v' is passed
# to the linker and the latter produces verbose output for the
# linking stage ('-Wc,-v', however, would break the compilation
# with a message from GCC that the flag is not recognized).
#
# This way, we at least enable the implicit rpath detection, which is
# based on compilation of a C file (see method
# spack.compiler._get_compiler_link_paths): in the case of a mixed
# NAG/GCC toolchain, the flag will be passed to g++ (e.g.
# 'g++ -Wl,-v ./main.c'), otherwise, the flag will be passed to nagfor
# (e.g. 'nagfor -Wl,-v ./main.c' - note that nagfor recognizes '.c'
# extension and treats the file accordingly). The list of detected
# rpaths will contain only GCC-related directories and rpaths to
# NAG-related directories are injected by nagfor anyway.
try:
output = spack.compiler.get_compiler_version_output(exe, '-Wl,-v')
match = version_regex.search(output)
if match:
return match.group(1)
except spack.util.executable.ProcessError:
pass
except Exception as e:
tty.debug(e)
@classmethod
def determine_variants(cls, exes, version_str):
compilers = {}
for exe in exes:
if 'nagfor' in exe:
compilers['fortran'] = exe
return '', {'compilers': compilers}
@property
def fortran(self):
msg = "cannot retrieve Fortran compiler [spec is not concrete]"
assert self.spec.concrete, msg
if self.spec.external:
return self.spec.extra_attributes['compilers'].get('fortran', None)
return str(self.spec.prefix.bin.nagfor)