diff options
Diffstat (limited to 'conanfile.py')
-rw-r--r-- | conanfile.py | 297 |
1 files changed, 0 insertions, 297 deletions
diff --git a/conanfile.py b/conanfile.py deleted file mode 100644 index 2a9f50f8b4..0000000000 --- a/conanfile.py +++ /dev/null @@ -1,297 +0,0 @@ -# Copyright (C) 2021 The Qt Company Ltd. -# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -from conans import ConanFile, tools -from conans.errors import ConanInvalidConfiguration -import os -import re -import shutil -from functools import lru_cache -from pathlib import Path -from typing import Dict - - -class QtConanError(Exception): - pass - - -def add_cmake_prefix_path(conan_file: ConanFile, dep: str) -> None: - if dep not in conan_file.deps_cpp_info.deps: - raise QtConanError("Unable to find dependency: {0}".format(dep)) - dep_cpp_info = conan_file.deps_cpp_info[dep] - cmake_args_str = str(conan_file.options.get_safe("cmake_args_qtbase", default="")) - formatted_cmake_args_str = conan_file._shared.append_cmake_arg( - cmake_args_str, "CMAKE_PREFIX_PATH", dep_cpp_info.rootpath - ) - print("Adjusted cmake args for qtbase build: {0}".format(formatted_cmake_args_str)) - setattr(conan_file.options, "cmake_args_qtbase", formatted_cmake_args_str) - - -def _build_qtbase(conan_file: ConanFile): - # we call the Qt's configure(.bat) directly - script = Path("configure.bat") if tools.os_info.is_windows else Path("configure") - configure = Path(conan_file.build_folder).joinpath(script).resolve(strict=True) - - if conan_file.options.get_safe("icu", default=False): - # we need to tell Qt build system where to find the ICU - add_cmake_prefix_path(conan_file, dep="icu") - - # convert the Conan options to Qt configure(.bat) arguments - parser = conan_file._qt_option_parser - qt_configure_options = parser.convert_conan_options_to_qt_options(conan_file.options) - cmd = " ".join( - [str(configure), " ".join(qt_configure_options), "-prefix", conan_file.package_folder] - ) - cmake_args = parser.get_cmake_args_for_configure(conan_file.options) - if cmake_args: - cmd += " -- {0}".format(" ".join(cmake_args)) - conan_file.output.info("Calling: {0}".format(cmd)) - conan_file.run(cmd) - - cmd = " ".join(["cmake", "--build", ".", "--parallel"]) - conan_file.output.info("Calling: {0}".format(cmd)) - conan_file.run(cmd) - - -@lru_cache(maxsize=8) -def _parse_qt_version_by_key(key: str) -> str: - with open(Path(__file__).parent.resolve() / ".cmake.conf") as f: - m = re.search(fr'{key} .*"(.*)"', f.read()) - return m.group(1) if m else "" - - -def _get_qt_minor_version() -> str: - return ".".join(_parse_qt_version_by_key("QT_REPO_MODULE_VERSION").split(".")[:2]) - - -class QtBase(ConanFile): - name = "qtbase" - license = "LGPL-3.0, GPL-2.0+, Commercial Qt License Agreement" - author = "The Qt Company <https://www.qt.io/contact-us>" - url = "https://code.qt.io/cgit/qt/qtbase.git" - description = "Qt6 core framework libraries and tools." - topics = ("qt", "qt6") - settings = "os", "compiler", "arch", "build_type" - _qt_option_parser = None - options = None - default_options = None - exports_sources = "*", "!conan*.*" - # use commit ID as the RREV (recipe revision) - revision_mode = "scm" - python_requires = "qt-conan-common/{0}@qt/everywhere".format(_get_qt_minor_version()) - short_paths = True - _shared = None - - def init(self): - self._shared = self.python_requires["qt-conan-common"].module - self._qt_option_parser = self._shared.QtOptionParser(Path(__file__).parent.resolve()) - self.options = self._qt_option_parser.get_qt_conan_options() - self.default_options = self._qt_option_parser.get_default_qt_conan_options() - - def set_version(self): - # Executed during "conan export" i.e. in source tree - _ver = _parse_qt_version_by_key("QT_REPO_MODULE_VERSION") - _prerelease = _parse_qt_version_by_key("QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT") - self.version = _ver + "-" + _prerelease if _prerelease else _ver - - def export(self): - self.copy("configure_options.json") - self.copy("configure_features.txt") - self.copy(".cmake.conf") - conf = self._shared.qt_sw_versions_config_folder() / self._shared.qt_sw_versions_config_name() - if not conf.exists(): - # If using "conan export" outside Qt CI provisioned machines - print("Warning: Couldn't find '{0}'. 3rd party dependencies skipped.".format(conf)) - else: - shutil.copy2(conf, self.export_folder) - - def requirements(self): - # list of tuples, (package_name, fallback version) - optional_requirements = [("icu", "56.1")] - for req_name, req_ver_fallback in optional_requirements: - 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 - # sw versions .ini file is not present then it will fall-back to default version - ver = self._shared.parse_qt_sw_pkg_dependency( - config_folder=Path(self.recipe_folder), - package_name=req_name, - target_os=str(self.settings.os), - ) - if not ver: - print( - "Warning: Using fallback version '{0}' for: {1}".format( - req_name, req_ver_fallback - ) - ) - ver = req_ver_fallback - requirement = "{0}/{1}@qt/everywhere".format(req_name, ver) - print("Setting 3rd party package requirement: {0}".format(requirement)) - self.requires(requirement) - - def _resolve_qt_host_path(self) -> str: - # When cross-building the user needs to pass 'qt_host_path' which is transformed to - # QT_HOST_PATH later on. Resolve the exact path. - qt_host_path = self.options.get_safe("qt_host_path") - if qt_host_path is None: - raise QtConanError("Expected 'qt_host_path' option in cross-build context") - return str(Path(os.path.expandvars(str(qt_host_path))).expanduser().resolve(strict=True)) - - def configure(self): - if self.settings.compiler == "gcc" and tools.Version(self.settings.compiler.version) < "8": - raise ConanInvalidConfiguration("Qt6 does not support GCC before 8") - - 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 - if self.options.get_safe(option_name) in [None, "None"]: - setattr(self.options, option_name, option_value) - - def _set_build_type(build_type: str) -> None: - if self.settings.build_type != build_type: - msg = ( - "The build_type '{0}' changed to '{1}'. Please check your Settings and " - "Options. The used Qt options enforce '{2}' as a build_type. ".format( - self.settings.build_type, build_type, build_type - ) - ) - raise QtConanError(msg) - self.settings.build_type = build_type - - def _check_mutually_exclusive_options(options: Dict[str, bool]) -> None: - if list(options.values()).count(True) > 1: - raise QtConanError( - "These Qt options are mutually exclusive: {0}" - ". Choose only one of them and try again.".format(list(options.keys())) - ) - - default_options = ["shared", "gui", "widgets", "accessibility", "system_proxies", "ico"] - - if self.settings.os == "Macos": - default_options.append("framework") - - for item in default_options: - _set_default_if_not_set(item, True) - - release = self.options.get_safe("release", default=False) - debug = self.options.get_safe("debug", default=False) - debug_and_release = self.options.get_safe("debug_and_release", default=False) - force_debug_info = self.options.get_safe("force_debug_info", default=False) - optimize_size = self.options.get_safe("optimize_size", default=False) - - # these options are mutually exclusive options so do a sanity check - _check_mutually_exclusive_options( - {"release": release, "debug": debug, "debug_and_release": debug_and_release} - ) - - # Prioritize Qt's configure options over Settings.build_type - if debug_and_release == True: - # Qt build system will build both debug and release binaries - if force_debug_info == True: - _set_build_type("RelWithDebInfo") - else: - _set_build_type("Release") - elif release == True: - _check_mutually_exclusive_options( - {"force_debug_info": force_debug_info, "optimize_size": optimize_size} - ) - if force_debug_info == True: - _set_build_type("RelWithDebInfo") - elif optimize_size == True: - _set_build_type("MinSizeRel") - else: - _set_build_type("Release") - elif debug == True: - _set_build_type("Debug") - else: - # As a fallback set the build type for Qt configure based on the 'build_type' - # defined in the conan build settings - build_type = self.settings.get_safe("build_type") - if build_type in [None, "None"]: - # set default that mirror the configure(.bat) default values - self.options.release = True - self.settings.build_type = "Release" - elif build_type == "Release": - self.options.release = True - elif build_type == "Debug": - self.options.debug = True - elif build_type == "RelWithDebInfo": - self.options.release = True - self.options.force_debug_info = True - elif build_type == "MinSizeRel": - self.options.release = True - self.options.optimize_size = True - else: - raise QtConanError("Unknown build_type: {0}".format(self.settings.build_type)) - - if tools.cross_building(conanfile=self): - # pass the QT_HOST_PATH as CMake argument so the user does not need to export it - cmake_args_qtbase = str(self.options.get_safe("cmake_args_qtbase", default="")) - formatted_cmake_args_qtbase = self._shared.append_cmake_arg( - cmake_args_qtbase, "QT_HOST_PATH", self._resolve_qt_host_path() - ) - setattr(self.options, "cmake_args_qtbase", formatted_cmake_args_qtbase) - - if self.settings.os == "Android": - if self.options.get_safe("android_sdk_version") == None: - cmake_args_qtbase = str(self.options.get_safe("cmake_args_qtbase")) - sdk_ver = self._shared.parse_android_sdk_version(cmake_args_qtbase) - if sdk_ver: - print("'android_sdk_version' not given. Deduced version: {0}".format(sdk_ver)) - self.options.android_sdk_version = sdk_ver - else: - # TODO, for now we have no clean means to query the Android SDK version from - # Qt build system so we just exclude the "android_sdk" from the package_id. - print("Can't deduce 'android_sdk_version'. Excluding it from 'package_id'") - delattr(self.info.options, "android_sdk_version") - if self.options.get_safe("android_ndk_version") == None: - ndk_ver = str(self.options.get_safe("android_ndk")) - ndk_ver = self._shared.parse_android_ndk_version(Path(ndk_ver, strict=True)) - print("'android_ndk_version' not given. Deduced version: {0}".format(ndk_ver)) - self.options.android_ndk_version = ndk_ver - - def build(self): - self._shared.build_env_wrap(self, _build_qtbase) - - def package(self): - self._shared.call_install(self) - - def package_info(self): - self._shared.package_info(self) - if tools.cross_building(conanfile=self): - self.env_info.QT_HOST_PATH.append(self._resolve_qt_host_path()) - - def package_id(self): - # https://docs.conan.io/en/latest/creating_packages/define_abi_compatibility.html - - # The package_revision_mode() is too strict for Qt CI. This mode includes artifacts - # checksum in package_id which is problematic in Qt CI re-runs (re-run flaky - # build) which contain different build timestamps (cmake) which end up in library - # files -> different package_id. - self.info.requires.recipe_revision_mode() - - # Enable 'qt-conan-common' updates on client side with $conan install .. --update - self.info.python_requires.recipe_revision_mode() - - # Remove those configure(.bat) options which should not affect package_id. - # These point to local file system paths and in order to re-use pre-built - # binaries (by Qt CI) by others these should not affect the 'package_id' - # as those probably differ on each machine - rm_list = [ - "sdk", - "qpa", - "translationsdir", - "headersclean", - "qt_host_path", - "android_sdk", - "android_ndk", - ] - for item in rm_list: - if item in self.info.options: - delattr(self.info.options, item) - # filter also those cmake options that should not end up in the package_id - if hasattr(self.info.options, "cmake_args_qtbase"): - _filter = self._shared.filter_cmake_args_for_package_id - self.info.options.cmake_args_qtbase = _filter(self.info.options.cmake_args_qtbase) - - def deploy(self): - self.copy("*") # copy from current package - self.copy_deps("*") # copy from dependencies |