add initial support for llvm-flang

pull/13323/head
H. Vetinari 5 months ago committed by Eli Schwartz
parent 541fee0c3c
commit 1e26a88481
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 4
      docs/markdown/Contributing.md
  2. 3
      docs/markdown/Reference-tables.md
  3. 9
      docs/markdown/snippets/llvm_flang.md
  4. 28
      mesonbuild/compilers/detect.py
  5. 56
      mesonbuild/compilers/fortran.py
  6. 1
      run_project_tests.py

@ -150,8 +150,8 @@ Subsets of project tests can be selected with
time when only a certain part of Meson is being tested. time when only a certain part of Meson is being tested.
For example, a useful and easy contribution to Meson is making For example, a useful and easy contribution to Meson is making
sure the full set of compilers is supported. One could for example test sure the full set of compilers is supported. One could for example test
various Fortran compilers by setting `FC=ifort` or `FC=flang` or similar various Fortran compilers by setting `FC=ifort`, `FC=flang` or
with `./run_project_test.py --only fortran`. `FC=flang-new` or similar with `./run_project_test.py --only fortran`.
Some families of tests require a particular backend to run. Some families of tests require a particular backend to run.
For example, all the CUDA project tests run and pass on Windows via For example, all the CUDA project tests run and pass on Windows via
`./run_project_tests.py --only cuda --backend ninja` `./run_project_tests.py --only cuda --backend ninja`

@ -15,7 +15,7 @@ These are return values of the `get_id` (Compiler family) and
| clang-cl | The Clang compiler (MSVC compatible driver) | msvc | | clang-cl | The Clang compiler (MSVC compatible driver) | msvc |
| dmd | D lang reference compiler | | | dmd | D lang reference compiler | |
| emscripten| Emscripten WASM compiler | | | emscripten| Emscripten WASM compiler | |
| flang | Flang Fortran compiler | | | flang | Classic Flang Fortran compiler | |
| g95 | The G95 Fortran compiler | | | g95 | The G95 Fortran compiler | |
| gcc | The GNU Compiler Collection | gcc | | gcc | The GNU Compiler Collection | gcc |
| intel | Intel compiler (Linux and Mac) | gcc | | intel | Intel compiler (Linux and Mac) | gcc |
@ -24,6 +24,7 @@ These are return values of the `get_id` (Compiler family) and
| intel-llvm-cl | Intel oneAPI LLVM-based compiler (Windows) | msvc | | intel-llvm-cl | Intel oneAPI LLVM-based compiler (Windows) | msvc |
| lcc | Elbrus C/C++/Fortran Compiler | | | lcc | Elbrus C/C++/Fortran Compiler | |
| llvm | LLVM-based compiler (Swift, D) | | | llvm | LLVM-based compiler (Swift, D) | |
| llvm-flang| Flang Fortran compiler (LLVM-based) | |
| mono | Xamarin C# compiler | | | mono | Xamarin C# compiler | |
| mwccarm | Metrowerks C/C++ compiler for Embedded ARM | | | mwccarm | Metrowerks C/C++ compiler for Embedded ARM | |
| mwcceppc | Metrowerks C/C++ compiler for Embedded PowerPC | | | mwcceppc | Metrowerks C/C++ compiler for Embedded PowerPC | |

