Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4] Install desktop Qt when required to by Qt 6.2+ mobile and WASM #189

Merged
merged 7 commits into from
May 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/test-android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: CI-android

on: [push, pull_request, workflow_dispatch]

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-22.04
- windows-2022
- macos-12
qt:
- version: "5.15.2"
ndk-version: r21e
modules:
example-archives: qtbase qtsensors
example-modules:
- version: "6.3.2"
ndk-version: r21e
modules: qtsensors
example-archives: qtbase
example-modules: qtsensors

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 16
cache: npm
cache-dependency-path: action/

- run: |
cd action
npm ci || npm install
shell: bash

- run: |
cd action
npm run build

- name: Install Qt
uses: ./
with:
target: android
modules: ${{ matrix.qt.modules }}
version: ${{ matrix.qt.version }}
examples: true
example-archives: ${{ matrix.qt.example-archives }}
example-modules: ${{ matrix.qt.example-modules }}

- name: Install Android NDK
shell: bash
# Links to NDK are at https://github.com/android/ndk/wiki/Unsupported-Downloads
run: |
if [[ "${RUNNER_OS}" == "Linux" ]]; then
export TARGET_ARCH="linux"
elif [[ "${RUNNER_OS}" == "Windows" ]]; then
export TARGET_ARCH="windows"
else
export TARGET_ARCH="darwin"
fi
export NDK_VER_NUM=$(echo ${{ matrix.qt.ndk-version }} | sed -e 's/r(\d+).*/$1/g')
# If it's less than 23, append -x86_64
if (( "${NDK_VER_NUM}" < 23 )); then
export TARGET_ARCH="${TARGET_ARCH}-x86_64"
fi;
curl -O "https://dl.google.com/android/repository/android-ndk-${{ matrix.qt.ndk-version }}-${TARGET_ARCH}.zip"
unzip "android-ndk-${{ matrix.qt.ndk-version }}-${TARGET_ARCH}.zip"

- name: Build test project
env:
QT_VERSION: ${{ matrix.qt.version }}
run: |
export ANDROID_NDK_ROOT=$(pwd)/android-ndk-${{ matrix.qt.ndk-version }}
cd ../Qt/Examples/Qt-${{ matrix.qt.version }}/sensors/accelbubble
qmake || qmake.bat
make
shell: bash
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ Default: `false`

