From 333e0aeef4b2cc7be82a89c3a1a5a4a4b9af2b53 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sat, 17 Oct 2020 17:11:42 +0300 Subject: [PATCH 1/6] Make MSVC accept gnu11 as a language standard version. Closes: #7611. Fixes: #7611 --- mesonbuild/compilers/c.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 95c469873..8d0a52bfa 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -428,7 +428,11 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi def get_options(self) -> 'OptionDictType': opts = super().get_options() - c_stds = ['none', 'c89', 'c99', 'c11'] + c_stds = ['none', 'c89', 'c99', 'c11', + # Need to have these to be compatible with projects + # that set c_std to e.g. gnu99. + # https://github.com/mesonbuild/meson/issues/7611 + 'gnu89', 'gnu90', 'gnu9x', 'gnu99', 'gnu1x', 'gnu11'] opts.update({ 'std': coredata.UserComboOption( 'C language standard to use', @@ -442,8 +446,8 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi args = [] std = options['std'] # As of MVSC 16.7, /std:c11 is the only valid C standard option. - if std.value in {'c11'}: - args.append('/std:' + std.value) + if std.value in {'c11', 'gnu11'}: + args.append('/std:c11') return args From 3e62307f3a5d184c8c331de2809d5eaa38f001fd Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 19 Oct 2020 09:28:46 -0700 Subject: [PATCH 2/6] compilers/c: Clang-cl also needs specific handling for standards --- mesonbuild/compilers/c.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 8d0a52bfa..fd3ebc051 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -462,6 +462,25 @@ class ClangClCCompiler(ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompile full_version=full_version) ClangClCompiler.__init__(self, target) + def get_options(self) -> 'OptionDictType': + # Clang-cl can compile up to c99, but doesn't have a std-swtich for + # them. Unlike recent versions of MSVC it doesn't (as of 10.0.1) + # support c11 + opts = super().get_options() + c_stds = ['none', 'c89', 'c99', + # Need to have these to be compatible with projects + # that set c_std to e.g. gnu99. + # https://github.com/mesonbuild/meson/issues/7611 + 'gnu89', 'gnu90', 'gnu9x', 'gnu99'] + opts.update({ + 'std': coredata.UserComboOption( + 'C language standard to use', + c_stds, + 'none', + ), + }) + return opts + class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin, CCompiler): From a28a34c6845144d2e947bd698244fb33909b4d45 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 29 Sep 2020 10:11:30 -0700 Subject: [PATCH 3/6] compilers: Standardize the names of compiler options Most options don't use language prefaced options (std vs c_std) internally, as we don't need that due to namespacing. Let's do that across the board --- mesonbuild/compilers/c.py | 18 +++++++++--------- mesonbuild/compilers/cpp.py | 6 +++--- mesonbuild/compilers/cuda.py | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index fd3ebc051..c136c6d07 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -615,9 +615,9 @@ class Xc16CCompiler(Xc16Compiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({'c_std': coredata.UserComboOption('C language standard to use', - ['none', 'c89', 'c99', 'gnu89', 'gnu99'], - 'none')}) + opts.update({'std': coredata.UserComboOption('C language standard to use', + ['none', 'c89', 'c99', 'gnu89', 'gnu99'], + 'none')}) return opts def get_no_stdinc_args(self) -> T.List[str]: @@ -660,9 +660,9 @@ class CompCertCCompiler(CompCertCompiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({'c_std': coredata.UserComboOption('C language standard to use', - ['none', 'c89', 'c99'], - 'none')}) + opts.update({'std': coredata.UserComboOption('C language standard to use', + ['none', 'c89', 'c99'], + 'none')}) return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -698,9 +698,9 @@ class C2000CCompiler(C2000Compiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({'c_std': coredata.UserComboOption('C language standard to use', - ['none', 'c89', 'c99', 'c11'], - 'none')}) + opts.update({'std': coredata.UserComboOption('C language standard to use', + ['none', 'c89', 'c99', 'c11'], + 'none')}) return opts def get_no_stdinc_args(self) -> T.List[str]: diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 3e9764a86..afc812a93 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -790,9 +790,9 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler): def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) - opts.update({'cpp_std': coredata.UserComboOption('C++ language standard to use', - ['none', 'c++03'], - 'none')}) + opts.update({'std': coredata.UserComboOption('C++ language standard to use', + ['none', 'c++03'], + 'none')}) return opts def get_always_args(self) -> T.List[str]: diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 603ad1321..89fcf400f 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -197,9 +197,9 @@ class CudaCompiler(Compiler): def get_options(self) -> 'OptionDictType': opts = super().get_options() - opts.update({'cuda_std': coredata.UserComboOption('C++ language standard to use', - ['none', 'c++03', 'c++11', 'c++14'], - 'none')}) + opts.update({'std': coredata.UserComboOption('C++ language standard to use with cuda', + ['none', 'c++03', 'c++11', 'c++14'], + 'none')}) return opts def _to_host_compiler_options(self, options: 'OptionDictType') -> 'OptionDictType': @@ -212,7 +212,7 @@ class CudaCompiler(Compiler): # the combination of CUDA version and MSVC version; the --std= is thus ignored # and attempting to use it will result in a warning: https://stackoverflow.com/a/51272091/741027 if not is_windows(): - std = options['cuda_std'] + std = options['std'] if std.value != 'none': args.append('--std=' + std.value) From 2844afedde3992564e0de4538b29781a420f8576 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 13 Oct 2020 10:09:38 -0700 Subject: [PATCH 4/6] compilers: define standards in the base language compiler And then update the choices in each leaf class. This way we don't end up with another case where we implicitly allow an invalid standard to be set on a compiler that doesn't have a 'std' setting currently. --- mesonbuild/compilers/c.py | 112 ++++++++------------------------ mesonbuild/compilers/cpp.py | 74 +++++++++------------ mesonbuild/compilers/fortran.py | 37 ++++------- 3 files changed, 71 insertions(+), 152 deletions(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index c136c6d07..886090651 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -95,6 +95,17 @@ class CCompiler(CLikeCompiler, Compiler): return self.compiles(t.format(**fargs), env, extra_args=extra_args, dependencies=dependencies) + def get_options(self) -> 'OptionDictType': + opts = super().get_options() + opts.update({ + 'std': coredata.UserComboOption( + 'C langauge standard to use', + ['none'], + 'none', + ) + }) + return opts + class ClangCCompiler(ClangCompiler, CCompiler): @@ -130,13 +141,7 @@ class ClangCCompiler(ClangCompiler, CCompiler): if version_compare(self.version, self._C2X_VERSION): c_stds += ['c2x'] g_stds += ['gnu2x'] - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - ['none'] + c_stds + g_stds, - 'none', - ), - }) + opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore if self.info.is_windows() or self.info.is_cygwin(): opts.update({ 'winlibs': coredata.UserArrayOption( @@ -207,13 +212,7 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11'], - 'none', - ), - }) + opts['std'].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -255,13 +254,7 @@ class GnuCCompiler(GnuCompiler, CCompiler): if version_compare(self.version, self._C2X_VERSION): c_stds += ['c2x'] g_stds += ['gnu2x'] - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - ['none'] + c_stds + g_stds, - 'none', - ), - }) + opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore if self.info.is_windows() or self.info.is_cygwin(): opts.update({ 'winlibs': coredata.UserArrayOption( @@ -327,17 +320,11 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler): # 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) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({ - 'std': coredata.UserComboOption( - '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', - ), - }) + opts['std'].choices = [ # type: ignore + 'none', 'c89', 'c90', 'c9x', 'c99', 'c1x', 'c11', + 'gnu89', 'gnu90', 'gnu9x', 'gnu99', 'gnu1x', 'gnu11', + 'iso9899:2011', 'iso9899:1990', 'iso9899:199409', 'iso9899:1999', + ] return opts # Elbrus C compiler does not have lchmod, but there is only linker warning, not compiler error. @@ -374,13 +361,7 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): g_stds = ['gnu89', 'gnu99'] if version_compare(self.version, '>=16.0.0'): c_stds += ['c11'] - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - ['none'] + c_stds + g_stds, - 'none', - ), - }) + opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -433,13 +414,7 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi # that set c_std to e.g. gnu99. # https://github.com/mesonbuild/meson/issues/7611 'gnu89', 'gnu90', 'gnu9x', 'gnu99', 'gnu1x', 'gnu11'] - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - c_stds, - 'none', - ), - }) + opts['std'].choices = c_stds # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -472,13 +447,7 @@ class ClangClCCompiler(ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompile # that set c_std to e.g. gnu99. # https://github.com/mesonbuild/meson/issues/7611 'gnu89', 'gnu90', 'gnu9x', 'gnu99'] - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - c_stds, - 'none', - ), - }) + opts['std'].choices = c_stds # type: ignore return opts @@ -498,14 +467,7 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM def get_options(self) -> 'OptionDictType': opts = super().get_options() - c_stds = ['none', 'c89', 'c99', 'c11'] - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - c_stds, - 'none', - ), - }) + opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -531,13 +493,7 @@ class ArmCCompiler(ArmCompiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - ['none', 'c90', 'c99'], - 'none', - ), - }) + opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -564,13 +520,7 @@ class CcrxCCompiler(CcrxCompiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({ - 'std': coredata.UserComboOption( - 'C language standard to use', - ['none', 'c89', 'c99'], - 'none', - ), - }) + opts['std'].choices = ['none', 'c89', 'c99'] # type: ignore return opts def get_no_stdinc_args(self) -> T.List[str]: @@ -615,9 +565,7 @@ class Xc16CCompiler(Xc16Compiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({'std': coredata.UserComboOption('C language standard to use', - ['none', 'c89', 'c99', 'gnu89', 'gnu99'], - 'none')}) + opts['std'].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99'] # type: ignore return opts def get_no_stdinc_args(self) -> T.List[str]: @@ -660,9 +608,7 @@ class CompCertCCompiler(CompCertCompiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({'std': coredata.UserComboOption('C language standard to use', - ['none', 'c89', 'c99'], - 'none')}) + opts['std'].choices = ['none', 'c89', 'c99'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -698,9 +644,7 @@ class C2000CCompiler(C2000Compiler, CCompiler): def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) - opts.update({'std': coredata.UserComboOption('C language standard to use', - ['none', 'c89', 'c99', 'c11'], - 'none')}) + opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore return opts def get_no_stdinc_args(self) -> T.List[str]: diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index afc812a93..6ba87eb2d 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -167,6 +167,17 @@ class CPPCompiler(CLikeCompiler, Compiler): raise MesonException('C++ Compiler does not support -std={}'.format(cpp_std)) + def get_options(self) -> 'OptionDictType': + opts = super().get_options() + opts.update({ + 'std': coredata.UserComboOption( + 'C++ language standard to use', + ['none'], + 'none', + ), + }) + return opts + class ClangCPPCompiler(ClangCompiler, CPPCompiler): def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, @@ -192,13 +203,11 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): 'default', ), 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'std': coredata.UserComboOption( - 'C++ language standard to use', - ['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', - 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'], - 'none', - ), }) + opts['std'].choices = [ # type: ignore + 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', + 'c++2a', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a', + ] if self.info.is_windows() or self.info.is_cygwin(): opts.update({ 'winlibs': coredata.UserArrayOption( @@ -283,15 +292,11 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'std': coredata.UserComboOption( - 'C++ language standard to use', - [ - 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', - 'gnu++98', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', - ], - 'none', - ), }) + opts['std'].choices = [ # type: ignore + 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'gnu++98', + 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', + ] return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -332,17 +337,16 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): 'default', ), 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'std': coredata.UserComboOption( - 'C++ language standard to use', - ['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', - 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'], - 'none', - ), 'debugstl': coredata.UserBooleanOption( 'STL debug mode', False, ) }) + opts['std'].choices = [ # type: ignore + 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', + 'c++2a', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', + 'gnu++2a', + ] if self.info.is_windows() or self.info.is_cygwin(): opts.update({ 'winlibs': coredata.UserArrayOption( @@ -437,16 +441,12 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'std': coredata.UserComboOption( - 'C++ language standard to use', - cpp_stds, - 'none', - ), 'debugstl': coredata.UserBooleanOption( 'STL debug mode', False, ), }) + opts['std'].choices = cpp_stds # type: ignore return opts # Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error. @@ -515,13 +515,9 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): 'default', ), 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'std': coredata.UserComboOption( - 'C++ language standard to use', - ['none'] + c_stds + g_stds, - 'none', - ), 'debugstl': coredata.UserBooleanOption('STL debug mode', False), }) + opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -573,16 +569,12 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): 'default', ), 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'std': coredata.UserComboOption( - 'C++ language standard to use', - cpp_stds, - 'none', - ), 'winlibs': coredata.UserArrayOption( 'Windows libs to link against.', msvc_winlibs, ), }) + opts['std'].choices = cpp_stds # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -726,13 +718,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) - opts.update({ - 'std': coredata.UserComboOption( - 'C++ language standard to use', - ['none', 'c++03', 'c++11'], - 'none', - ), - }) + opts['std'].choices = ['none', 'c++03', 'c++11'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -790,9 +776,7 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler): def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) - opts.update({'std': coredata.UserComboOption('C++ language standard to use', - ['none', 'c++03'], - 'none')}) + opts['std'].choices = ['none', 'c++03'] # type: ignore return opts def get_always_args(self) -> T.List[str]: diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index e85ee6d28..036369a73 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -150,6 +150,17 @@ class FortranCompiler(CLikeCompiler, Compiler): def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: return self._has_multi_link_arguments(args, env, 'stop; end program') + def get_options(self) -> 'OptionDictType': + opts = super().get_options() + opts.update({ + 'std': coredata.UserComboOption( + 'Fortran language standard to use', + ['none'], + 'none', + ), + }) + return opts + class GnuFortranCompiler(GnuCompiler, FortranCompiler): @@ -175,13 +186,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): fortran_stds += ['f2008'] if version_compare(self.version, '>=8.0.0'): fortran_stds += ['f2018'] - opts.update({ - 'std': coredata.UserComboOption( - 'Fortran language standard to use', - ['none'] + fortran_stds, - 'none', - ), - }) + opts['std'].choices = ['none'] + fortran_stds # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -310,14 +315,7 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): def get_options(self) -> 'OptionDictType': opts = FortranCompiler.get_options(self) - fortran_stds = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] - opts.update({ - 'std': coredata.UserComboOption( - 'Fortran language standard to use', - ['none'] + fortran_stds, - 'none', - ), - }) + opts['std'].choices = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -367,14 +365,7 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): def get_options(self) -> 'OptionDictType': opts = FortranCompiler.get_options(self) - fortran_stds = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] - opts.update({ - 'std': coredata.UserComboOption( - 'Fortran language standard to use', - ['none'] + fortran_stds, - 'none', - ), - }) + opts['std'].choices = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] # type: ignore return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: From 0217faf13f13b9899f480513f248611893d23871 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 19 Oct 2020 09:34:41 -0700 Subject: [PATCH 5/6] compilers/c: Log that MSVC doesn't support gnu stds Since the current approach of demoting to the nearest C standard *might* work, but might not. For projects like Glib that detect which standard is used and fall back this is fine. For projects like libdrm that only work with gnu standards, this wont. We're nog tusing a warning because this shouldn't be fatal if --meson-fatal-warnings is used. Also demote a similar message in IntelCl from warning to log. --- mesonbuild/compilers/c.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 886090651..78185b204 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -420,6 +420,11 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] + if std.value.startswith('gnu'): + mlog.log( + 'cl.exe does not actually support gnu standards, and meson ' + 'will instead demote to the nearest ISO C standard. This ' + 'may cause compilation to fail.', once=True) # As of MVSC 16.7, /std:c11 is the only valid C standard option. if std.value in {'c11', 'gnu11'}: args.append('/std:c11') @@ -449,6 +454,13 @@ class ClangClCCompiler(ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompile 'gnu89', 'gnu90', 'gnu9x', 'gnu99'] opts['std'].choices = c_stds # type: ignore return opts + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + if options['std'].value.startswith('gnu'): + mlog.warning( + 'Clang-cl does not actually support gnu standards, and ' + 'meson will instead demote to the nearest ISO C standard. This ' + 'may cause compilation to fail.', once=True) + return [] class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin, CCompiler): @@ -474,7 +486,7 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM args = [] std = options['std'] if std.value == 'c89': - mlog.warning("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.", once=True) + mlog.log("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.", once=True) elif std.value != 'none': args.append('/Qstd:' + std.value) return args From f31acbe2a4492c5d513c42277ff0f603e3f53560 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 27 Oct 2020 09:17:28 -0700 Subject: [PATCH 6/6] clang-cl: Allow clang-cl (when compiling C) to pass std to underlying clang) This allows a wider array of standard support than would be available directly from clang-cl, emulating MSVC stds. --- mesonbuild/compilers/c.py | 67 +++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 78185b204..49008768a 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -1,4 +1,4 @@ -# Copyright 2012-2017 The Meson development team +# Copyright 2012-2020 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -107,27 +107,20 @@ class CCompiler(CLikeCompiler, Compiler): return opts -class ClangCCompiler(ClangCompiler, CCompiler): +class _ClangCStds(CompilerMixinBase): + + """Mixin class for clang based compilers for setting C standards. + + This is used by both ClangCCompiler and ClangClCompiler, as they share + the same versions + """ _C17_VERSION = '>=6.0.0' _C18_VERSION = '>=8.0.0' _C2X_VERSION = '>=9.0.0' - def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, - linker: T.Optional['DynamicLinker'] = None, - defines: T.Optional[T.Dict[str, str]] = None, - full_version: T.Optional[str] = None): - CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) - ClangCompiler.__init__(self, defines) - default_warn_args = ['-Wall', '-Winvalid-pch'] - self.warn_args = {'0': [], - '1': default_warn_args, - '2': default_warn_args + ['-Wextra'], - '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': - opts = CCompiler.get_options(self) + opts = super().get_options() c_stds = ['c89', 'c99', 'c11'] g_stds = ['gnu89', 'gnu99', 'gnu11'] # https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html @@ -142,6 +135,26 @@ class ClangCCompiler(ClangCompiler, CCompiler): c_stds += ['c2x'] g_stds += ['gnu2x'] opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore + return opts + + +class ClangCCompiler(_ClangCStds, ClangCompiler, CCompiler): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) + ClangCompiler.__init__(self, defines) + default_warn_args = ['-Wall', '-Winvalid-pch'] + self.warn_args = {'0': [], + '1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} + + def get_options(self) -> 'OptionDictType': + opts = super().get_options() if self.info.is_windows() or self.info.is_cygwin(): opts.update({ 'winlibs': coredata.UserArrayOption( @@ -431,7 +444,7 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi return args -class ClangClCCompiler(ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler): +class ClangClCCompiler(_ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler): def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', target: str, exe_wrapper: T.Optional['ExternalProgram'] = None, @@ -442,24 +455,10 @@ class ClangClCCompiler(ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompile full_version=full_version) ClangClCompiler.__init__(self, target) - def get_options(self) -> 'OptionDictType': - # Clang-cl can compile up to c99, but doesn't have a std-swtich for - # them. Unlike recent versions of MSVC it doesn't (as of 10.0.1) - # support c11 - opts = super().get_options() - c_stds = ['none', 'c89', 'c99', - # Need to have these to be compatible with projects - # that set c_std to e.g. gnu99. - # https://github.com/mesonbuild/meson/issues/7611 - 'gnu89', 'gnu90', 'gnu9x', 'gnu99'] - opts['std'].choices = c_stds # type: ignore - return opts def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: - if options['std'].value.startswith('gnu'): - mlog.warning( - 'Clang-cl does not actually support gnu standards, and ' - 'meson will instead demote to the nearest ISO C standard. This ' - 'may cause compilation to fail.', once=True) + std = options['std'].value + if std != "none": + return ['/clang:-std={}'.format(std)] return []