Skip to content

On non-Unix platforms, use deep copying rather than symlinking #5296

On non-Unix platforms, use deep copying rather than symlinking

On non-Unix platforms, use deep copying rather than symlinking #5296

# SPDX-FileCopyrightText: 2022 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# SPDX-FileContributor: Andrew Hayzen <[email protected]>
# SPDX-FileContributor: Be <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0
name: cxx-qt tests
on:
push:
branches:
- 'main'
- '[0-9]+\.[0-9]+\.x'
pull_request:
schedule:
# Run daily at 01:01
# This ensures CI still works and ensures the cache remains active
- cron: "1 1 * * *"
# Cancel any previous runs for the same pull request
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
jobs:
clang_format:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
# Note ensure that matrix runner is updated too
- run: |
pip install --user --break-system-packages clang-format==18.1.8
test -x ~/.local/bin/clang-format
test -x /home/runner/.local/bin/clang-format
- run: ./scripts/clang_format_check.sh /home/runner/.local/bin/clang-format .
license_check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v5
rust_format_check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- run: rustup default 1.77.2
- run: rustup component add rustfmt
- run: cargo fmt --all --check --verbose
markdown_lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: DavidAnson/markdownlint-cli2-action@v18
with:
globs: '**/*.md'
shellcheck:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
# Shellcheck is likely already installed but lets ensure it is
- name: install shellcheck
run: sudo apt-get install -y shellcheck
- name: shellcheck
run: shellcheck scripts/*.sh
coverage:
# Run after pre checks
needs: [ clang_format, license_check, rust_format_check, markdown_lint, shellcheck ]
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup toolchain
run: |
rustup default 1.77.2
cargo install grcov
rustup component add llvm-tools rustfmt
- name: build
env:
RUSTFLAGS: -Cinstrument-coverage
LLVM_PROFILE_FILE: coverage/coverage_data-%p-%m.profraw
run: cargo build --package cxx-qt-gen
- name: test
env:
RUSTFLAGS: -Cinstrument-coverage
LLVM_PROFILE_FILE: coverage/coverage_data-%p-%m.profraw
run: cargo test --lib --package cxx-qt-gen
- name: generate-report
run: grcov . -s . --binary-path ./target/debug/ -t lcov --branch --ignore-not-existing -o ./target/debug/lcov.info --excl-start CODECOV_EXCLUDE_START --excl-stop CODECOV_EXCLUDE_STOP
- name: upload-report
uses: codecov/codecov-action@v5
with:
directory: ./target/debug/
files: lcov.info
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
build-wasm:
name: Ubuntu 24.04 (wasm_32) Qt 6
needs: [clang_format, license_check, rust_format_check, markdown_lint, shellcheck]
runs-on: ubuntu-24.04
env:
SCCACHE_CACHE_SIZE: 600M
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
- name: Setup toolchain
run: |
rustup default 1.77.2
rustup component add rustfmt
rustup target add wasm32-unknown-emscripten
- name: "Rust tools cache"
uses: actions/cache@v4
id: rust-tools-cache
with:
path: |
~/.cargo/bin/sccache
~/.cargo/bin/mdbook
~/.cargo/bin/mdbook-linkcheck
key: ubuntu-24.04_sccache-0.8.2_mdbook-0.4.36_mdbook-linkcheck-0.7.7
- name: "Build Rust tools"
if: steps.rust-tools-cache.outputs.cache-hit != 'true'
# Do not build with storage backends enabled, we only need local
run: |
cargo install --no-default-features --version 0.8.2 sccache
cargo install --version 0.4.36 mdbook
cargo install --version 0.7.7 mdbook-linkcheck
# We want our compiler cache to always update to the newest state.
# The best way for us to achieve this is to **always** update the cache after every landed commit.
# That way it will closely follow our development.
# And if a PR diverges a lot with its cache that's not a big deal, as it will be merged eventually.
#
# This is a workaround for the fact that GH doesn't support updating existing caches.
# See: https://github.com/azu/github-actions-overwrite-cache-example
#
# Ideally we'd like to use this:
# - name: "Compiler cache"
# uses: actions/cache@v4
# with:
# update: true <------- THIS DOESN'T EXIST YET
# path: /home/runner/.cache/sccache
# key: "Ubuntu 24.04 (wasm_32) Qt6_compiler_cache"
- name: "Restore Compiler Cache"
id: compiler-cache-restore
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: "Ubuntu 24.04 (wasm_32) Qt6_compiler_cache"
- name: "emsdk cache"
uses: actions/cache@v4
id: emsdk-cache
with:
path: ./emsdk
key: emsdk_2.0.14
- name: "Setup emsdk"
if: steps.emsdk-cache.outputs.cache-hit != 'true'
run: |
git clone https://github.com/emscripten-core/emsdk
./emsdk/emsdk install 2.0.14
./emsdk/emsdk activate 2.0.14
- name: "Install Dependencies"
run: |
sudo apt-get update && sudo apt-get install -y ninja-build
pip install --user --break-system-packages clang-format==18.1.8
test -x ~/.local/bin/clang-format
test -x /home/runner/.local/bin/clang-format
- name: Install Qt WASM & Desktop
uses: jurplel/install-qt-action@v4
with:
version: '6.2.4'
host: 'linux'
target: 'desktop'
arch: 'wasm_32'
tools: 'tools_cmake'
cache: true
- name: "Configure"
# FIXME: ninja is not being found?
env:
RUSTC_WRAPPER: sccache
run: |
source ./emsdk/emsdk_env.sh
/home/runner/work/cxx-qt/Qt/6.2.4/wasm_32/bin/qt-cmake -DQT_HOST_PATH=/home/runner/work/cxx-qt/Qt/6.2.4/gcc_64 -DBUILD_WASM=ON -Bbuild .
- name: "Build"
env:
RUSTC_WRAPPER: sccache
run: cmake --build build --parallel 4
- name: Test output files exist
run: |
test -f ./build/examples/qml_minimal/example_qml_minimal.html
test -f ./build/examples/qml_minimal/example_qml_minimal.js
test -f ./build/examples/qml_minimal/libqml_minimal.a
test -x ./build/examples/qml_minimal/example_qml_minimal.wasm
test -f ./build/examples/qml_minimal/qtloader.js
test -f ./build/examples/qml_features/example_qml_features.html
test -f ./build/examples/qml_features/example_qml_features.js
test -f ./build/examples/qml_features/libqml_features.a
test -x ./build/examples/qml_features/example_qml_features.wasm
test -f ./build/examples/qml_features/qtloader.js
- name: "Print compiler cache statistics"
run: sccache --show-stats
# This is a workaround for the fact that GH doesn't support updating existing caches.
# See: https://github.com/azu/github-actions-overwrite-cache-example
- name: "Delete previous compiler cache"
# Updating th cache doesn't work from forks
# So update it once it's merged into the repo
if: ${{ steps.compiler-cache-restore.outputs.cache-hit && github.event_name == 'push' }}
continue-on-error: true
run: |
gh extension install actions/gh-actions-cache
gh actions-cache delete "Ubuntu 22.04 (wasm_32) Qt6_compiler_cache" --confirm
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Save Compiler Cache"
# Updating th cache doesn't work from forks
# So update it once it's merged into the repo
if: ${{ github.event_name == 'push' }}
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: "Ubuntu 24.04 (wasm_32) Qt6_compiler_cache"
build:
# Run after pre checks
needs: [clang_format, license_check, rust_format_check, markdown_lint, shellcheck]
strategy:
fail-fast: false
matrix:
include:
- name: Ubuntu 24.04 (gcc) Qt5
os: ubuntu-24.04
qt_version: 5
aqt_version: '5.15.2'
aqt_arch: 'gcc_64'
aqt_host: 'linux'
cores: 4
# FIXME: valgrind complains about invalid debuginfo. Might be fixed when Ubuntu updates to valgrind 3.20
# https://bugs.kde.org/show_bug.cgi?id=452758
ctest_args: --exclude-regex '^(example_qml_features_test_valgrind|example_qml_minimal_myobject_test_valgrind)$'
qt_qpa_platform: offscreen
compiler_cache_path: /home/runner/.cache/sccache
clang_format_path: /home/runner/.local/bin/clang-format
cargo_dir: ~/.cargo
rustc_wrapper: sccache
- name: Ubuntu 24.04 (gcc) Qt6
os: ubuntu-24.04
qt_version: 6
aqt_version: '6.8.0'
aqt_arch: 'linux_gcc_64'
aqt_host: 'linux'
cores: 4
# FIXME: valgrind complains about invalid debuginfo. Might be fixed when Ubuntu updates to valgrind 3.20
# https://bugs.kde.org/show_bug.cgi?id=452758
ctest_args: --exclude-regex '^(example_qml_features_test_valgrind|example_qml_minimal_myobject_test_valgrind)$'
qt_qpa_platform: offscreen
compiler_cache_path: /home/runner/.cache/sccache
clang_format_path: /home/runner/.local/bin/clang-format
cargo_dir: ~/.cargo
rustc_wrapper: sccache
packages-extra: >-
libgl1-mesa-dev
libvulkan-dev
libxkbcommon-dev
- name: macOS 13 (clang) Qt5
os: macos-13
qt_version: 5
aqt_version: '5.15.2'
aqt_arch: 'clang_64'
aqt_host: 'mac'
dyld_framework_path: /Users/runner/work/cxx-qt/Qt/5.15.2/clang_64/lib
# https://doc.qt.io/qt-5/macos.html#target-platforms
macosx_deployment_target: '10.13'
cores: 3
# FIXME: qmltestrunner fails to import QtQuick module
# https://github.com/KDAB/cxx-qt/issues/110
ctest_args: --exclude-regex '^(cargo_clippy|cargo_doc|example_qml_features_test|example_qml_minimal_myobject_test|cargo_build_rerun|.*valgrind)$'
qt_qpa_platform: cocoa
compiler_cache_path: /Users/runner/Library/Caches/Mozilla.sccache
clang_format_path: /Users/runner/Library/Python/3.13/bin/clang-format
cargo_dir: ~/.cargo
cc: clang
cxx: clang++
# sccache is disabled due on macOS to https://github.com/mozilla/sccache/issues/2092
cmake_args: -DSCCACHE=OFF
- name: macOS 14 (clang) Qt6
os: macos-14
qt_version: 6
aqt_version: '6.8.0'
aqt_arch: 'clang_64'
aqt_host: 'mac'
dyld_framework_path: /Users/runner/work/cxx-qt/Qt/6.8.0/macos/lib
# https://doc.qt.io/qt-6.7/macos.html#target-platforms
macosx_deployment_target: '13.0'
cores: 3
# FIXME: qmltestrunner fails to import QtQuick module
# https://github.com/KDAB/cxx-qt/issues/110
ctest_args: --exclude-regex '^(cargo_clippy|cargo_doc|example_qml_features_test|example_qml_minimal_myobject_test|cargo_build_rerun|.*valgrind)$'
qt_qpa_platform: cocoa
compiler_cache_path: /Users/runner/Library/Caches/Mozilla.sccache
clang_format_path: /Users/runner/Library/Python/3.13/bin/clang-format
cargo_dir: ~/.cargo
cc: clang
cxx: clang++
# sccache is disabled on macOS due to https://github.com/mozilla/sccache/issues/2092
cmake_args: -DSCCACHE=OFF
- name: Windows 2022 (MSVC) Qt5
os: windows-2022
qt_version: 5
aqt_version: '5.15.2'
aqt_arch: 'win64_msvc2019_64'
aqt_host: 'windows'
cores: 4
ctest_args: --exclude-regex '^(cargo_clippy|cargo_doc|cargo_build_rerun|.*valgrind)$'
exe_suffix: .exe
qt_qpa_platform: windows
compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache
clang_format_path: C:\Users\runneradmin\AppData\Roaming\Python\Python39\Scripts\clang-format.exe
cargo_dir: C:\Users\runneradmin\.cargo
cc: cl
cxx: cl
rustc_wrapper: sccache
- name: Windows 2022 (MSVC2019) Qt6
os: windows-2022
qt_version: 6
aqt_version: '6.7.3'
aqt_arch: 'win64_msvc2019_64'
aqt_host: 'windows'
cores: 4
ctest_args: --exclude-regex '^(cargo_clippy|cargo_doc|cargo_build_rerun|.*valgrind)$'
exe_suffix: .exe
qt_qpa_platform: windows
compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache
clang_format_path: C:\Users\runneradmin\AppData\Roaming\Python\Python39\Scripts\clang-format.exe
cargo_dir: C:\Users\runneradmin\.cargo
cc: cl
cxx: cl
rustc_wrapper: sccache
- name: Windows 2022 (MSVC2022) Qt6
os: windows-2022
qt_version: 6
aqt_version: '6.8.0'
aqt_arch: 'win64_msvc2022_64'
aqt_host: 'windows'
cores: 4
ctest_args: --exclude-regex '^(cargo_clippy|cargo_doc|cargo_build_rerun|.*valgrind)$'
exe_suffix: .exe
qt_qpa_platform: windows
compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache
clang_format_path: C:\Users\runneradmin\AppData\Roaming\Python\Python39\Scripts\clang-format.exe
cargo_dir: C:\Users\runneradmin\.cargo
cc: cl
cxx: cl
rustc_wrapper: sccache
runs-on: ${{ matrix.os }}
name: ${{ matrix.name }}
env:
# ld: warning: object file (LIB) was built for newer macOS version (12.7) than being linked (12.0)
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
# sccache is around 180-300M in size for a normal build
# With GitHub caches we have a 10 GB limit / 6 conditions = 1666 MB
# Allow a larger cache size so that code in branches can be cached
# but still leave room for the tools cache
SCCACHE_CACHE_SIZE: 600M
steps:
- name: "Clone Git repository"
uses: actions/checkout@v4
# Ensure clippy and rustfmt is installed, they should come from github runner
# clippy version needs to be 1.78.0 for the MSRV lint
#
# Note we still need rustfmt for the cxx-qt-gen tests
- name: "Install Rust toolchain"
run: |
rustup toolchain add 1.78.0 --component clippy
rustup default 1.77.2
rustup component add rustfmt
- name: "Rust tools cache"
uses: actions/cache@v4
id: rust-tools-cache
with:
path: |
${{ matrix.cargo_dir }}/bin/sccache${{ matrix.exe_suffix }}
${{ matrix.cargo_dir }}/bin/mdbook${{ matrix.exe_suffix }}
${{ matrix.cargo_dir }}/bin/mdbook-linkcheck${{ matrix.exe_suffix }}
key: ${{ matrix.os }}_sccache-0.8.2_mdbook-0.4.36_mdbook-linkcheck-0.7.7
- name: "Build Rust tools"
if: steps.rust-tools-cache.outputs.cache-hit != 'true'
# Do not build with storage backends enabled, we only need local
run: |
cargo install --no-default-features --version 0.8.2 sccache
cargo install --version 0.4.36 mdbook
cargo install --version 0.7.7 mdbook-linkcheck
# We want our compiler cache to always update to the newest state.
# The best way for us to achieve this is to **always** update the cache after every landed commit.
# That way it will closely follow our development.
# And if a PR diverges a lot with its cache that's not a big deal, as it will be merged eventually.
#
# This is a workaround for the fact that GH doesn't support updating existing caches.
# See: https://github.com/azu/github-actions-overwrite-cache-example
#
# Ideally we'd like to use this:
# - name: "Compiler cache"
# uses: actions/cache@v4
# with:
# update: true <------- THIS DOESN'T EXIST YET
# path: ${{ matrix.compiler_cache_path }}
# key: ${{ matrix.name }}_compiler_cache
- name: "Restore Compiler Cache"
id: compiler-cache-restore
uses: actions/cache/restore@v4
with:
path: ${{ matrix.compiler_cache_path }}
key: ${{ matrix.name }}_compiler_cache
- name: "Install clang-format"
# Note ensure that clang-format runner is updated too
run: |
pip install --user --break-system-packages clang-format==18.1.8
test -x ${{ matrix.clang_format_path }}
# Version info found using https://ddalcino.github.io/aqt-list-server/
- name: "Install Qt"
uses: jurplel/install-qt-action@v4
with:
version: ${{ matrix.aqt_version }}
host: ${{ matrix.aqt_host }}
target: 'desktop'
arch: ${{ matrix.aqt_arch }}
tools: 'tools_cmake'
cache: true
- name: "[Ubuntu] Install dependencies"
if: runner.os == 'Linux'
run: >-
sudo apt-get update &&
sudo apt-get install -y
ninja-build
libssl-dev
pkg-config
valgrind
${{ matrix.packages-extra }}
# hack around https://bugs.launchpad.net/ubuntu/+source/qtchooser/+bug/1964763
- name: "[Ubuntu] Add Qt6 tools to PATH"
if: runner.os == 'Linux' && matrix.qt_version == 6
run: echo "PATH=/usr/lib/qt6/bin:${PATH}" >> "${GITHUB_ENV}"
- name: "[macOS] Install dependencies"
if: runner.os == 'macOS'
# automake is needed for building libicu which is a dependency of Qt
run: brew install automake autoconf-archive ninja
# Required for CMake to find Ninja
- name: "[Windows] Set up MSVC Developer Command Prompt"
if: runner.os == 'Windows'
uses: seanmiddleditch/gha-setup-vsdevenv@v4
# Ninja is required on Windows for CMAKE_CXX_COMPILER_LAUNCHER to work for using sccache.
- name: "Configure"
run: >-
cmake ${{ matrix.cmake_args }}
-D USE_QT5=${{ matrix.qt_version == 5 }}
-D CMAKE_BUILD_TYPE=Release
-G Ninja
-S . -B build
env:
RUSTC_WRAPPER: ${{ matrix.rustc_wrapper }}
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
- name: "Build"
run: cmake --build build --config Release --parallel ${{ matrix.cores }}
env:
RUSTC_WRAPPER: ${{ matrix.rustc_wrapper }}
- name: "Test"
run: ctest ${{ matrix.ctest_args }} -C Release -T test --output-on-failure --parallel ${{ matrix.cores }}
working-directory: ./build
env:
# Use the version of clang-format from pip
CLANG_FORMAT_BINARY: ${{ matrix.clang_format_path }}
RUSTC_WRAPPER: ${{ matrix.rustc_wrapper }}
QT_QPA_PLATFORM: ${{ matrix.qt_qpa_platform }}
QT_SELECT: qt${{ matrix.qt_version }}
DYLD_FRAMEWORK_PATH: ${{ matrix.dyld_framework_path }}
- name: "Print compiler cache statistics"
run: sccache --show-stats
# This is a workaround for the fact that GH doesn't support updating existing caches.
# See: https://github.com/azu/github-actions-overwrite-cache-example
- name: "Delete previous compiler cache"
# Updating th cache doesn't work from forks
# So update it once it's merged into the repo
if: ${{ steps.compiler-cache-restore.outputs.cache-hit && github.event_name == 'push' }}
continue-on-error: true
run: |
gh extension install actions/gh-actions-cache
gh actions-cache delete "${{ matrix.name }}_compiler_cache" --confirm
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Save Compiler Cache"
# Updating th cache doesn't work from forks
# So update it once it's merged into the repo
if: ${{ github.event_name == 'push' }}
uses: actions/cache/save@v4
with:
path: ${{ matrix.compiler_cache_path }}
key: ${{ matrix.name }}_compiler_cache