COIN: Make independent from internal scripts

The coin scripts may no longer access the repository with the internal
build scripts. Move (adapted versions of) the needed scripts into the
repository itself.

Change-Id: I0515b8d66bd917e32eaabf64a1c76cc852fbe5df
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Eike Ziller
2024-10-17 11:57:44 +02:00
parent e281855dfa
commit cf1f4b050f
7 changed files with 423 additions and 75 deletions

View File

@@ -44,7 +44,7 @@ instructions:
userMessageOnFailure: "Failed to extract LLVM package, check logs."
- type: ExecuteCommand
command: >-
python3 -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/build.py
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/build.py
--build-type {{.Env.QTC_BUILD_TYPE}}
--src {{.AgentWorkingDir}}/qt-creator/qt-creator
--build {{.AgentWorkingDir}}/qt-creator/qt-creator_build
@@ -59,11 +59,9 @@ instructions:
maxTimeInSeconds: 36000
maxTimeBetweenOutput: 3600
userMessageOnFailure: "Failed to run build.py, check logs."
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}/build/tqtc-qtsdk/packaging_tools"
- type: ExecuteCommand
command: >-
python3 -m pipenv run python -u bld_sdktool.py
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/build_sdktool.py
--qt-url {{.Env.QTC_SDKTOOL_QT_BASE_URL}}{{.Env.QTC_SDKTOOL_QT_EXT}}
--qt-build {{.AgentWorkingDir}}/build/sdktool/qt
--src {{.AgentWorkingDir}}/qt-creator/qt-creator/src/tools/sdktool
@@ -97,7 +95,7 @@ instructions:
userMessageOnFailure: "Failed to extract LLVM package, check logs."
- type: ExecuteCommand
command: >-
python3 -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/build.py
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/build.py
--build-type {{.Env.QTC_BUILD_TYPE}}
--src {{.AgentWorkingDir}}/qt-creator/qt-creator
--build {{.AgentWorkingDir}}/qt-creator/qt-creator_build
@@ -112,14 +110,12 @@ instructions:
maxTimeInSeconds: 36000
maxTimeBetweenOutput: 3600
userMessageOnFailure: "Failed to run build.py, check logs."
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}/build/tqtc-qtsdk/packaging_tools"
- type: EnvironmentVariable
variableName: MACOSX_DEPLOYMENT_TARGET
variableValue: "{{.Env.SDKTOOL_MACOSX_DEPLOYMENT_TARGET}}"
- type: ExecuteCommand
command: >-
python3 -m pipenv run python -u bld_sdktool.py
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/build_sdktool.py
--qt-url {{.Env.QTC_SDKTOOL_QT_BASE_URL}}{{.Env.QTC_SDKTOOL_QT_EXT}}
--qt-build {{.AgentWorkingDir}}/build/sdktool/qt
--src {{.AgentWorkingDir}}/qt-creator/qt-creator/src/tools/sdktool
@@ -235,7 +231,7 @@ instructions:
userMessageOnFailure: "Failed to extract LLVM package, check logs."
- type: ExecuteCommand
command: >-
python -u {{.AgentWorkingDir}}\qt-creator\qt-creator\scripts\build.py
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}\qt-creator\qt-creator\scripts\build.py
--build-type {{.Env.QTC_BUILD_TYPE}}
--src {{.AgentWorkingDir}}\qt-creator\qt-creator
--build {{.AgentWorkingDir}}\qt-creator\qt-creator_build
@@ -254,11 +250,9 @@ instructions:
maxTimeInSeconds: 36000
maxTimeBetweenOutput: 3600
userMessageOnFailure: "Failed to run build.py, check logs."
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}\\build\\tqtc-qtsdk\\packaging_tools"
- type: ExecuteCommand
command: >-
python -m pipenv run python -u bld_sdktool.py
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}\qt-creator\qt-creator\scripts\build_sdktool.py
--qt-url {{.Env.QTC_SDKTOOL_QT_BASE_URL}}{{.Env.QTC_SDKTOOL_QT_EXT}}
--qt-build {{.AgentWorkingDir}}\build\sdktool\qt
--src {{.AgentWorkingDir}}\qt-creator\qt-creator\src\tools\sdktool

