summaryrefslogtreecommitdiff
path: root/lib/spack/spack/compilers/nag.py
blob: c12ccec7bfa1b8990853dccb8aead8808cd20613 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import os
import re
from typing import List

import llnl.util.lang

import spack.compiler


class Nag(spack.compiler.Compiler):
    # Subclasses use possible names of C compiler
    cc_names: List[str] = []

    # Subclasses use possible names of C++ compiler
    cxx_names: List[str] = []

    # Subclasses use possible names of Fortran 77 compiler
    f77_names = ["nagfor"]

    # Subclasses use possible names of Fortran 90 compiler
    fc_names = ["nagfor"]

    # Named wrapper links within build_env_path
    # Use default wrappers for C and C++, in case provided in compilers.yaml
    link_paths = {
        "cc": "cc",
        "cxx": "c++",
        "f77": os.path.join("nag", "nagfor"),
        "fc": os.path.join("nag", "nagfor"),
    }

    version_argument = "-V"

    @classmethod
    @llnl.util.lang.memoized
    def extract_version_from_output(cls, output):
        match = re.search(r"NAG Fortran Compiler Release (\d+).(\d+)\(.*\) Build (\d+)", output)
        if match:
            return ".".join(match.groups())

    @property
    def verbose_flag(self):
        # 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.
        return "-Wl,-v"

    @property
    def openmp_flag(self):
        return "-openmp"

    @property
    def debug_flags(self):
        return ["-g", "-gline", "-g90"]

    @property
    def opt_flags(self):
        return ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"]

    @property
    def cxx11_flag(self):
        # NAG does not have a C++ compiler
        # However, it can be mixed with a compiler that does support it
        return "-std=c++11"

    @property
    def f77_pic_flag(self):
        return "-PIC"

    @property
    def fc_pic_flag(self):
        return "-PIC"

    # Unlike other compilers, the NAG compiler passes options to GCC, which
    # then passes them to the linker. Therefore, we need to doubly wrap the
    # options with '-Wl,-Wl,,'
    @property
    def f77_rpath_arg(self):
        return "-Wl,-Wl,,-rpath,,"

    @property
    def fc_rpath_arg(self):
        return "-Wl,-Wl,,-rpath,,"

    @property
    def linker_arg(self):
        return "-Wl,-Wl,,"

    @property
    def disable_new_dtags(self):
        # Disable RPATH/RUNPATH forcing for NAG/GCC mixed toolchains:
        return ""

    @property
    def enable_new_dtags(self):
        # Disable RPATH/RUNPATH forcing for NAG/GCC mixed toolchains:
        return ""