Conan: Align binary option values with conan-center recipes
The recipes in conan-center use True/False option values for common binary options, for example: - shared - release Currently the binary option values for Qt recipes use 'yes'/'no' values which makes the consumption of Qt conan packages suboptimal. Example: $ conan install .. -o qtbase:shared=yes -o shared=True After the change one can use: $ conan install .. -o shared=True The shared=True is applied to all packages in the dependency tree including Qt now. Adjust how the booleaness is checked for Conan options which are wrapped with PackageOptionValue. Task-number: QTBUG-99558 Change-Id: I52e16d76418ac3c3e9d653e77287ae89248675d7 Reviewed-by: Toni Saario <toni.saario@qt.io> (cherry picked from commit 8775528e9a998c7b91b68c7e10e9aaf97838ae3c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
7a4ae41040
commit
dae16a2ca7
89
conanfile.py
89
conanfile.py
@ -113,7 +113,7 @@ class QtConfigureOption(object):
|
|||||||
# The 'None' is added as a possible value. For Conan this means it is not mandatory to pass
|
# The 'None' is added as a possible value. For Conan this means it is not mandatory to pass
|
||||||
# this option for the build.
|
# this option for the build.
|
||||||
if self._binary_option:
|
if self._binary_option:
|
||||||
return ["yes", "no", None]
|
return [True, False, None]
|
||||||
if self.possible_values == ["ANY"]:
|
if self.possible_values == ["ANY"]:
|
||||||
# For 'ANY' value it can not be a List type for Conan
|
# For 'ANY' value it can not be a List type for Conan
|
||||||
return "ANY"
|
return "ANY"
|
||||||
@ -251,16 +251,15 @@ class QtOptionParser:
|
|||||||
opt.update(self.extra_options_default_values)
|
opt.update(self.extra_options_default_values)
|
||||||
return opt
|
return opt
|
||||||
|
|
||||||
def is_used_option(self, conan_option_value: str) -> bool:
|
def is_used_option(self, conan_options: Options, option_name: str) -> bool:
|
||||||
# conan install ... -o release=no -> configure(.bat)
|
# conan install ... -o release=False -> configure(.bat)
|
||||||
# conan install ... -> configure(.bat)
|
# conan install ... -> configure(.bat)
|
||||||
# conan install ... -o release=yes -> configure(.bat) -release
|
# conan install ... -o release=True -> configure(.bat) -release
|
||||||
if not conan_option_value or conan_option_value == "None" or conan_option_value == "no":
|
return bool(conan_options.get_safe(option_name))
|
||||||
# Conan seems to convert None to literal 'None'?
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def convert_conan_option_to_qt_option(self, name: str, value: Any) -> str:
|
def convert_conan_option_to_qt_option(
|
||||||
|
self, conan_options: Options, name: str, value: Any
|
||||||
|
) -> str:
|
||||||
ret: str = ""
|
ret: str = ""
|
||||||
|
|
||||||
def _find_qt_option(conan_option_name: str) -> QtConfigureOption:
|
def _find_qt_option(conan_option_name: str) -> QtConfigureOption:
|
||||||
@ -281,7 +280,7 @@ class QtOptionParser:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.is_used_option(value) and not _is_excluded_from_configure():
|
if self.is_used_option(conan_options, name) and not _is_excluded_from_configure():
|
||||||
qt_option = _find_qt_option(name)
|
qt_option = _find_qt_option(name)
|
||||||
if qt_option.incremental_option:
|
if qt_option.incremental_option:
|
||||||
# e.g. -make=libs -make=examples <-> -o make=libs;examples;foo;bar
|
# e.g. -make=libs -make=examples <-> -o make=libs;examples;foo;bar
|
||||||
@ -297,24 +296,23 @@ class QtOptionParser:
|
|||||||
def convert_conan_options_to_qt_options(self, conan_options: Options) -> List[str]:
|
def convert_conan_options_to_qt_options(self, conan_options: Options) -> List[str]:
|
||||||
qt_options: List[str] = []
|
qt_options: List[str] = []
|
||||||
|
|
||||||
def _option_enabled(options: Dict[str, Any], opt: str) -> bool:
|
def _option_enabled(opt: str) -> bool:
|
||||||
return opt in options and options[opt] == "yes"
|
return bool(conan_options.get_safe(opt))
|
||||||
|
|
||||||
def _option_disabled(options: Dict[str, Any], opt: str) -> bool:
|
def _option_disabled(opt: str) -> bool:
|
||||||
return opt in options and options[opt] == "no"
|
return not bool(conan_options.get_safe(opt))
|
||||||
|
|
||||||
def _filter_overlapping_options(options: Dict[str, Any]) -> None:
|
def _filter_overlapping_options() -> None:
|
||||||
if _option_enabled(options, "shared") or _option_disabled(options, "static"):
|
if _option_enabled("shared") or _option_disabled("static"):
|
||||||
del _options["static"] # should result only into "-shared"
|
delattr(conan_options, "static") # should result only into "-shared"
|
||||||
if _option_enabled(options, "static") or _option_disabled(options, "shared"):
|
if _option_enabled("static") or _option_disabled("shared"):
|
||||||
del _options["shared"] # should result only into "-static"
|
delattr(conan_options, "shared") # should result only into "-static"
|
||||||
|
|
||||||
_options = {key: value for key, value in conan_options.items()}
|
_filter_overlapping_options()
|
||||||
_filter_overlapping_options(_options)
|
|
||||||
|
|
||||||
for option_name, option_value in _options.items():
|
for option_name, option_value in conan_options.items():
|
||||||
qt_option = self.convert_conan_option_to_qt_option(
|
qt_option = self.convert_conan_option_to_qt_option(
|
||||||
name=option_name, value=option_value
|
conan_options=conan_options, name=option_name, value=option_value
|
||||||
)
|
)
|
||||||
if not qt_option:
|
if not qt_option:
|
||||||
continue
|
continue
|
||||||
@ -324,7 +322,9 @@ class QtOptionParser:
|
|||||||
def get_cmake_args_for_configure(self, conan_options: Options) -> List[Optional[str]]:
|
def get_cmake_args_for_configure(self, conan_options: Options) -> List[Optional[str]]:
|
||||||
ret: List[Optional[str]] = []
|
ret: List[Optional[str]] = []
|
||||||
for option_name, option_value in conan_options.items():
|
for option_name, option_value in conan_options.items():
|
||||||
if option_name == "cmake_args_qtbase" and self.is_used_option(option_value):
|
if option_name == "cmake_args_qtbase" and self.is_used_option(
|
||||||
|
conan_options, option_value
|
||||||
|
):
|
||||||
ret = [ret for ret in option_value.strip(r" '\"").split()]
|
ret = [ret for ret in option_value.strip(r" '\"").split()]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ def _build_qtbase(conan_file: ConanFile):
|
|||||||
script = Path("configure.bat") if tools.os_info.is_windows else Path("configure")
|
script = Path("configure.bat") if tools.os_info.is_windows else Path("configure")
|
||||||
configure = Path(conan_file.build_folder).joinpath(script).resolve(strict=True)
|
configure = Path(conan_file.build_folder).joinpath(script).resolve(strict=True)
|
||||||
|
|
||||||
if conan_file.options.get_safe("icu", default="no"):
|
if conan_file.options.get_safe("icu", default=False):
|
||||||
# we need to tell Qt build system where to find the ICU
|
# we need to tell Qt build system where to find the ICU
|
||||||
add_cmake_prefix_path(conan_file, dep="icu")
|
add_cmake_prefix_path(conan_file, dep="icu")
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ class QtBase(ConanFile):
|
|||||||
# list of tuples, (package_name, fallback version)
|
# list of tuples, (package_name, fallback version)
|
||||||
optional_requirements = [("icu", "56.1")]
|
optional_requirements = [("icu", "56.1")]
|
||||||
for req_name, req_ver_fallback in optional_requirements:
|
for req_name, req_ver_fallback in optional_requirements:
|
||||||
if self.options.get_safe(req_name, default="no") == "yes":
|
if self.options.get_safe(req_name, default=False) == True:
|
||||||
# Note! If this conan package is being "conan export"ed outside Qt CI and the
|
# Note! If this conan package is being "conan export"ed outside Qt CI and the
|
||||||
# sw versions .ini file is not present then it will fall-back to default version
|
# sw versions .ini file is not present then it will fall-back to default version
|
||||||
ver = parse_sw_req(
|
ver = parse_sw_req(
|
||||||
@ -442,10 +442,9 @@ class QtBase(ConanFile):
|
|||||||
if self.settings.compiler == "gcc" and tools.Version(self.settings.compiler.version) < "8":
|
if self.settings.compiler == "gcc" and tools.Version(self.settings.compiler.version) < "8":
|
||||||
raise ConanInvalidConfiguration("Qt6 does not support GCC before 8")
|
raise ConanInvalidConfiguration("Qt6 does not support GCC before 8")
|
||||||
|
|
||||||
def _set_default_if_not_set(option_name: str, option_value: str) -> None:
|
def _set_default_if_not_set(option_name: str, option_value: bool) -> None:
|
||||||
# let it fail if option name does not exist, it means the recipe is not up to date
|
# let it fail if option name does not exist, it means the recipe is not up to date
|
||||||
value = getattr(self.options, option_name)
|
if self.options.get_safe(option_name) in [None, "None"]:
|
||||||
if not value or value == "None":
|
|
||||||
setattr(self.options, option_name, option_value)
|
setattr(self.options, option_name, option_value)
|
||||||
|
|
||||||
def _set_build_type(build_type: str) -> None:
|
def _set_build_type(build_type: str) -> None:
|
||||||
@ -459,8 +458,8 @@ class QtBase(ConanFile):
|
|||||||
raise QtConanError(msg)
|
raise QtConanError(msg)
|
||||||
self.settings.build_type = build_type
|
self.settings.build_type = build_type
|
||||||
|
|
||||||
def _check_mutually_exclusive_options(options: Dict[str, str]) -> None:
|
def _check_mutually_exclusive_options(options: Dict[str, bool]) -> None:
|
||||||
if list(options.values()).count("yes") > 1:
|
if list(options.values()).count(True) > 1:
|
||||||
raise QtConanError(
|
raise QtConanError(
|
||||||
"These Qt options are mutually exclusive: {0}"
|
"These Qt options are mutually exclusive: {0}"
|
||||||
". Choose only one of them and try again.".format(list(options.keys()))
|
". Choose only one of them and try again.".format(list(options.keys()))
|
||||||
@ -472,13 +471,13 @@ class QtBase(ConanFile):
|
|||||||
default_options.append("framework")
|
default_options.append("framework")
|
||||||
|
|
||||||
for item in default_options:
|
for item in default_options:
|
||||||
_set_default_if_not_set(item, "yes")
|
_set_default_if_not_set(item, True)
|
||||||
|
|
||||||
release = self.options.get_safe("release", default="no")
|
release = self.options.get_safe("release", default=False)
|
||||||
debug = self.options.get_safe("debug", default="no")
|
debug = self.options.get_safe("debug", default=False)
|
||||||
debug_and_release = self.options.get_safe("debug_and_release", default="no")
|
debug_and_release = self.options.get_safe("debug_and_release", default=False)
|
||||||
force_debug_info = self.options.get_safe("force_debug_info", default="no")
|
force_debug_info = self.options.get_safe("force_debug_info", default=False)
|
||||||
optimize_size = self.options.get_safe("optimize_size", default="no")
|
optimize_size = self.options.get_safe("optimize_size", default=False)
|
||||||
|
|
||||||
# these options are mutually exclusive options so do a sanity check
|
# these options are mutually exclusive options so do a sanity check
|
||||||
_check_mutually_exclusive_options(
|
_check_mutually_exclusive_options(
|
||||||
@ -486,27 +485,27 @@ class QtBase(ConanFile):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Prioritize Qt's configure options over Settings.build_type
|
# Prioritize Qt's configure options over Settings.build_type
|
||||||
if debug_and_release == "yes":
|
if debug_and_release == True:
|
||||||
# Qt build system will build both debug and release binaries
|
# Qt build system will build both debug and release binaries
|
||||||
if force_debug_info == "yes":
|
if force_debug_info == True:
|
||||||
_set_build_type("RelWithDebInfo")
|
_set_build_type("RelWithDebInfo")
|
||||||
else:
|
else:
|
||||||
_set_build_type("Release")
|
_set_build_type("Release")
|
||||||
elif release == "yes":
|
elif release == True:
|
||||||
_check_mutually_exclusive_options(
|
_check_mutually_exclusive_options(
|
||||||
{"force_debug_info": force_debug_info, "optimize_size": optimize_size}
|
{"force_debug_info": force_debug_info, "optimize_size": optimize_size}
|
||||||
)
|
)
|
||||||
if force_debug_info == "yes":
|
if force_debug_info == True:
|
||||||
_set_build_type("RelWithDebInfo")
|
_set_build_type("RelWithDebInfo")
|
||||||
elif optimize_size == "yes":
|
elif optimize_size == True:
|
||||||
_set_build_type("MinSizeRel")
|
_set_build_type("MinSizeRel")
|
||||||
else:
|
else:
|
||||||
_set_build_type("Release")
|
_set_build_type("Release")
|
||||||
elif debug == "yes":
|
elif debug == True:
|
||||||
_set_build_type("Debug")
|
_set_build_type("Debug")
|
||||||
else:
|
else:
|
||||||
# set default that mirror the configure(.bat) default values
|
# set default that mirror the configure(.bat) default values
|
||||||
self.options.release = "yes"
|
self.options.release = True
|
||||||
_set_build_type("Release")
|
_set_build_type("Release")
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user