diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py index f09f25277..1679243ac 100644 --- a/mesonbuild/compilers/__init__.py +++ b/mesonbuild/compilers/__init__.py @@ -54,10 +54,13 @@ __all__ = [ 'FortranCompiler', 'G95FortranCompiler', 'GnuCCompiler', + 'ElbrusCCompiler', 'GnuCompiler', 'GnuCPPCompiler', + 'ElbrusCPPCompiler', 'GnuDCompiler', 'GnuFortranCompiler', + 'ElbrusFortranCompiler', 'GnuObjCCompiler', 'GnuObjCPPCompiler', 'IntelCompiler', @@ -117,6 +120,7 @@ from .c import ( CCompiler, ClangCCompiler, GnuCCompiler, + ElbrusCCompiler, IntelCCompiler, VisualStudioCCompiler, ) @@ -124,6 +128,7 @@ from .cpp import ( CPPCompiler, ClangCPPCompiler, GnuCPPCompiler, + ElbrusCPPCompiler, IntelCPPCompiler, VisualStudioCPPCompiler, ) @@ -138,6 +143,7 @@ from .fortran import ( FortranCompiler, G95FortranCompiler, GnuFortranCompiler, + ElbrusFortranCompiler, IntelFortranCompiler, NAGFortranCompiler, Open64FortranCompiler, diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 1c9b9b4fa..be8bb5285 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -36,6 +36,7 @@ from .compilers import ( CompilerArgs, CrossNoRunException, GnuCompiler, + ElbrusCompiler, IntelCompiler, RunResult, ) @@ -888,6 +889,21 @@ class GnuCCompiler(GnuCompiler, CCompiler): return ['-fpch-preprocess', '-include', os.path.basename(header)] +class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler): + def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None, **kwargs): + GnuCCompiler.__init__(self, exelist, version, gcc_type, is_cross, exe_wrapper, defines, **kwargs) + ElbrusCompiler.__init__(self, gcc_type, defines) + + # It does support some various ISO standards and c/gnu 90, 9x, 1x in addition to those which GNU CC supports. + def get_options(self): + opts = {'c_std': coredata.UserComboOption('c_std', 'C language standard to use', + ['none', 'c89', 'c90', 'c9x', 'c99', 'c1x', 'c11', + 'gnu89', 'gnu90', 'gnu9x', 'gnu99', 'gnu1x', 'gnu11', + 'iso9899:2011', 'iso9899:1990', 'iso9899:199409', 'iso9899:1999'], + 'none')} + return opts + + class IntelCCompiler(IntelCompiler, CCompiler): def __init__(self, exelist, version, icc_type, is_cross, exe_wrapper=None, **kwargs): CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 034fef4eb..0ab9b49c1 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1076,6 +1076,17 @@ class GnuCompiler: return gnulike_default_include_dirs(self.exelist, self.language) +class ElbrusCompiler(GnuCompiler): + # Elbrus compiler is nearly like GCC, but does not support + # PCH, LTO, sanitizers and color output as of version 1.21.x. + def __init__(self, gcc_type, defines): + GnuCompiler.__init__(self, gcc_type, defines) + self.id = 'lcc' + self.base_options = ['b_pgo', 'b_coverage', + 'b_ndebug', 'b_staticpic', + 'b_lundef', 'b_asneeded' ] + + class ClangCompiler: def __init__(self, clang_type): self.id = 'clang' diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index c10f38edb..fd09e4691 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -25,6 +25,7 @@ from .compilers import ( msvc_winlibs, ClangCompiler, GnuCompiler, + ElbrusCompiler, IntelCompiler, ) @@ -133,6 +134,21 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): return ['-fpch-preprocess', '-include', os.path.basename(header)] +class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): + def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None, **kwargs): + GnuCPPCompiler.__init__(self, exelist, version, gcc_type, is_cross, exe_wrapper, defines, **kwargs) + ElbrusCompiler.__init__(self, gcc_type, defines) + + # It does not support c++/gnu++ 17 and 1z, but still does support 0x, 1y, and gnu++98. + def get_options(self): + opts = super().get_options() + opts['cpp_std'] = coredata.UserComboOption('cpp_std', 'C++ language standard to use', + ['none', 'c++98', 'c++03', 'c++0x', 'c++11', 'c++14', 'c++1y', + 'gnu++98', 'gnu++03', 'gnu++0x', 'gnu++11', 'gnu++14', 'gnu++1y'], + 'none') + return opts + + class IntelCPPCompiler(IntelCompiler, CPPCompiler): def __init__(self, exelist, version, icc_type, is_cross, exe_wrap, **kwargs): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs) diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index f9fcc1cd0..e61c97618 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -27,6 +27,7 @@ from .compilers import ( gnulike_buildtype_args, gnulike_buildtype_linker_args, Compiler, + ElbrusCompiler, IntelCompiler, ) @@ -180,6 +181,12 @@ class GnuFortranCompiler(FortranCompiler): return ['-Wl,--out-implib=' + implibname] +class ElbrusFortranCompiler(GnuFortranCompiler, ElbrusCompiler): + def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None, **kwargs): + GnuFortranCompiler.__init__(self, exelist, version, gcc_type, is_cross, exe_wrapper, defines, **kwargs) + ElbrusCompiler.__init__(self, gcc_type, defines) + + class G95FortranCompiler(FortranCompiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags): super().__init__(exelist, version, is_cross, exe_wrapper=None, **kwags) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index b3b4a55ae..67a0fe0cc 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -49,6 +49,9 @@ from .compilers import ( GnuFortranCompiler, GnuObjCCompiler, GnuObjCPPCompiler, + ElbrusCCompiler, + ElbrusCPPCompiler, + ElbrusFortranCompiler, IntelCCompiler, IntelCPPCompiler, IntelFortranCompiler, @@ -498,15 +501,26 @@ class Environment: continue version = search_version(out) full_version = out.split('\n', 1)[0] - if 'Free Software Foundation' in out or ('e2k' in out and 'lcc' in out): + + guess_gcc_or_lcc = False + if 'Free Software Foundation' in out: + guess_gcc_or_lcc = 'gcc' + if 'e2k' in out and 'lcc' in out: + guess_gcc_or_lcc = 'lcc' + + if guess_gcc_or_lcc: defines = self.get_gnu_compiler_defines(compiler) if not defines: popen_exceptions[' '.join(compiler)] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) version = self.get_gnu_version_from_defines(defines) - cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler + if guess_gcc_or_lcc == 'lcc': + cls = ElbrusCCompiler if lang == 'c' else ElbrusCPPCompiler + else: + cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler return cls(ccache + compiler, version, gtype, is_cross, exe_wrap, defines, full_version=full_version) + if 'clang' in out: if 'Apple' in out or mesonlib.for_darwin(want_cross, self): cltype = CLANG_OSX @@ -559,14 +573,24 @@ class Environment: version = search_version(out) full_version = out.split('\n', 1)[0] + guess_gcc_or_lcc = False if 'GNU Fortran' in out: + guess_gcc_or_lcc = 'gcc' + if 'e2k' in out and 'lcc' in out: + guess_gcc_or_lcc = 'lcc' + + if guess_gcc_or_lcc: defines = self.get_gnu_compiler_defines(compiler) if not defines: popen_exceptions[' '.join(compiler)] = 'no pre-processor defines' continue gtype = self.get_gnu_compiler_type(defines) version = self.get_gnu_version_from_defines(defines) - return GnuFortranCompiler(compiler, version, gtype, is_cross, exe_wrap, defines, full_version=full_version) + if guess_gcc_or_lcc == 'lcc': + cls = ElbrusFortranCompiler + else: + cls = GnuFortranCompiler + return cls(compiler, version, gtype, is_cross, exe_wrap, defines, full_version=full_version) if 'G95' in out: return G95FortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version) diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py index dbb01f717..5c9ed1487 100644 --- a/mesonbuild/modules/rpm.py +++ b/mesonbuild/modules/rpm.py @@ -32,10 +32,17 @@ class RPMModule(ExtensionModule): def generate_spec_template(self, state, args, kwargs): compiler_deps = set() for compiler in state.compilers.values(): + # Elbrus has one 'lcc' package for every compiler if isinstance(compiler, compilers.GnuCCompiler): compiler_deps.add('gcc') elif isinstance(compiler, compilers.GnuCPPCompiler): compiler_deps.add('gcc-c++') + elif isinstance(compiler, compilers.ElbrusCCompiler): + compiler_deps.add('lcc') + elif isinstance(compiler, compilers.ElbrusCPPCompiler): + compiler_deps.add('lcc') + elif isinstance(compiler, compilers.ElbrusFortranCompiler): + compiler_deps.add('lcc') elif isinstance(compiler, compilers.ValaCompiler): compiler_deps.add('vala') elif isinstance(compiler, compilers.GnuFortranCompiler):