Skip to content
Draft
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
20 changes: 16 additions & 4 deletions .github/workflows/github-cxx-qt-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,22 @@ jobs:
if-no-files-found: ignore

build-qt-minimal:
name: Ubuntu 24.04 (gcc) Qt 6 Minimal
needs: [clang_format, license_check, rust_format_check, markdown_lint, shellcheck]
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
include:
- name: macOS 15 (clang) Qt 6 Minimal
runs-on: macos-15
clang_format_path: /Users/runner/Library/Python/3.14/bin/clang-format
- name: Ubuntu 24.04 (gcc) Qt 6 Minimal
runs-on: ubuntu-24.04
clang_format_path: /home/runner/.local/bin/clang-format
- name: Windows 2022 (MSVC) Qt 6 Minimal
runs-on: windows-2022
clang_format_path: C:\Users\runneradmin\AppData\Roaming\Python\Python312\Scripts\clang-format.exe
runs-on: ${{ matrix.runs-on }}
name: ${{ matrix.name }}
steps:
- name: "Checkout repository"
uses: actions/checkout@v6
Expand All @@ -153,21 +166,20 @@ jobs:
run: >-
sudo apt-get update &&
sudo apt-get install -y
ninja-build
libdouble-conversion3
libgl1-mesa-dev
libssl-dev
libvulkan-dev
libxkbcommon-dev
pkg-config
valgrind

# Just test that we can build with no Qt install available
#
# NOTE: no compiler cache is needed as build is fast
- name: "Build"
run: cargo build --package qml-minimal-no-cmake
- name: Test output files exist
if: runner.os == 'Linux'
run: |
! command -v qmake
test -x ./target/debug/qml-minimal-no-cmake
Expand Down
56 changes: 48 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions crates/qt-build-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ sha2 = { version = "0.10.9", optional = true }
tempfile = { version = "3.25.0", optional = true }
tar = { version = "0.4.44", optional = true }
flate2 = { version = "1.1.9", optional = true }
qt-artifacts = { version = "0.1.2", optional = true }
qt-artifacts = { version = "0.1.3", optional = true }
qt-version = { version = "0.1.4", optional = true }
which = { version = "8.0.0", optional = true }
# NOTE: version 8.x has a MSRV of 1.88 and CXX-Qt is currently 1.85
zip = { version = "7.2.0", optional = true, default-features = false, features = ["deflate"] }

[features]
# TODO: should we default to qmake or let downstream crates specify, such as cxx-qt-build
Expand All @@ -44,7 +46,7 @@ default = ["qmake"]
# When linking Qt dynamically, this makes no difference.
link_qt_object_files = []
qmake = ["dep:which"]
qt_minimal = ["qt_version", "dep:serde", "serde/derive", "semver/serde", "dep:reqwest", "dep:sha2", "dep:tempfile", "dep:serde_json", "dep:flate2", "dep:tar", "dep:qt-artifacts", "dep:dirs"]
qt_minimal = ["qt_version", "dep:serde", "serde/derive", "semver/serde", "dep:reqwest", "dep:sha2", "dep:tempfile", "dep:serde_json", "dep:flate2", "dep:tar", "dep:qt-artifacts", "dep:dirs", "dep:zip"]
qt_version = ["dep:qt-version"]
serde = ["dep:serde"]

Expand Down
16 changes: 14 additions & 2 deletions crates/qt-build-utils/src/installation/qt_minimal/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ impl ParsedQtArtifact {
.expect("Could not verify sha256 hash");

// Extract into the target folder
super::extract::extract_archive(&archive_path, target_path)
let archive_format = if self.url.ends_with(".tar.gz") {
super::extract::ArchiveFormat::TarGz
} else if self.url.ends_with(".zip") {
super::extract::ArchiveFormat::Zip
} else {
panic!("Unknown archive format to decompress: {}", self.url);
};
super::extract::extract_archive(&archive_path, target_path, archive_format)
.expect("Could not extract archive into target");

target_path.to_path_buf()
Expand Down Expand Up @@ -77,7 +84,12 @@ impl ParsedQtArtifact {
}

if self.sha256 != hash_string {
return Err(anyhow::anyhow!("sha256 does not match for: {}", &self.url));
return Err(anyhow::anyhow!(
"sha256 does not match for: {}, expected: {}, actual: {}",
&self.url,
self.sha256,
hash_string
));
}

Ok(())
Expand Down
33 changes: 27 additions & 6 deletions crates/qt-build-utils/src/installation/qt_minimal/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,36 @@
use flate2::read::GzDecoder;
use std::{fs::File, path::Path};
use tar::Archive;
use zip::ZipArchive;

pub(crate) enum ArchiveFormat {
TarGz,
Zip,
}

/// Extract archive to same directory as this workspace, not same as path
pub(crate) fn extract_archive(archive_path: &Path, target_path: &Path) -> anyhow::Result<()> {
let tar_gz = File::open(archive_path)?;
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
pub(crate) fn extract_archive(
archive_path: &Path,
target_path: &Path,
archive_format: ArchiveFormat,
) -> anyhow::Result<()> {
let file = File::open(archive_path)?;

match archive_format {
ArchiveFormat::TarGz => {
let gz_decoder = GzDecoder::new(file);
let mut archive = Archive::new(gz_decoder);

// Modify destination in unpack here
archive.unpack(target_path)?;
}
ArchiveFormat::Zip => {
let mut archive = ZipArchive::new(file)?;

// Modify destination in unpack here
archive.unpack(target_path)?;
// Modify destination in unpack here
archive.extract(target_path)?;
}
}

Ok(())
}
24 changes: 22 additions & 2 deletions crates/qt-build-utils/src/installation/qt_minimal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ impl TryFrom<PathBuf> for QtInstallationQtMinimal {
println!("cargo::rerun-if-changed={}", path_qt.display());

// Verify that the expected folders exist
for folder in ["bin", "include", "lib", "libexec"] {
//
// NOTE: libexec does not exist on Windows, so is not mandatory
for folder in ["bin", "include", "lib"] {
if !path_qt.join(folder).exists() {
return Err(anyhow::anyhow!(
"Failed to find {folder} in Qt path: {}",
Expand All @@ -45,7 +47,19 @@ impl TryFrom<PathBuf> for QtInstallationQtMinimal {
.join(folder)
.join(crate::QtTool::QtPaths.binary_name())
})
.find(|path| path.exists())
.find(|path| {
if path.exists() {
return true;
}

// NOTE: try with .exe for Windows
let path_exe = path.with_extension("exe");
if path_exe.exists() {
return true;
}

false
})
else {
return Err(anyhow::anyhow!(
"Failed to find qtpaths in Qt path: {}",
Expand Down Expand Up @@ -159,6 +173,12 @@ impl QtInstallation for QtInstallationQtMinimal {
if path.exists() {
return Ok(path);
}

// NOTE: try with .exe for Windows
let path_exe = path.with_extension("exe");
if path_exe.exists() {
return Ok(path_exe);
}
}

Err(anyhow::anyhow!(
Expand Down
Loading