|
|
|
@ -253,7 +253,6 @@ class UserOption(T.Generic[_T], HoldableObject): |
|
|
|
|
name: str |
|
|
|
|
description: str |
|
|
|
|
value_: dataclasses.InitVar[_T] |
|
|
|
|
choices: T.Optional[T.Union[str, T.List[_T]]] = None |
|
|
|
|
yielding: bool = DEFAULT_YIELDING |
|
|
|
|
deprecated: DeprecatedType = False |
|
|
|
|
readonly: bool = dataclasses.field(default=False, init=False) |
|
|
|
@ -269,11 +268,7 @@ class UserOption(T.Generic[_T], HoldableObject): |
|
|
|
|
return self.value |
|
|
|
|
|
|
|
|
|
def printable_choices(self) -> T.Optional[T.List[str]]: |
|
|
|
|
if not self.choices: |
|
|
|
|
return None |
|
|
|
|
if isinstance(self.choices, str): |
|
|
|
|
return [self.choices] |
|
|
|
|
return [str(c) for c in self.choices] |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
# Check that the input is a valid value and return the |
|
|
|
|
# "cleaned" or "native" version. For example the Boolean |
|
|
|
@ -287,6 +282,17 @@ class UserOption(T.Generic[_T], HoldableObject): |
|
|
|
|
return self.value != oldvalue |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class EnumeratedUserOption(UserOption[_T]): |
|
|
|
|
|
|
|
|
|
"""A generic UserOption that has enumerated values.""" |
|
|
|
|
|
|
|
|
|
choices: T.List[_T] = dataclasses.field(default_factory=list) |
|
|
|
|
|
|
|
|
|
def printable_choices(self) -> T.Optional[T.List[str]]: |
|
|
|
|
return [str(c) for c in self.choices] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class UserStringOption(UserOption[str]): |
|
|
|
|
|
|
|
|
@ -296,7 +302,7 @@ class UserStringOption(UserOption[str]): |
|
|
|
|
return value |
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class UserBooleanOption(UserOption[bool]): |
|
|
|
|
class UserBooleanOption(EnumeratedUserOption[bool]): |
|
|
|
|
|
|
|
|
|
choices: T.List[bool] = dataclasses.field(default_factory=lambda: [True, False]) |
|
|
|
|
|
|
|
|
@ -327,7 +333,10 @@ class UserIntegerOption(UserOption[int]): |
|
|
|
|
choices.append(f'>= {self.min_value!s}') |
|
|
|
|
if self.max_value is not None: |
|
|
|
|
choices.append(f'<= {self.max_value!s}') |
|
|
|
|
self.choices = ', '.join(choices) |
|
|
|
|
self.__choices: str = ', '.join(choices) |
|
|
|
|
|
|
|
|
|
def printable_choices(self) -> T.Optional[T.List[str]]: |
|
|
|
|
return [self.__choices] |
|
|
|
|
|
|
|
|
|
def validate_value(self, value: T.Any) -> int: |
|
|
|
|
if isinstance(value, str): |
|
|
|
@ -376,7 +385,7 @@ class UserUmaskOption(UserIntegerOption, UserOption[T.Union[str, OctalInt]]): |
|
|
|
|
raise MesonException(f'Invalid mode for option "{self.name}" {e}') |
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class UserComboOption(UserOption[str]): |
|
|
|
|
class UserComboOption(EnumeratedUserOption[str]): |
|
|
|
|
|
|
|
|
|
def validate_value(self, value: T.Any) -> str: |
|
|
|
|
if value not in self.choices: |
|
|
|
@ -390,15 +399,32 @@ class UserComboOption(UserOption[str]): |
|
|
|
|
raise MesonException('Value "{}" (of type "{}") for option "{}" is not one of the choices.' |
|
|
|
|
' Possible choices are (as string): {}.'.format( |
|
|
|
|
value, _type, self.name, optionsstring)) |
|
|
|
|
|
|
|
|
|
assert isinstance(value, str), 'for mypy' |
|
|
|
|
return value |
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class UserArrayOption(UserOption[T.List[str]]): |
|
|
|
|
class UserArrayOption(UserOption[T.List[_T]]): |
|
|
|
|
|
|
|
|
|
value_: dataclasses.InitVar[T.Union[str, T.List[str]]] |
|
|
|
|
value_: dataclasses.InitVar[T.Union[_T, T.List[_T]]] |
|
|
|
|
choices: T.Optional[T.List[_T]] = None |
|
|
|
|
split_args: bool = False |
|
|
|
|
allow_dups: bool = False |
|
|
|
|
|
|
|
|
|
def extend_value(self, value: T.Union[str, T.List[str]]) -> None: |
|
|
|
|
"""Extend the value with an additional value.""" |
|
|
|
|
new = self.validate_value(value) |
|
|
|
|
self.set_value(self.value + new) |
|
|
|
|
|
|
|
|
|
def printable_choices(self) -> T.Optional[T.List[str]]: |
|
|
|
|
if self.choices is None: |
|
|
|
|
return None |
|
|
|
|
return [str(c) for c in self.choices] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class UserStringArrayOption(UserArrayOption[str]): |
|
|
|
|
|
|
|
|
|
def listify(self, value: T.Any) -> T.List[T.Any]: |
|
|
|
|
try: |
|
|
|
|
return listify_array_value(value, self.split_args) |
|
|
|
@ -427,11 +453,6 @@ class UserArrayOption(UserOption[T.List[str]]): |
|
|
|
|
) |
|
|
|
|
return newvalue |
|
|
|
|
|
|
|
|
|
def extend_value(self, value: T.Union[str, T.List[str]]) -> None: |
|
|
|
|
"""Extend the value with an additional value.""" |
|
|
|
|
new = self.validate_value(value) |
|
|
|
|
self.set_value(self.value + new) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass |
|
|
|
|
class UserFeatureOption(UserComboOption): |
|
|
|
@ -471,7 +492,7 @@ class UserStdOption(UserComboOption): |
|
|
|
|
# Map a deprecated std to its replacement. e.g. gnu11 -> c11. |
|
|
|
|
self.deprecated_stds: T.Dict[str, str] = {} |
|
|
|
|
opt_name = 'cpp_std' if lang == 'c++' else f'{lang}_std' |
|
|
|
|
super().__init__(opt_name, f'{lang} language standard to use', 'none', ['none']) |
|
|
|
|
super().__init__(opt_name, f'{lang} language standard to use', 'none', choices=['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) |
|
|
|
@ -637,7 +658,7 @@ BUILTIN_CORE_OPTIONS: T.Dict['OptionKey', 'BuiltinOption'] = OrderedDict([ |
|
|
|
|
(OptionKey('warning_level'), BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3', 'everything'], yielding=False)), |
|
|
|
|
(OptionKey('werror'), BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False, yielding=False)), |
|
|
|
|
(OptionKey('wrap_mode'), BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback', 'nopromote'])), |
|
|
|
|
(OptionKey('force_fallback_for'), BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])), |
|
|
|
|
(OptionKey('force_fallback_for'), BuiltinOption(UserStringArrayOption, 'Force fallback for those subprojects', [])), |
|
|
|
|
(OptionKey('vsenv'), BuiltinOption(UserBooleanOption, 'Activate Visual Studio environment', False, readonly=True)), |
|
|
|
|
|
|
|
|
|
# Pkgconfig module |
|
|
|
@ -660,8 +681,8 @@ BUILTIN_CORE_OPTIONS: T.Dict['OptionKey', 'BuiltinOption'] = OrderedDict([ |
|
|
|
|
BUILTIN_OPTIONS = OrderedDict(chain(BUILTIN_DIR_OPTIONS.items(), BUILTIN_CORE_OPTIONS.items())) |
|
|
|
|
|
|
|
|
|
BUILTIN_OPTIONS_PER_MACHINE: T.Dict['OptionKey', 'BuiltinOption'] = OrderedDict([ |
|
|
|
|
(OptionKey('pkg_config_path'), BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [])), |
|
|
|
|
(OptionKey('cmake_prefix_path'), BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [])), |
|
|
|
|
(OptionKey('pkg_config_path'), BuiltinOption(UserStringArrayOption, 'List of additional paths for pkg-config to search', [])), |
|
|
|
|
(OptionKey('cmake_prefix_path'), BuiltinOption(UserStringArrayOption, 'List of additional prefixes for cmake to search', [])), |
|
|
|
|
]) |
|
|
|
|
|
|
|
|
|
# Special prefix-dependent defaults for installation directories that reside in |
|
|
|
|