forked from qt-creator/qt-creator
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:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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
193
scripts/build_sdktool.py
Executable 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()
|
@@ -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
103
scripts/install_qt.py
Executable 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()
|
Reference in New Issue
Block a user