1# Copyright 2019 The meson development team
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Abstractions for the PGI family of compilers."""
16
17import typing as T
18import os
19from pathlib import Path
20
21from ..compilers import clike_debug_args, clike_optimization_args
22from ...mesonlib import OptionKey
23
24if T.TYPE_CHECKING:
25    from ...environment import Environment
26    from ...compilers.compilers import Compiler
27else:
28    # This is a bit clever, for mypy we pretend that these mixins descend from
29    # Compiler, so we get all of the methods and attributes defined for us, but
30    # for runtime we make them descend from object (which all classes normally
31    # do). This gives up DRYer type checking, with no runtime impact
32    Compiler = object
33
34pgi_buildtype_args = {
35    'plain': [],
36    'debug': [],
37    'debugoptimized': [],
38    'release': [],
39    'minsize': [],
40    'custom': [],
41}  # type: T.Dict[str, T.List[str]]
42
43
44class PGICompiler(Compiler):
45
46    def __init__(self) -> None:
47        self.base_options = {OptionKey('b_pch')}
48        self.id = 'pgi'
49
50        default_warn_args = ['-Minform=inform']
51        self.warn_args = {'0': [],
52                          '1': default_warn_args,
53                          '2': default_warn_args,
54                          '3': default_warn_args
55        }  # type: T.Dict[str, T.List[str]]
56
57    def get_module_incdir_args(self) -> T.Tuple[str]:
58        return ('-module', )
59
60    def get_no_warn_args(self) -> T.List[str]:
61        return ['-silent']
62
63    def gen_import_library_args(self, implibname: str) -> T.List[str]:
64        return []
65
66    def get_pic_args(self) -> T.List[str]:
67        # PGI -fPIC is Linux only.
68        if self.info.is_linux():
69            return ['-fPIC']
70        return []
71
72    def openmp_flags(self) -> T.List[str]:
73        return ['-mp']
74
75    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
76        return pgi_buildtype_args[buildtype]
77
78    def get_optimization_args(self, optimization_level: str) -> T.List[str]:
79        return clike_optimization_args[optimization_level]
80
81    def get_debug_args(self, is_debug: bool) -> T.List[str]:
82        return clike_debug_args[is_debug]
83
84    def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], build_dir: str) -> T.List[str]:
85        for idx, i in enumerate(parameter_list):
86            if i[:2] == '-I' or i[:2] == '-L':
87                parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))
88        return parameter_list
89
90    def get_always_args(self) -> T.List[str]:
91        return []
92
93    def get_pch_suffix(self) -> str:
94        # PGI defaults to .pch suffix for PCH on Linux and Windows with --pch option
95        return 'pch'
96
97    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
98        # PGI supports PCH for C++ only.
99        hdr = Path(pch_dir).resolve().parent / header
100        if self.language == 'cpp':
101            return ['--pch',
102                    '--pch_dir', str(hdr.parent),
103                    f'-I{hdr.parent}']
104        else:
105            return []
106
107    def thread_flags(self, env: 'Environment') -> T.List[str]:
108        # PGI cannot accept -pthread, it's already threaded
109        return []
110