aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2022-04-28 16:08:24 -0400
committerXavier Claessens <xavier.claessens@collabora.com>2023-08-07 08:28:00 -0400
commit82a8c72187f844713618526ed3890d7b313b2065 (patch)
tree33c8df357aaf530901b8d56dc7832411dec3ab25 /mesonbuild
parent7600856e0a1b1e058ef684928ac29a92218b1257 (diff)
downloadmeson-82a8c72187f844713618526ed3890d7b313b2065.zip
meson-82a8c72187f844713618526ed3890d7b313b2065.tar.gz
meson-82a8c72187f844713618526ed3890d7b313b2065.tar.bz2
c_std, cpp_std: Change to a list of desired versions in preference order
Projects that prefer GNU C but can fallback to ISO C can now set for example `default_options: 'c_std=gnu11,c11'` and it will use gnu11 when available, fallback to c11 otherwise. It is an error only if none of the values are supported by the current compiler. This allows to deprecate gnuXX values from MSVC compiler, that means that `default_options: 'c_std=gnu11'` will now print warning with MSVC but still fallback to 'c11' value. No warning is printed if at least one of the values is valid, i.e. `default_options: 'c_std=gnu11,c11'`. In the future that deprecation warning will become an hard error because `c_std=gnu11` should mean GNU is required, for projects that cannot be built with MSVC for example.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/compilers/c.py114
-rw-r--r--mesonbuild/compilers/cpp.py76
-rw-r--r--mesonbuild/coredata.py53
-rw-r--r--mesonbuild/optinterpreter.py2
4 files changed, 150 insertions, 95 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index d514650..7f9e584 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -56,6 +56,10 @@ if T.TYPE_CHECKING:
else:
CompilerMixinBase = object
+_ALL_STDS = ['c89', 'c9x', 'c90', 'c99', 'c1x', 'c11', 'c17', 'c18', 'c2x']
+_ALL_STDS += [f'gnu{std[1:]}' for std in _ALL_STDS]
+_ALL_STDS += ['iso9899:1990', 'iso9899:199409', 'iso9899:1999', 'iso9899:2011', 'iso9899:2017', 'iso9899:2018']
+
class CCompiler(CLikeCompiler, Compiler):
def attribute_check_func(self, name: str) -> str:
@@ -101,12 +105,9 @@ class CCompiler(CLikeCompiler, Compiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- OptionKey('std', machine=self.for_machine, lang=self.language): coredata.UserComboOption(
- 'C language standard to use',
- ['none'],
- 'none',
- )
+ key: coredata.UserStdOption('C', _ALL_STDS),
})
return opts
@@ -125,20 +126,18 @@ class _ClangCStds(CompilerMixinBase):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
- c_stds = ['c89', 'c99', 'c11']
- g_stds = ['gnu89', 'gnu99', 'gnu11']
+ stds = ['c89', 'c99', 'c11']
# https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html
# https://en.wikipedia.org/wiki/Xcode#Latest_versions
if version_compare(self.version, self._C17_VERSION):
- c_stds += ['c17']
- g_stds += ['gnu17']
+ stds += ['c17']
if version_compare(self.version, self._C18_VERSION):
- c_stds += ['c18']
- g_stds += ['gnu18']
+ stds += ['c18']
if version_compare(self.version, self._C2X_VERSION):
- c_stds += ['c2x']
- g_stds += ['gnu2x']
- opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds
+ stds += ['c2x']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds, gnu=True)
return opts
@@ -244,8 +243,9 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c90', 'c99', 'c11'], gnu=True)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -285,16 +285,15 @@ class GnuCCompiler(GnuCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- c_stds = ['c89', 'c99', 'c11']
- g_stds = ['gnu89', 'gnu99', 'gnu11']
+ stds = ['c89', 'c99', 'c11']
if version_compare(self.version, self._C18_VERSION):
- c_stds += ['c17', 'c18']
- g_stds += ['gnu17', 'gnu18']
+ stds += ['c17', 'c18']
if version_compare(self.version, self._C2X_VERSION):
- c_stds += ['c2x']
- g_stds += ['gnu2x']
+ stds += ['c2x']
key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none'] + c_stds + g_stds
+ std_opt = opts[key]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds, gnu=True)
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
key.evolve('winlibs'): coredata.UserArrayOption(
@@ -370,7 +369,9 @@ class ElbrusCCompiler(ElbrusCompiler, CCompiler):
stds += ['c90', 'c1x', 'gnu90', 'gnu1x', 'iso9899:2011']
if version_compare(self.version, '>=1.26.00'):
stds += ['c17', 'c18', 'iso9899:2017', 'iso9899:2018', 'gnu17', 'gnu18']
- opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + stds
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds)
return opts
# Elbrus C compiler does not have lchmod, but there is only linker warning, not compiler error.
@@ -404,11 +405,12 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- c_stds = ['c89', 'c99']
- g_stds = ['gnu89', 'gnu99']
+ stds = ['c89', 'c99']
if version_compare(self.version, '>=16.0.0'):
- c_stds += ['c11']
- opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds
+ stds += ['c11']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds, gnu=True)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -465,33 +467,23 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
- c_stds = ['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
- g_stds = ['gnu89', 'gnu90', 'gnu9x', 'gnu99']
+ stds = ['c89', 'c99']
if version_compare(self.version, self._C11_VERSION):
- c_stds += ['c11']
- g_stds += ['gnu1x', 'gnu11']
+ stds += ['c11']
if version_compare(self.version, self._C17_VERSION):
- c_stds += ['c17', 'c18']
- g_stds += ['gnu17', 'gnu18']
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none'] + c_stds + g_stds
+ stds += ['c17', 'c18']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds, gnu=True, gnu_deprecated=True)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
- 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.8, /std:c11 and /std:c17 are the only valid C standard options.
- if std.value in {'c11', 'gnu1x', 'gnu11'}:
+ if std.value in {'c11'}:
args.append('/std:c11')
- elif std.value in {'c17', 'c18', 'gnu17', 'gnu18'}:
+ elif std.value in {'c17', 'c18'}:
args.append('/std:c17')
return args
@@ -531,8 +523,9 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c89', 'c99', 'c11']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c89', 'c99', 'c11'])
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -564,8 +557,9 @@ class ArmCCompiler(ArmCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c89', 'c99', 'c11']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c89', 'c99', 'c11'])
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -593,8 +587,9 @@ class CcrxCCompiler(CcrxCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c89', 'c99']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c89', 'c99'])
return opts
def get_no_stdinc_args(self) -> T.List[str]:
@@ -640,8 +635,9 @@ class Xc16CCompiler(Xc16Compiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c89', 'c99'], gnu=True)
return opts
def get_no_stdinc_args(self) -> T.List[str]:
@@ -685,8 +681,9 @@ class CompCertCCompiler(CompCertCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c89', 'c99']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c89', 'c99'])
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -722,8 +719,9 @@ class TICCompiler(TICompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c89', 'c99', 'c11']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c89', 'c99', 'c11'])
return opts
def get_no_stdinc_args(self) -> T.List[str]:
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 8c80437..3e96682 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -55,6 +55,10 @@ if T.TYPE_CHECKING:
else:
CompilerMixinBase = object
+_ALL_STDS = ['c++98', 'c++0x', 'c++03', 'c++1y', 'c++1z', 'c++11', 'c++14', 'c++17', 'c++2a', 'c++20', 'c++23']
+_ALL_STDS += [f'gnu{std[1:]}' for std in _ALL_STDS]
+_ALL_STDS += ['vc++11', 'vc++14', 'vc++17', 'vc++20', 'vc++latest', 'c++latest']
+
def non_msvc_eh_options(eh: str, args: T.List[str]) -> None:
if eh == 'none':
@@ -178,11 +182,7 @@ class CPPCompiler(CLikeCompiler, Compiler):
opts = super().get_options()
key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- key: coredata.UserComboOption(
- 'C++ language standard to use',
- ['none'],
- 'none',
- ),
+ key: coredata.UserStdOption('C++', _ALL_STDS),
})
return opts
@@ -257,17 +257,15 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCompiler, CPPCompiler):
key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True),
})
cppstd_choices = [
- 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z',
- 'c++2a', 'c++20', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z',
- 'gnu++2a', 'gnu++20',
+ 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 'c++20',
]
if version_compare(self.version, self._CPP23_VERSION):
cppstd_choices.append('c++23')
- cppstd_choices.append('gnu++23')
if version_compare(self.version, self._CPP26_VERSION):
cppstd_choices.append('c++26')
- cppstd_choices.append('gnu++26')
- opts[key.evolve('std')].choices = cppstd_choices
+ std_opt = opts[key.evolve('std')]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(cppstd_choices, gnu=True)
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
key.evolve('winlibs'): coredata.UserArrayOption(
@@ -371,10 +369,9 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
'default',
),
})
- opts[key].choices = [
- 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'gnu++98',
- 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17',
- ]
+ std_opt = opts[key]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c++98', 'c++03', 'c++11', 'c++14', 'c++17'], gnu=True)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -426,17 +423,16 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler):
)
})
cppstd_choices = [
- 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z',
- 'c++2a', 'c++20', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17',
- 'gnu++1z', 'gnu++2a', 'gnu++20',
+ 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z',
+ 'c++2a', 'c++20',
]
if version_compare(self.version, '>=12.2.0'):
cppstd_choices.append('c++23')
- cppstd_choices.append('gnu++23')
if version_compare(self.version, '>=14.0.0'):
cppstd_choices.append('c++26')
- cppstd_choices.append('gnu++26')
- opts[key].choices = cppstd_choices
+ std_opt = opts[key]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(cppstd_choices, gnu=True)
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
key.evolve('winlibs'): coredata.UserArrayOption(
@@ -513,21 +509,21 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CPPCompiler.get_options(self)
- cpp_stds = ['none', 'c++98', 'gnu++98']
+ cpp_stds = ['c++98']
if version_compare(self.version, '>=1.20.00'):
- cpp_stds += ['c++03', 'c++0x', 'c++11', 'gnu++03', 'gnu++0x', 'gnu++11']
+ cpp_stds += ['c++03', 'c++0x', 'c++11']
if version_compare(self.version, '>=1.21.00') and version_compare(self.version, '<1.22.00'):
- cpp_stds += ['c++14', 'gnu++14', 'c++1y', 'gnu++1y']
+ cpp_stds += ['c++14', 'c++1y']
if version_compare(self.version, '>=1.22.00'):
- cpp_stds += ['c++14', 'gnu++14']
+ cpp_stds += ['c++14']
if version_compare(self.version, '>=1.23.00'):
- cpp_stds += ['c++1y', 'gnu++1y']
+ cpp_stds += ['c++1y']
if version_compare(self.version, '>=1.24.00'):
- cpp_stds += ['c++1z', 'c++17', 'gnu++1z', 'gnu++17']
+ cpp_stds += ['c++1z', 'c++17']
if version_compare(self.version, '>=1.25.00'):
- cpp_stds += ['c++2a', 'gnu++2a']
+ cpp_stds += ['c++2a']
if version_compare(self.version, '>=1.26.00'):
- cpp_stds += ['c++20', 'gnu++20']
+ cpp_stds += ['c++20']
key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
@@ -541,7 +537,9 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler):
False,
),
})
- opts[key].choices = cpp_stds
+ std_opt = opts[key]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(cpp_stds, gnu=True)
return opts
# Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error.
@@ -615,7 +613,9 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True),
key.evolve('debugstl'): coredata.UserBooleanOption('STL debug mode', False),
})
- opts[key].choices = ['none'] + c_stds + g_stds
+ std_opt = opts[key]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(c_stds + g_stds)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -682,7 +682,9 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
msvc_winlibs,
),
})
- opts[key.evolve('std')].choices = cpp_stds
+ std_opt = opts[key]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(cpp_stds)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -846,8 +848,9 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CPPCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c++03', 'c++11']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c++03', 'c++11'])
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -906,8 +909,9 @@ class TICPPCompiler(TICompiler, CPPCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CPPCompiler.get_options(self)
- key = OptionKey('std', machine=self.for_machine, lang=self.language)
- opts[key].choices = ['none', 'c++03']
+ std_opt = opts[OptionKey('std', machine=self.for_machine, lang=self.language)]
+ assert isinstance(std_opt, coredata.UserStdOption), 'for mypy'
+ std_opt.set_versions(['c++03'])
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 97261d6..1184866 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -320,6 +320,59 @@ class UserFeatureOption(UserComboOption):
def is_auto(self) -> bool:
return self.value == 'auto'
+class UserStdOption(UserComboOption):
+ '''
+ UserOption specific to c_std and cpp_std options. User can set a list of
+ STDs in preference order and it selects the first one supported by current
+ compiler.
+
+ For historical reasons, some compilers (msvc) allowed setting a GNU std and
+ silently fell back to C std. This is now deprecated. Projects that support
+ both GNU and MSVC compilers should set e.g. c_std=gnu11,c11.
+
+ This is not using self.deprecated mechanism we already have for project
+ options because we want to print a warning if ALL values are deprecated, not
+ if SOME values are deprecated.
+ '''
+ def __init__(self, lang: str, all_stds: T.List[str]) -> None:
+ self.lang = lang.lower()
+ self.all_stds = ['none'] + all_stds
+ # Map a deprecated std to its replacement. e.g. gnu11 -> c11.
+ self.deprecated_stds: T.Dict[str, str] = {}
+ super().__init__(f'{lang} language standard to use', ['none'], 'none')
+
+ def set_versions(self, versions: T.List[str], gnu: bool = False, gnu_deprecated: bool = False) -> None:
+ assert all(std in self.all_stds for std in versions)
+ self.choices += versions
+ if gnu:
+ gnu_stds_map = {f'gnu{std[1:]}': std for std in versions}
+ if gnu_deprecated:
+ self.deprecated_stds.update(gnu_stds_map)
+ else:
+ self.choices += gnu_stds_map.keys()
+
+ def validate_value(self, value: T.Union[str, T.List[str]]) -> str:
+ candidates = UserArrayOption.listify_value(value)
+ unknown = [std for std in candidates if std not in self.all_stds]
+ if unknown:
+ raise MesonException(f'Unknown {self.lang.upper()} std {unknown}. Possible values are {self.all_stds}.')
+ # Check first if any of the candidates are not deprecated
+ for std in candidates:
+ if std in self.choices:
+ return std
+ # Fallback to a deprecated std if any
+ for std in candidates:
+ newstd = self.deprecated_stds.get(std)
+ if newstd is not None:
+ mlog.deprecation(
+ f'None of the values {candidates} are supported by the {self.lang} compiler.\n' +
+ f'However, the deprecated {std} std currently falls back to {newstd}.\n' +
+ 'This will be an error in the future.\n' +
+ 'If the project supports both GNU and MSVC compilers, a value such as\n' +
+ '"c_std=gnu11,c11" specifies that GNU is prefered but it can safely fallback to plain c11.')
+ return newstd
+ raise MesonException(f'None of values {candidates} are supported by the {self.lang.upper()} compiler. ' +
+ f'Possible values are {self.choices}')
class DependencyCacheType(enum.Enum):
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 2756997..8ad84aa 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -268,7 +268,7 @@ class OptionInterpreter:
value = kwargs['value'] if kwargs['value'] is not None else choices
if isinstance(value, str):
if value.startswith('['):
- FeatureDeprecated('String value for array option', '1.2.0').use(self.subproject)
+ FeatureDeprecated('String value for array option', '1.3.0').use(self.subproject)
else:
raise mesonlib.MesonException('Value does not define an array: ' + value)
return coredata.UserArrayOption(description, value,