View File

@@ -40,6 +40,9 @@ instructions:
- type: EnvironmentVariable
variableName: QTC_LLVM_POSTFIX
variableValue: "-windows-vs2019_64.7z"
- type: EnvironmentVariable
variableName: PYTHON_EXECUTABLE
variableValue: "python"
enable_if:
condition: property
property: target.os
@@ -61,6 +64,17 @@ instructions:
- type: EnvironmentVariable
variableName: QTC_ICU_URL
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/icu/prebuilt/56.1/icu-linux-g++-Rhel7.2-x64.7z"
- type: EnvironmentVariable
variableName: PYTHON_EXECUTABLE
variableValue: "python3"
# RHEL 8.10 comes with Python 3.6, we need explicitly python3.11
- type: EnvironmentVariable
variableName: PYTHON_EXECUTABLE
variableValue: "python3.11"
enable_if:
condition: property
property: host.osVersion
contains_value: "RHEL"
enable_if:
condition: and
conditions:
@@ -87,6 +101,9 @@ instructions:
- type: EnvironmentVariable
variableName: QTC_ICU_URL
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/icu/prebuilt/73.2/icu-linux-g++-Debian11.6-aarch64.7z"
- type: EnvironmentVariable
variableName: PYTHON_EXECUTABLE
variableValue: "python3"
enable_if:
condition: and
conditions:
@@ -107,6 +124,9 @@ instructions:
- type: EnvironmentVariable
variableName: QTC_LLVM_POSTFIX
variableValue: "-macos-universal.7z"
- type: EnvironmentVariable
variableName: PYTHON_EXECUTABLE
variableValue: "python3"
enable_if:
condition: property
property: target.os

View File