Version of [aqtinstall](https://github.com/miurahr/aqtinstall) to use, given in the format used by pip, for example: `==0.7.1`, `>=0.7.1`, `==0.7.*`. This is intended to be used to troubleshoot any bugs that might be caused or fixed by certain versions of aqtinstall.

Default: `==2.1.*`
Default: `==3.1.*`

### `py7zrversion`
Version of py7zr in the same style as the aqtversion and intended to be used for the same purpose.

Default: `==0.19.*`
Default: `==0.20.*`

### `extra`
This input can be used to append arguments to the end of the aqtinstall command for any special purpose.
Expand All @@ -253,8 +253,8 @@ Example value: `--external 7z`
tools: 'tools_ifw tools_qtcreator,qt.tools.qtcreator'
set-env: 'true'
tools-only: 'false'
aqtversion: '==2.1.*'
py7zrversion: '==0.19.*'
aqtversion: '==3.1.*'
py7zrversion: '==0.20.*'
extra: '--external 7z'
```

Expand Down
8 changes: 8 additions & 0 deletions README_upgrade_guide.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Upgrading `install-qt-action`

## Unreleased
* Updated `aqtinstall` to version 3.1.* by default.
* Use the `--autodesktop` flag to automatically install the desktop version of Qt, parallel to any WASM or mobile
versions of Qt 6.2 and above.
* If your action installed Qt 6.2+ for Android or WASM using `install-qt-action@v3`, then your action would have
needed to install the desktop version of Qt alongside the WASM/mobile version of Qt, otherwise it would not have
worked properly. As long as you are using `aqtinstall v3` or higher, the new version of `install-qt-action` will do
that automatically, so you can remove the second step where you add the parallel desktop version of Qt.
If you don't, your workflow will install desktop Qt twice.
* Added the `QT_ROOT_DIR` environment variable that points to the root of the Qt installation.
This variable points to the same directory as the old `Qt5_DIR` and `Qt6_DIR` variables.
* Changed `Qt5_DIR` environment variable, so that it points to `${QT_ROOT_DIR}/lib/cmake`, as required by CMake.
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ inputs:
default: false
aqtversion:
description: Version of aqtinstall to use in case of issues
default: ==2.1.*
default: ==3.1.*
py7zrversion:
description: Version of py7zr to use in case of issues
default: ==0.19.*
default: ==0.20.*
extra:
description: Any extra arguments to append to the back
source:
Expand Down
4 changes: 2 additions & 2 deletions action/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ inputs:
default: false
aqtversion:
description: Version of aqtinstall to use in case of issues
default: ==2.1.*
default: ==3.1.*
py7zrversion:
description: Version of py7zr to use in case of issues
default: ==0.19.*
default: ==0.20.*
extra:
description: Any extra arguments to append to the back
source:
Expand Down
47 changes: 34 additions & 13 deletions action/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as process from "process";

import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { exec } from "@actions/exec";
import { exec, getExecOutput } from "@actions/exec";

import * as glob from "glob";
import { compare, CompareOperator } from "compare-versions";
Expand All @@ -25,9 +25,19 @@ const setOrAppendEnvVar = (name: string, value: string): void => {
core.exportVariable(name, newValue);
};

const execPython = async (command: string, args: readonly string[]): Promise<number> => {
const pythonCommand = (command: string, args: readonly string[]): string => {
const python = process.platform === "win32" ? "python" : "python3";
return exec(`${python} -m ${command} ${args.join(" ")}`);
return `${python} -m ${command} ${args.join(" ")}`;
};
const execPython = async (command: string, args: readonly string[]): Promise<number> => {
return exec(pythonCommand(command, args));
};

const getPythonOutput = async (command: string, args: readonly string[]): Promise<string> => {
// Aqtinstall prints to both stderr and stdout, depending on the command.
// This function assumes we don't care which is which, and we want to see it all.
const out = await getExecOutput(pythonCommand(command, args));
return out.stdout + out.stderr;
};

const flaggedList = (flag: string, listArgs: readonly string[]): string[] => {
Expand Down Expand Up @@ -58,6 +68,12 @@ const locateQtArchDir = (installDir: string): string => {
}
};

const isAutodesktopSupported = async (): Promise<boolean> => {
const rawOutput = await getPythonOutput("aqt", ["version"]);
const match = rawOutput.match(/aqtinstall\(aqt\)\s+v(\d+\.\d+\.\d+)/);
return match ? compareVersions(match[1], ">=", "3.0.0") : false;
};

class Inputs {
readonly host: "windows" | "mac" | "linux";
readonly target: "desktop" | "android" | "ios";
Expand Down Expand Up @@ -130,7 +146,16 @@ class Inputs {
this.arch = core.getInput("arch");
// Set arch automatically if omitted
if (!this.arch) {
if (this.host === "windows") {
if (this.target === "android") {
if (
compareVersions(this.version, ">=", "5.14.0") &&
compareVersions(this.version, "<", "6.0.0")
) {
this.arch = "android";
} else {
this.arch = "android_armv7";
}
} else if (this.host === "windows") {
if (compareVersions(this.version, ">=", "5.15.0")) {
this.arch = "win64_msvc2019_64";
} else if (compareVersions(this.version, "<", "5.6.0")) {
Expand All @@ -140,15 +165,6 @@ class Inputs {
} else {
this.arch = "win64_msvc2017_64";
}
} else if (this.target === "android") {
if (
compareVersions(this.version, ">=", "5.14.0") &&
compareVersions(this.version, "<", "6.0.0")
) {
this.arch = "android";
} else {
this.arch = "android_armv7";
}
}
}

Expand Down Expand Up @@ -321,13 +337,18 @@ const run = async (): Promise<void> => {
// Install aqtinstall separately: allows aqtinstall to override py7zr if required
await execPython("pip install", [`"aqtinstall${inputs.aqtVersion}"`]);

// This flag will install a parallel desktop version of Qt, only where required.
// aqtinstall will automatically determine if this is necessary.
const autodesktop = (await isAutodesktopSupported()) ? ["--autodesktop"] : [];

// Install Qt
if (inputs.isInstallQtBinaries) {
const qtArgs = [
inputs.host,
inputs.target,
inputs.version,
...(inputs.arch ? [inputs.arch] : []),
...autodesktop,
...["--outputdir", inputs.dir],
...flaggedList("--modules", inputs.modules),
...flaggedList("--archives", inputs.archives),
Expand Down