Conan: Inherit recipe class from QtLeafModule for common functionality

The qt-conan-common package implements a base class for Qt leaf
module recipes. The build steps in leaf modules are mostly identical
so it makes sense to put those in the base class.

Dependencies are read by the base class from the 'dependencies.yaml'
which is the same file the CI system uses.

Task-number: QTBUG-94822
Change-Id: I73e7906e1b24ddad7fd808e30e22c5015eb9aa4a
Reviewed-by: Toni Saario <toni.saario@qt.io>
(cherry picked from commit 946b7dc4f9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Iikka Eklund 2021-06-28 11:31:11 +03:00 committed by Qt Cherry-pick Bot
parent d046eeaf11
commit e7dcdbc8f1
2 changed files with 17 additions and 96 deletions

View File

@ -1 +1,2 @@
set(QT_REPO_MODULE_VERSION "6.2.0") set(QT_REPO_MODULE_VERSION "6.2.0")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")

View File

@ -26,111 +26,31 @@
## ##
############################################################################# #############################################################################
from conans import ConanFile, tools, CMake from conans import ConanFile
import os import re
from pathlib import Path from pathlib import Path
class QtConanError(Exception): def _parse_qt_version_by_key(key: str) -> str:
pass 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 QtImageFormats(ConanFile): class QtImageFormats(ConanFile):
name = "qtimageformats" name = "qtimageformats"
version = "6.2.0" license = "LGPL-3.0, GPL-2.0+, Commercial Qt License Agreement"
license = "LGPL-3.0+, GPL-2.0+, Commercial Qt License Agreement"
author = "The Qt Company <https://www.qt.io/contact-us>" author = "The Qt Company <https://www.qt.io/contact-us>"
url = "https://code.qt.io/cgit/qt/qtimageformats.git" url = "https://code.qt.io/cgit/qt/qtimageformats.git"
description = "Additional Image Format plugins for Qt." description = "Additional Image Format plugins for Qt."
topics = ("qt", "qt6", "addon", "icns", "jp2", "mng", "tga", "tiff", "wbmb", "webp") topics = ("qt", "qt6", "addon", "icns", "jp2", "mng", "tga", "tiff", "wbmb", "webp")
settings = "os", "compiler", "build_type", "arch" settings = "os", "compiler", "arch", "build_type"
options = {"shared": [True, False, "default"], # for referencing the version number and prerelease tag and dependencies info
"qt6": "ANY"} # this is needed to model unique package_id for the Add-on build per used Qt6 version exports = ".cmake.conf", "dependencies.yaml"
default_options = {"shared": "default", # default: Use the value of the Qt build
"qt6": None}
exports_sources = "*", "!conan*.*" exports_sources = "*", "!conan*.*"
# use commit ID as the RREV (recipe revision) if this is exported from .git repository python_requires = f"qt-conan-common/{_get_qt_minor_version()}@qt/everywhere"
revision_mode = "scm" if Path(Path(__file__).parent.resolve() / ".git").exists() else "hash" python_requires_extend = "qt-conan-common.QtLeafModule"
def source(self):
# sources are installed next to recipe, no need to clone etc. sources here
pass
def _get_cmake_prefix_path(self):
# 'QTDIR' provided as env variable in profile file which is part of the Qt essential binary
# package(s). Installed under .conan/profiles
cmake_prefix_path = os.environ.get("QTDIR")
if not cmake_prefix_path:
raise QtConanError("'QTDIR' not defined! The 'QTDIR' needs to point to Qt installation directory.")
print(f"CMAKE_PREFIX_PATH for '{self.name}/{self.version}' build is: {cmake_prefix_path}")
return cmake_prefix_path
def _read_env(self, key):
value = os.environ.get(key)
if not value:
raise QtConanError(f"{self.settings.os} build specified but '{key}' was not defined?")
return value
def _get_qtcmake(self):
qt_install_path = self._get_cmake_prefix_path()
ext = ".bat" if tools.os_info.is_windows else ""
qtcmake = os.path.abspath(os.path.join(qt_install_path, "bin", "qt-cmake" + ext))
if not os.path.exists(qtcmake):
raise QtConanError(f"Unable to locate {qtcmake} from 'QTDIR': {qt_install_path}")
return qtcmake
def _get_cmake_tool(self):
cmake = CMake(self, cmake_program=self._get_qtcmake())
cmake.verbose = True
# Qt modules need to be 'installed'.
# We need to direct the 'make install' to some directory under Conan cache,
# place it under the current build directory which is also under the Conan cache.
# Note, the actual 'make install' is called in "package()".
install_dir = os.path.join(os.getcwd(), "_install_tmp")
cmake.definitions["CMAKE_INSTALL_PREFIX"] = install_dir
# Use the value of the Qt build
if self.options.shared.value == "default":
del cmake.definitions["BUILD_SHARED_LIBS"]
cmake_toolchain_file = os.environ.get("CMAKE_TOOLCHAIN_FILE")
if cmake_toolchain_file:
cmake.definitions["CMAKE_TOOLCHAIN_FILE"] = cmake_toolchain_file
if self.settings.os == "Android":
cmake.definitions["ANDROID_SDK_ROOT"] = self._read_env('ANDROID_SDK_ROOT')
cmake.definitions["ANDROID_NDK_ROOT"] = self._read_env('ANDROID_NDK_ROOT')
if self.settings.os == "iOS":
# Instead of Conan's auto-added 'Darwin', explicitly pass 'iOS'.
cmake.definitions["CMAKE_SYSTEM_NAME"] = "iOS"
# Remove the explicit sysroot, let CMake detect the sysroots, to ensure
# that multi-arch builds work.
del cmake.definitions["CMAKE_OSX_SYSROOT"]
# Remove the conan provided architecture, instead rely on the architectures set
# by the Qt toolchain file, which with official Qt packages most likely means
# multi-arch iOS.
del cmake.definitions["CMAKE_OSX_ARCHITECTURES"]
return cmake
def build(self):
cmake = self._get_cmake_tool()
self.run('%s "%s" %s' % (self._get_qtcmake(), self.source_folder, cmake.command_line))
self.run('cmake --build . %s' % cmake.build_config)
def package(self):
install_dir = os.path.join(os.getcwd(), "_install_tmp") # see 'CMAKE_INSTALL_PREFIX' above
self.run('cmake --build . --target install')
self.copy("*", src=install_dir, dst=".")
def package_info(self):
self.cpp_info.libs = ["Qt6ImageFormats"] # used for the actual library filename, Ordered list with the library names
def deploy(self):
self.copy("*") # copy from current package
self.copy_deps("*") # copy from dependencies