@@ -15,66 +15,55 @@ instructions:
- type: MakeDirectory
directory: "{{.BuildDir}}"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: ExecuteCommand
command: ["git", "clone", "--jobs={{.NumCPU}}", "--depth=50", "-b", "production", "git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qtsdk/tqtc-qtsdk","tqtc-qtsdk"]
maxTimeInSeconds: 600
maxTimeBetweenOutput: 600
userMessageOnFailure: "Failed to install tqtc-qtsdk, check logs"
directory: "{{.AgentWorkingDir}}/qt-creator/qt-creator/scripts"
- type: Group
instructions:
- type: ExecuteCommand
command: python tqtc-qtsdk/jenkins-templates/jenkins/scripts/pkg_bootstrap.py
maxTimeInSeconds: 36000
maxTimeBetweenOutput: 3600
userMessageOnFailure: "pkg_bootstrap.py failed"
enable_if:
condition: and
conditions:
- condition: property
property: host.os
equals_value: Windows
- type: Group
instructions:
- type: ExecuteCommand
command: python3 tqtc-qtsdk/jenkins-templates/jenkins/scripts/pkg_bootstrap.py
maxTimeInSeconds: 36000
maxTimeBetweenOutput: 3600
userMessageOnFailure: "pkg_bootstrap.py failed"
enable_if:
condition: and
conditions:
- condition: property
property: host.os
not_equals_value: Windows
- type: ChangeDirectory
directory: "{{.BuildDir}}/tqtc-qtsdk/packaging_tools"
- type: ExecuteCommand
command: "python3 -m pipenv run python -u install_qt.py --qt-path {{.BuildDir}}/qt_install_dir --base-url {{.Env.QTC_QT_BASE_URL}} --base-url-postfix={{.Env.QTC_QT_POSTFIX}} --icu7z {{.Env.QTC_ICU_URL}} {{.Env.QTC_QT_MODULES}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 3600
maxTimeBetweenOutput: 360
userMessageOnFailure: "Failed to install qt, check logs."
- type: ExecuteCommand
command: >-
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/install_qt.py
--qt-path {{.BuildDir}}/qt_install_dir
--base-url {{.Env.QTC_QT_BASE_URL}}
--base-url-postfix={{.Env.QTC_QT_POSTFIX}}
--icu7z {{.Env.QTC_ICU_URL}}
{{.Env.QTC_QT_MODULES}}
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 3600
maxTimeBetweenOutput: 360
userMessageOnFailure: "Failed to install qt, check logs."
enable_if:
condition: property
property: host.os
equals_value: Linux
- type: ExecuteCommand
command: "python3 -m pipenv run python -u install_qt.py --qt-path {{.BuildDir}}/qt_install_dir --base-url {{.Env.QTC_QT_BASE_URL}} --base-url-postfix={{.Env.QTC_QT_POSTFIX}} {{.Env.QTC_QT_MODULES}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 3600
maxTimeBetweenOutput: 360
userMessageOnFailure: "Failed to install qt, check logs."
- type: Group
instructions:
- type: ExecuteCommand
command: >-
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}/qt-creator/qt-creator/scripts/install_qt.py
--qt-path {{.BuildDir}}/qt_install_dir
--base-url {{.Env.QTC_QT_BASE_URL}}
--base-url-postfix={{.Env.QTC_QT_POSTFIX}}
{{.Env.QTC_QT_MODULES}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 3600
maxTimeBetweenOutput: 360
userMessageOnFailure: "Failed to install qt, check logs."
enable_if:
condition: property
property: host.os
equals_value: MacOS
- type: ExecuteCommand
command: "python -m pipenv run python -u install_qt.py --qt-path {{.BuildDir}}/qt_install_dir --base-url {{.Env.QTC_QT_BASE_URL}} --base-url-postfix={{.Env.QTC_QT_POSTFIX}} --opengl32sw7z https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/llvmpipe/windows/opengl32sw-64.7z --d3dcompiler7z https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/d3dcompiler/msvc2013/d3dcompiler_47-x64.7z --openssl7z https://ci-files02-hki.ci.qt.io/packages/jenkins/openssl/openssl_1.1.1d_prebuild_x64.7z {{.Env.QTC_QT_MODULES}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 3600
maxTimeBetweenOutput: 360
userMessageOnFailure: "Failed to install qt, check logs."
- type: Group
instructions:
- type: ExecuteCommand
command: >-
{{.Env.PYTHON_EXECUTABLE}} -u {{.AgentWorkingDir}}\qt-creator\qt-creator\scripts\install_qt.py
--qt-path {{.BuildDir}}/qt_install_dir
--base-url {{.Env.QTC_QT_BASE_URL}}
--base-url-postfix={{.Env.QTC_QT_POSTFIX}}
{{.Env.QTC_QT_MODULES}}
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 3600
maxTimeBetweenOutput: 360
userMessageOnFailure: "Failed to install qt, check logs."
enable_if:
condition: and
conditions:

View File

@@ -10,20 +10,13 @@ import collections
import os
import shlex
import shutil
import sys
import common
def existing_path(path):
return path if os.path.exists(path) else None
def default_python3():
path_system = os.path.join('/usr', 'bin') if not common.is_windows_platform() else None
path = os.environ.get('PYTHON3_PATH') or path_system
postfix = '.exe' if common.is_windows_platform() else ''
return (path if not path
else (existing_path(os.path.join(path, 'python3' + postfix)) or
existing_path(os.path.join(path, 'python' + postfix))))
def get_arguments():
parser = argparse.ArgumentParser(description='Build Qt Creator for packaging')
parser.add_argument('--src', help='path to sources', required=True)
@@ -52,7 +45,7 @@ def get_arguments():
help='Path to python libraries for use by cdbextension (Windows)')
parser.add_argument('--python3', help='File path to python3 executable for generating translations',
default=default_python3())
default=sys.executable)
parser.add_argument('--no-qtcreator',
help='Skip Qt Creator build (only build separate tools)',
@@ -324,7 +317,7 @@ def package_qtcreator(args, paths):
app],
signed_install_path)
if not args.no_dmg:
common.check_print_call(['python', '-u',
common.check_print_call([args.python3, '-u',
os.path.join(paths.src, 'scripts', 'makedmg.py'),
'qt-creator' + args.zip_infix + '.dmg',
'Qt Creator',

193
scripts/build_sdktool.py Executable file
View File

@@ -0,0 +1,193 @@
#!/usr/bin/env python3
# Copyright (C) 2024 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from __future__ import annotations
import argparse
from itertools import islice
import os
from pathlib import Path
from typing import NamedTuple
from common import (is_linux_platform, is_mac_platform, is_windows_platform,
download_and_extract, check_print_call)
class BuildParams(NamedTuple):
src_path: Path
build_path: Path
target_path: Path
make_command: str
universal: bool = False
platform: str | None = None
def qt_static_configure_options() -> list[str]:
return ['-release', '-opensource', '-confirm-license', '-accessibility',
'-no-gui',
'-no-openssl',
'-no-feature-sql',
'-qt-zlib',
'-nomake', 'examples',
'-nomake', 'tests',
'-static'] + qt_static_platform_configure_options()
def qt_static_platform_configure_options() -> list[str]:
if is_windows_platform():
return ['-static-runtime', '-no-icu']
if is_linux_platform():
return ['-no-icu', '-no-glib', '-qt-zlib', '-qt-pcre', '-qt-doubleconversion']
return []
def get_qt_src_path(qt_build_base: Path) -> Path:
return qt_build_base / 'src'
def get_qt_build_path(qt_build_base: Path) -> Path:
return qt_build_base / 'build'
def get_qt_install_path(qt_build_base: Path) -> Path:
return qt_build_base / 'install'
def configure_qt(params: BuildParams, src: Path, build: Path, install: Path) -> None:
build.mkdir(parents=True, exist_ok=True)
configure = src / "configure"
cmd = [str(configure), "-prefix", str(install)] + qt_static_configure_options()
if params.platform:
cmd.extend(['-platform', params.platform])
if params.universal:
cmd.extend(['--', '-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64'])
check_print_call(cmd, cwd=build)
def build_qt(params: BuildParams, build: Path) -> None:
check_print_call([params.make_command], cwd=build)
def install_qt(params: BuildParams, build: Path) -> None:
check_print_call([params.make_command, 'install'], cwd=build)
def build_sdktool_impl(params: BuildParams, qt_install_path: Path) -> None:
params.build_path.mkdir(parents=True, exist_ok=True)
cmake_args = [
'cmake', '-DCMAKE_PREFIX_PATH=' + str(qt_install_path), '-DCMAKE_BUILD_TYPE=Release'
]
# force MSVC on Windows, because it looks for GCC in the PATH first,
# even if MSVC is first mentioned in the PATH...
# TODO would be nicer if we only did this if cl.exe is indeed first in the PATH
if is_windows_platform():
cmake_args += ['-DCMAKE_C_COMPILER=cl', '-DCMAKE_CXX_COMPILER=cl']
cmake_args += ['-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded']
if params.universal:
cmake_args += ['-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64']
cmd = cmake_args + ['-G', 'Ninja', str(params.src_path)]
check_print_call(cmd, cwd=params.build_path)
check_print_call(['cmake', '--build', '.'], cwd=params.build_path)
cmd = ['cmake', '--install', '.', '--prefix', str(params.target_path)]
check_print_call(cmd, cwd=params.build_path)
def sign_sdktool(params: BuildParams,
environment: dict[str, str]) -> None:
signing_identity = environment.get('SIGNING_IDENTITY')
if not is_mac_platform() or not signing_identity:
return
check_print_call(['codesign', '-o', 'runtime', '--force', '-s', signing_identity,
'-v', 'sdktool'],
cwd=params.target_path,
env=environment)
def get_single_subdir(path: Path):
entries = list(islice(path.iterdir(), 2))
if len(entries) == 1:
return path / entries[0]
return path
def build_sdktool(
qt_src_url: str,
qt_build_base: Path,
sdktool_src_path: Path,
sdktool_build_path: Path,
sdktool_target_path: Path,
make_command: str,
universal: bool = False,
platform: str | None = None,
environment: dict[str, str] | None = None
) -> None:
if not environment:
environment = os.environ.copy()
params = BuildParams(
src_path=sdktool_src_path,
build_path=sdktool_build_path,
target_path=sdktool_target_path,
make_command=make_command,
platform=platform,
universal=universal
)
qt_src = get_qt_src_path(qt_build_base)
qt_build = get_qt_build_path(qt_build_base)
qt_install = get_qt_install_path(qt_build_base)
download_and_extract([qt_src_url], qt_src, qt_build_base)
qt_src = get_single_subdir(qt_src)
configure_qt(params, qt_src, qt_build, qt_install)
build_qt(params, qt_build)
install_qt(params, qt_build)
build_sdktool_impl(params, qt_install)
sign_sdktool(params, environment)
def zip_sdktool(
sdktool_target_path: Path, out_7zip: Path
) -> None:
glob = "*.exe" if is_windows_platform() else "*"
check_print_call(
cmd=["7z", "a", str(out_7zip), glob],
cwd=sdktool_target_path
)
def get_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(description='Build sdktool')
parser.add_argument('--qt-url', help='URL to Qt sources', required=True)
parser.add_argument(
'--qt-build', help='Path that is used for building Qt', required=True, type=Path
)
parser.add_argument('--src', help='Path to sdktool sources', required=True, type=Path)
parser.add_argument(
'--build', help='Path that is used for building sdktool', required=True, type=Path
)
parser.add_argument(
'--install', help='Path that is used for installing sdktool', required=True, type=Path
)
parser.add_argument('--make-command', help='Make command to use for Qt', required=True)
parser.add_argument('--platform', help='Platform argument for configuring Qt',
required=False)
parser.add_argument('--universal', help='Build universal binaries on macOS',
action='store_true', default=False, required=False)
return parser.parse_args()
def main() -> None:
args = get_arguments()
build_sdktool(
qt_src_url=args.qt_url,
qt_build_base=args.qt_build,
sdktool_src_path=args.src,
sdktool_build_path=args.build,
sdktool_target_path=args.install,
make_command=args.make_command,
platform=args.platform
)
if __name__ == '__main__':
main()

View File

@@ -1,12 +1,17 @@
# Copyright (C) 2016 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from __future__ import annotations
import argparse
import asyncio
import os
import locale
from pathlib import Path
import shutil
import subprocess
import sys
from urllib.parse import urlparse
import urllib.request
encoding = locale.getdefaultlocale()[1]
if not encoding:
@@ -27,13 +32,13 @@ def to_posix_path(path):
return path.replace('\\', '/')
return path
def check_print_call(command, workdir=None, env=None):
def check_print_call(command, cwd=None, env=None):
print('------------------------------------------')
print('COMMAND:')
print(' '.join(['"' + c.replace('"', '\\"') + '"' for c in command]))
print('PWD: "' + (workdir if workdir else os.getcwd()) + '"')
print('PWD: "' + (str(cwd) if cwd else os.getcwd()) + '"')
print('------------------------------------------')
subprocess.check_call(command, cwd=workdir, env=env)
subprocess.check_call(command, cwd=cwd, shell=is_windows_platform(), env=env)
def get_git_SHA(path):
@@ -105,6 +110,57 @@ def copytree(src, dst, symlinks=False, ignore=None):
if errors:
raise shutil.Error(errors)
def extract_file(archive: Path, target: Path) -> None:
cmd_args = []
if archive.suffix == '.tar':
cmd_args = ['tar', '-xf', str(archive)]
elif archive.suffixes[-2:] == ['.tar', '.gz'] or archive.suffix == '.tgz':
cmd_args = ['tar', '-xzf', str(archive)]
elif archive.suffixes[-2:] == ['.tar', '.xz']:
cmd_args = ['tar', '-xf', str(archive)]
elif archive.suffixes[-2:] == ['.tar', '.bz2'] or archive.suffix == '.tbz':
cmd_args = ['tar', '-xjf', str(archive)]
elif archive.suffix in ('.7z', '.zip', '.gz', '.xz', '.bz2', '.qbsp'):
cmd_args = ['7z', 'x', str(archive)]
else:
raise(
"Extract fail: %s. Not an archive or appropriate extractor was not found", str(archive)
)
return
target.mkdir(parents=True, exist_ok=True)
subprocess.check_call(cmd_args, cwd=target)
async def download(url: str, target: Path) -> None:
print('- Starting download {} -> {}'.format(url, str(target)))
# Since urlretrieve does blocking I/O it would prevent parallel downloads.
# Run in default thread pool.
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, urllib.request.urlretrieve, url, str(target))
print('+ finished downloading {}'.format(str(target)))
def download_and_extract(urls: list[str], target: Path, temp: Path) -> None:
temp.mkdir(parents=True, exist_ok=True)
target_files = []
# TODO make this work with file URLs, which then aren't downloaded
# but just extracted
async def impl():
tasks : list[asyncio.Task] = []
for url in urls:
u = urlparse(url)
filename = Path(u.path).name
target_file = temp / filename
target_files.append(target_file)
tasks.append(asyncio.create_task(download(url, target_file)))
for task in tasks:
await task
asyncio.run(impl())
for file in target_files:
extract_file(file, target)
def get_qt_install_info(qmake_bin):
output = subprocess.check_output([qmake_bin, '-query'])
decoded_output = output.decode(encoding) if encoding else output

103
scripts/install_qt.py Executable file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# Copyright (C) 2024 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from __future__ import annotations
import argparse
from common import download_and_extract
from pathlib import Path
import subprocess
import sys
from tempfile import TemporaryDirectory
from typing import Optional
def get_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(description='Install Qt from individual module archives')
parser.add_argument('--qt-path', help='path to Qt', type=Path, required=True)
parser.add_argument('--qt-module', help='Qt module package url (.7z) needed for building',
action='append', dest='qt_modules', default=[])
parser.add_argument('--base-url', help='Base URL for given module_name(s)')
parser.add_argument(
'module_name',
help='Name of Qt module to install, based on --base-url and --base-url-postfix',
nargs='*'
)
parser.add_argument(
'--base-url-postfix',
help='Postfix to add to URLs constructed from --base-url and given module_name(s)',
default=''
)
# Linux
parser.add_argument('--icu7z', help='a file or url where to get ICU libs as 7z')
args = parser.parse_args(sys.argv[1:])
return args
def patch_qt(qt_path: Path) -> None:
print("##### patch Qt #####")
qmake_binary = qt_path / 'bin' / 'qmake'
# write qt.conf
with (qt_path / 'bin' / 'qt.conf').open('w', encoding='utf-8') as qt_conf_file:
qt_conf_file.write('[Paths]\n')
qt_conf_file.write('Prefix=..\n')
subprocess.check_call([str(qmake_binary), '-query'], cwd=qt_path)
def install_qt(
qt_path: Path,
qt_modules: list[str],
icu_url: Optional[str] = None
) -> None:
"""
Install Qt to directory qt_path with the specified module and library packages.
Args:
qt_path: File system path to Qt (target install directory)
qt_modules: List of Qt module package URLs (.7z)
icu_url: Local or remote URI to Linux ICU libraries (.7z)
temp_path: Temporary path used for saving downloaded archives
Raises:
SystemExit: When qt_modules list is empty
"""
if not qt_modules:
raise SystemExit("No modules specified in qt_modules")
qt_path = qt_path.resolve()
need_to_install_qt = not qt_path.exists()
with TemporaryDirectory() as temporary_dir:
if need_to_install_qt:
urls = qt_modules
if icu_url:
qt_modules.append(icu_url)
download_and_extract(urls, qt_path, Path(temporary_dir))
patch_qt(qt_path)
def main() -> None:
"""Main"""
args: argparse.Namespace = get_arguments()
# Check that qt_module(s) or base-url/module_name(s) combo is specified
if not args.qt_modules and not (args.base_url and args.module_name):
raise SystemExit("'qt-module(s)' and/or 'base-url' with 'module_name(s)' required")
# Create the list of modules from qt_modules + module_names with base_url and postfix
qt_modules: list[str] = args.qt_modules
if args.base_url and args.module_name:
for module in args.module_name:
qt_modules += [args.base_url + "/" + module + "/" + module + args.base_url_postfix]
install_qt(
qt_path=args.qt_path,
qt_modules=qt_modules,
icu_url=args.icu7z
)
if __name__ == '__main__':
main()