aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/coredata.py
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2023-08-30 12:04:09 -0700
committerGitHub <noreply@github.com>2023-08-30 12:04:09 -0700
commit08d83a4a97e66c83d23f10f853d6948921ad144c (patch)
treece6b7197fcf7d450419f699f2d06aa1bf31343fa /mesonbuild/coredata.py
parent494bdbd3345d1c2d20cf2520249962bd32fc61e6 (diff)
parent82a8c72187f844713618526ed3890d7b313b2065 (diff)
downloadmeson-08d83a4a97e66c83d23f10f853d6948921ad144c.zip
meson-08d83a4a97e66c83d23f10f853d6948921ad144c.tar.gz
meson-08d83a4a97e66c83d23f10f853d6948921ad144c.tar.bz2
Merge pull request #10332 from xclaesse/std-opt
c_std, cpp_std: Change to a list of desired versions in preference order
Diffstat (limited to 'mesonbuild/coredata.py')
-rw-r--r--mesonbuild/coredata.py76
1 files changed, 63 insertions, 13 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index b0dad13..4b0f9af 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -248,23 +248,17 @@ class UserComboOption(UserOption[str]):
class UserArrayOption(UserOption[T.List[str]]):
def __init__(self, description: str, value: T.Union[str, T.List[str]],
- split_args: bool = False, user_input: bool = False,
+ split_args: bool = False,
allow_dups: bool = False, yielding: bool = DEFAULT_YIELDING,
choices: T.Optional[T.List[str]] = None,
deprecated: T.Union[bool, str, T.Dict[str, str], T.List[str]] = False):
super().__init__(description, choices if choices is not None else [], yielding, deprecated)
self.split_args = split_args
self.allow_dups = allow_dups
- self.value = self.validate_value(value, user_input=user_input)
-
- def listify(self, value: T.Union[str, T.List[str]], user_input: bool = True) -> T.List[str]:
- # User input is for options defined on the command line (via -D
- # options). Users can put their input in as a comma separated
- # string, but for defining options in meson_options.txt the format
- # should match that of a combo
- if not user_input and isinstance(value, str) and not value.startswith('['):
- raise MesonException('Value does not define an array: ' + value)
+ self.set_value(value)
+ @staticmethod
+ def listify_value(value: T.Union[str, T.List[str]], shlex_split_args: bool = False) -> T.List[str]:
if isinstance(value, str):
if value.startswith('['):
try:
@@ -274,7 +268,7 @@ class UserArrayOption(UserOption[T.List[str]]):
elif value == '':
newvalue = []
else:
- if self.split_args:
+ if shlex_split_args:
newvalue = split_args(value)
else:
newvalue = [v.strip() for v in value.split(',')]
@@ -284,8 +278,11 @@ class UserArrayOption(UserOption[T.List[str]]):
raise MesonException(f'"{value}" should be a string array, but it is not')
return newvalue
- def validate_value(self, value: T.Union[str, T.List[str]], user_input: bool = True) -> T.List[str]:
- newvalue = self.listify(value, user_input)
+ def listify(self, value: T.Any) -> T.List[T.Any]:
+ return self.listify_value(value, self.split_args)
+
+ def validate_value(self, value: T.Union[str, T.List[str]]) -> T.List[str]:
+ newvalue = self.listify(value)
if not self.allow_dups and len(set(newvalue)) != len(newvalue):
msg = 'Duplicated values in array option is deprecated. ' \
@@ -324,6 +321,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):