@ -0,0 +1,9 @@
## Support for LLVM-based flang compiler
Added basic handling for the [flang](https://flang.llvm.org/docs/) compiler
that's now part of LLVM. It is the successor of another compiler named
[flang](https://github.com/flang-compiler/flang) by largely the same
group of developers, who now refer to the latter as "classic flang".
Meson already supports classic flang, and the LLVM-based flang now
uses the compiler-id `'llvm-flang'`.

@ -45,7 +45,8 @@ if is_windows():
defaults['c'] = ['icl', 'cl', 'cc', 'gcc', 'clang', 'clang-cl', 'pgcc'] defaults['c'] = ['icl', 'cl', 'cc', 'gcc', 'clang', 'clang-cl', 'pgcc']
# There is currently no pgc++ for Windows, only for Mac and Linux. # There is currently no pgc++ for Windows, only for Mac and Linux.
defaults['cpp'] = ['icl', 'cl', 'c++', 'g++', 'clang++', 'clang-cl'] defaults['cpp'] = ['icl', 'cl', 'c++', 'g++', 'clang++', 'clang-cl']
defaults['fortran'] = ['ifort', 'gfortran', 'flang', 'pgfortran', 'g95'] # the binary flang-new will be renamed to flang in the foreseeable future
defaults['fortran'] = ['ifort', 'gfortran', 'flang-new', 'flang', 'pgfortran', 'g95']
defaults['objc'] = ['clang-cl', 'gcc'] defaults['objc'] = ['clang-cl', 'gcc']
defaults['objcpp'] = ['clang-cl', 'g++'] defaults['objcpp'] = ['clang-cl', 'g++']
defaults['cs'] = ['csc', 'mcs'] defaults['cs'] = ['csc', 'mcs']
@ -60,7 +61,8 @@ else:
defaults['cpp'] = ['c++', 'g++', 'clang++', 'nvc++', 'pgc++', 'icpc', 'icpx'] defaults['cpp'] = ['c++', 'g++', 'clang++', 'nvc++', 'pgc++', 'icpc', 'icpx']
defaults['objc'] = ['clang', 'gcc'] defaults['objc'] = ['clang', 'gcc']
defaults['objcpp'] = ['clang++', 'g++'] defaults['objcpp'] = ['clang++', 'g++']
defaults['fortran'] = ['gfortran', 'flang', 'nvfortran', 'pgfortran', 'ifort', 'ifx', 'g95'] # the binary flang-new will be renamed to flang in the foreseeable future
defaults['fortran'] = ['gfortran', 'flang-new', 'flang', 'nvfortran', 'pgfortran', 'ifort', 'ifx', 'g95']
defaults['cs'] = ['mcs', 'csc'] defaults['cs'] = ['mcs', 'csc']
defaults['d'] = ['ldc2', 'ldc', 'gdc', 'dmd'] defaults['d'] = ['ldc2', 'ldc', 'gdc', 'dmd']
defaults['java'] = ['javac'] defaults['java'] = ['javac']
@ -659,6 +661,13 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
info = env.machines[for_machine] info = env.machines[for_machine]
cls: T.Type[FortranCompiler] cls: T.Type[FortranCompiler]
for compiler in compilers: for compiler in compilers:
# capture help text for possible fallback
try:
_, help_out, _ = Popen_safe_logged(compiler + ['--help'], msg='Detecting compiler via')
except OSError as e:
popen_exceptions[join_args(compiler + ['--help'])] = e
help_out = ''
for arg in ['--version', '-V']: for arg in ['--version', '-V']:
try: try:
p, out, err = Popen_safe_logged(compiler + [arg], msg='Detecting compiler via') p, out, err = Popen_safe_logged(compiler + [arg], msg='Detecting compiler via')
@ -776,8 +785,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
compiler, version, for_machine, is_cross, info, compiler, version, for_machine, is_cross, info,
full_version=full_version, linker=linker) full_version=full_version, linker=linker)
if 'flang' in out or 'clang' in out: def _get_linker_try_windows(cls: T.Type['Compiler']) -> T.Optional['DynamicLinker']:
cls = fortran.FlangFortranCompiler
linker = None linker = None
if 'windows' in out or env.machines[for_machine].is_windows(): if 'windows' in out or env.machines[for_machine].is_windows():
# If we're in a MINGW context this actually will use a gnu # If we're in a MINGW context this actually will use a gnu
@ -793,6 +801,18 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
if linker is None: if linker is None:
linker = guess_nix_linker(env, compiler, cls, linker = guess_nix_linker(env, compiler, cls,
version, for_machine) version, for_machine)
return linker
if 'flang-new' in out or 'flang LLVM compiler' in help_out:
cls = fortran.LlvmFlangFortranCompiler
linker = _get_linker_try_windows(cls)
return cls(
compiler, version, for_machine, is_cross, info,
full_version=full_version, linker=linker)
if 'flang' in out or 'clang' in out:
cls = fortran.ClassicFlangFortranCompiler
linker = _get_linker_try_windows(cls)
return cls( return cls(
compiler, version, for_machine, is_cross, info, compiler, version, for_machine, is_cross, info,
full_version=full_version, linker=linker) full_version=full_version, linker=linker)

@ -430,7 +430,7 @@ class NvidiaHPC_FortranCompiler(PGICompiler, FortranCompiler):
'everything': default_warn_args + ['-Mdclchk']} 'everything': default_warn_args + ['-Mdclchk']}
class FlangFortranCompiler(ClangCompiler, FortranCompiler): class ClassicFlangFortranCompiler(ClangCompiler, FortranCompiler):
id = 'flang' id = 'flang'
@ -460,10 +460,62 @@ class FlangFortranCompiler(ClangCompiler, FortranCompiler):
search_dirs.append(f'-L{d}') search_dirs.append(f'-L{d}')
return search_dirs + ['-lflang', '-lpgmath'] return search_dirs + ['-lflang', '-lpgmath']
class ArmLtdFlangFortranCompiler(FlangFortranCompiler):
class ArmLtdFlangFortranCompiler(ClassicFlangFortranCompiler):
id = 'armltdflang' id = 'armltdflang'
class LlvmFlangFortranCompiler(ClangCompiler, FortranCompiler):
id = 'llvm-flang'
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo', linker: T.Optional['DynamicLinker'] = None,
full_version: T.Optional[str] = None):
FortranCompiler.__init__(self, exelist, version, for_machine,
is_cross, info, linker=linker,
full_version=full_version)
ClangCompiler.__init__(self, {})
default_warn_args = ['-Wall']
self.warn_args = {'0': [],
'1': default_warn_args,
'2': default_warn_args,
'3': default_warn_args,
'everything': default_warn_args}
def get_colorout_args(self, colortype: str) -> T.List[str]:
# not yet supported, see https://github.com/llvm/llvm-project/issues/89888
return []
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
# not yet supported, see https://github.com/llvm/llvm-project/issues/89888
return []
def get_module_outdir_args(self, path: str) -> T.List[str]:
# different syntax from classic flang (which supported `-module`), see
# https://github.com/llvm/llvm-project/issues/66969
return ['-module-dir', path]
def gnu_symbol_visibility_args(self, vistype: str) -> T.List[str]:
# flang doesn't support symbol visibility flag yet, see
# https://github.com/llvm/llvm-project/issues/92459
return []
def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]:
# matching setup from ClassicFlangFortranCompiler
search_dirs: T.List[str] = []
for d in self.get_compiler_dirs(env, 'libraries'):
search_dirs.append(f'-L{d}')
# does not automatically link to Fortran_main anymore after
# https://github.com/llvm/llvm-project/commit/9d6837d595719904720e5ff68ec1f1a2665bdc2f
# note that this changed again in flang 19 with
# https://github.com/llvm/llvm-project/commit/8d5386669ed63548daf1bee415596582d6d78d7d;
# it seems flang 18 doesn't work if something accidentally includes a program unit, see
# https://github.com/llvm/llvm-project/issues/92496
return search_dirs + ['-lFortranRuntime', '-lFortranDecimal']
class Open64FortranCompiler(FortranCompiler): class Open64FortranCompiler(FortranCompiler):
id = 'open64' id = 'open64'

@ -1086,6 +1086,7 @@ def detect_tests_to_run(only: T.Dict[str, T.List[str]], use_tmp: bool) -> T.List
""" """
skip_fortran = not(shutil.which('gfortran') or skip_fortran = not(shutil.which('gfortran') or
shutil.which('flang-new') or
shutil.which('flang') or shutil.which('flang') or
shutil.which('pgfortran') or shutil.which('pgfortran') or
shutil.which('nagfor') or shutil.which('nagfor') or

Loading…
Cancel
Save