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

use vcpkg for Windows & macOS builds; add Qt6 builds; use sccache #107

Merged
merged 6 commits into from
Mar 10, 2022
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
241 changes: 204 additions & 37 deletions .github/workflows/github-cxx-qt-tests.yml
Original file line number Diff line number Diff line change
@@ -1,46 +1,213 @@
# 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, pull_request]
jobs:
ctest:
runs-on: ubuntu-20.04
build:
Be-ing marked this conversation as resolved.
Show resolved Hide resolved
strategy:
fail-fast: false
matrix:
include:
- name: Ubuntu 20.04 (gcc) Qt5
os: ubuntu-20.04
qt_version: 5
qt_qpa_platform: offscreen
compiler_cache_path: /home/runner/.cache/sccache
ahayzen-kdab marked this conversation as resolved.
Show resolved Hide resolved
cargo_dir: ~/.cargo
# TODO: Remove PPA for Qt 5.15 when Ubuntu 22.04 is available
ppa: ppa:savoury1/qt-5-15
packages-extra: >-
qtbase5-dev
qtdeclarative5-dev
qtquickcontrols2-5-dev
qml-module-qtquick2
qml-module-qtquick-controls2
qml-module-qttest
workspace: /home/runner/cxx-qt
- name: Ubuntu 20.04 (gcc) Qt6
os: ubuntu-20.04
qt_version: 6
# FIXME: fix valgrind failures
ahayzen-kdab marked this conversation as resolved.
Show resolved Hide resolved
ctest_args: --exclude-regex '^.*valgrind$'
qt_qpa_platform: offscreen
compiler_cache_path: /home/runner/.cache/sccache
cargo_dir: ~/.cargo
# TODO: Remove PPA for Qt 6 when Ubuntu 22.04 is available
ppa: ppa:daschuer/qt6-backports
packages-extra: >-
qt6-base-dev
qt6-declarative-dev
qt6-declarative-dev-tools
qml6-module-qtquick-controls
qml6-module-qtquick-window
qml6-module-qttest
qml6-module-qtqml-workerscript
libgl1-mesa-dev
libvulkan-dev
libxkbcommon-dev
workspace: /home/runner/cxx-qt

- name: macOS 11 (clang) Qt5
os: macos-11
qt_version: 5
# FIXME: qmltestrunner fails to import QtQuick module
ctest_args: --exclude-regex '^(example_qml_extension_plugin_test|reuse_lint|.*valgrind)$'
qt_qpa_platform: cocoa
compiler_cache_path: /Users/runner/Library/Caches/Mozilla.sccache
cargo_dir: ~/.cargo
workspace: /Users/runner/cxx-qt
- name: macOS 11 (clang) Qt6
os: macos-11
qt_version: 6
# FIXME: qmltestrunner fails to import QtQuick module
ctest_args: --exclude-regex '^(example_qml_extension_plugin_test|reuse_lint|.*valgrind)$'
qt_qpa_platform: cocoa
compiler_cache_path: /Users/runner/Library/Caches/Mozilla.sccache
cargo_dir: ~/.cargo
workspace: /Users/runner/cxx-qt

- name: Windows 2022 (MSVC) Qt5
os: windows-2022
qt_version: 5
# FIXME: many tests fail to link
ctest_args: --exclude-regex '^(cxx_qt_gen_cargo_tests|example_qml.*|qml.*tests|test.*|reuse_lint|cpp_clang_format|.*valgrind)$'
exe_suffix: .exe
qt_qpa_platform: windows
compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache
cargo_dir: C:\Users\runneradmin\.cargo
cc: cl
cxx: cl
# The D drive runs out of space when building dependencies with vcpkg.
workspace: C:\cxx-qt
- name: Windows 2022 (MSVC) Qt6
os: windows-2022
qt_version: 6
# FIXME: many tests fail to link
ctest_args: --exclude-regex '^(cxx_qt_gen_cargo_tests|example_qml.*|qml.*tests|test.*|reuse_lint|cpp_clang_format|.*valgrind)$'
exe_suffix: .exe
qt_qpa_platform: windows
compiler_cache_path: C:\Users\runneradmin\AppData\Local\Mozilla\sccache\cache
cargo_dir: C:\Users\runneradmin\.cargo
cc: cl
cxx: cl
# The D drive runs out of space when building dependencies with vcpkg.
workspace: C:\cxx-qt

runs-on: ${{ matrix.os }}
name: ${{ matrix.name }}

steps:
- uses: actions/checkout@v2
# Install Rust toolchain
- uses: actions-rs/toolchain@v1
with:
components: clippy, rustfmt
toolchain: stable
# Instal mdbook and mdbook-linkcheck
- name: Install mdbook and mdbook-linkcheck from binaries
run: |
mkdir mdbook
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
curl -sSL https://github.com/Michael-F-Bryan/mdbook-linkcheck/releases/latest/download/mdbook-linkcheck.x86_64-unknown-linux-gnu.zip -o mdbook-linkcheck.zip
unzip mdbook-linkcheck.zip -d mdbook-linkcheck/
rm mdbook-linkcheck.zip
chmod +x ./mdbook-linkcheck/mdbook-linkcheck
echo `pwd`/mdbook-linkcheck >> $GITHUB_PATH
# FIXME: FUTURE: Remove PPA for Qt 5.15 once 22.04 is available
# https://launchpad.net/~savoury1/+archive/ubuntu/qt-5-15
- run: sudo add-apt-repository ppa:savoury1/qt-5-15
# Install clang-format, Qt, reuse, valgrind
- run: sudo apt-get update
- run: sudo apt-get install -y clang-format-12 libssl-dev pkg-config python3-pip qtbase5-dev qtdeclarative5-dev qtquickcontrols2-5-dev qml-module-qtquick2 qml-module-qtquick-controls2 qml-module-qttest valgrind
- run: sudo ln -s /usr/bin/clang-format-12 /usr/local/bin/clang-format
- run: pip3 install reuse
# Ensure we have a clean build folder
- run: rm -rf build/
- run: mkdir -p build/
# Configure and build CMake then run ctest
#
# Note that each github action run command is executed from the same directory even after
# performing cd so for the ctest line we need to cd within the same command
- run: cmake -S. -Bbuild/ -G "Unix Makefiles"
- run: cmake --build build/ --config Debug --target all -j$(nproc)
- run: (cd build/ && QT_QPA_PLATFORM=offscreen ctest -j$(nproc) -C Debug -T test --output-on-failure)
# On Windows, the D drive that the workspace is on by default runs out of space when
# vcpkg builds Qt, so the repo needs to be cloned to the C drive. GitHub's checkout
# action does not support cloning to a path outside GITHUB_WORKSPACE:
# https://github.com/actions/checkout/issues/197
- name: "Clone Git repository"
uses: LebedevRI/checkout@issue197
Be-ing marked this conversation as resolved.
Show resolved Hide resolved
ahayzen-kdab marked this conversation as resolved.
Show resolved Hide resolved
with:
path: ${{ matrix.workspace }}
- name: "Install Rust toolchain"
uses: actions-rs/toolchain@v1
with:
components: clippy, rustfmt
toolchain: stable

- name: "Rust tools cache"
uses: actions/cache@v2
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.2.15_mdbook-0.4.15_mdbook-linkcheck-0.2.8
ahayzen-kdab marked this conversation as resolved.
Show resolved Hide resolved
- name: "Build Rust tools"
if: steps.rust-tools-cache.outputs.cache-hit != 'true'
run: cargo install sccache mdbook mdbook-linkcheck

- name: "Compiler cache"
uses: actions/cache@v2
with:
path: ${{ matrix.compiler_cache_path }}
key: ${{ matrix.name }}-${{ github.head_ref }}-${{ github.run_number }}
restore-keys: |
${{ matrix.name }}-${{ github.head_ref }}
${{ matrix.name }}

- name: "[Ubuntu] Install dependencies"
if: runner.os == 'Linux'
run: >-
sudo add-apt-repository ${{ matrix.ppa }} &&
sudo apt-get update &&
sudo apt-get install -y
ninja-build
clang-format-12
libssl-dev
pkg-config
python3-pip
valgrind
${{ matrix.packages-extra }}
- name: "[Ubuntu] Install reuse"
if: runner.os == 'Linux'
run: pip3 install reuse
- name: "[macOS] Install dependencies"
if: runner.os == 'macOS'
# automake is needed for building libicu which is a dependency of Qt
run: brew install automake ninja clang-format

- name: "Authenticate to GitHub Packages"
# TODO: replace 'Be-ing' with 'KDAB'
ahayzen-kdab marked this conversation as resolved.
Show resolved Hide resolved
if: runner.os != 'Linux' && github.repository_owner == 'Be-ing'
shell: bash
run: |
nuget sources add -Name cxx-qt-github-packages -Source https://nuget.pkg.github.com/Be-ing/index.json -Username Be-ing -Password ${{ secrets.GITHUB_TOKEN }} -NonInteractive
nuget setapikey ${{ secrets.GITHUB_TOKEN }} -Source cxx-qt-github-packages -NonInteractive
echo "VCPKG_BINARY_SOURCES=clear;nuget,cxx-qt-github-packages,readwrite;" >> "${GITHUB_ENV}"

# Required for CMake to find Ninja
- name: "[Windows] Set up MSVC Developer Command Prompt"
if: runner.os == 'Windows'
uses: seanmiddleditch/gha-setup-vsdevenv@v3

# Ninja is required on Windows for CMAKE_CXX_COMPILER_LAUNCHER to work for using sccache.
- name: "Configure"
run: >-
cmake
-D QT_DEFAULT_MAJOR_VERSION=${{ matrix.qt_version }}
-D CMAKE_BUILD_TYPE=Debug
-G Ninja
-S . -B build
working-directory: ${{ matrix.workspace }}
env:
RUSTC_WRAPPER: sccache
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
- name: "Build"
run: cmake --build build --config Debug --parallel 2
working-directory: ${{ matrix.workspace }}
env:
RUSTC_WRAPPER: sccache
- name: "Test"
run: ctest ${{ matrix.ctest_args }} -C Debug -T test --output-on-failure --parallel 2
working-directory: ${{ matrix.workspace }}/build
env:
RUSTC_WRAPPER: sccache
QT_QPA_PLATFORM: ${{ matrix.qt_qpa_platform }}
QT_SELECT: qt${{ matrix.qt_version }}

- name: "Print compiler cache statistics"
run: sccache --show-stats

- name: Upload GitHub Actions artifacts of vcpkg logs
if: always()
uses: actions/upload-artifact@v2
with:
name: vcpkg-logs-${{ matrix.name }}
path: |
${{ matrix.workspace }}/vcpkg/buildtrees/**/*.log
${{ matrix.workspace }}/build/vcpkg-bootstrap.log
${{ matrix.workspace }}/build/vcpkg-manifest-install.log
if-no-files-found: ignore
5 changes: 5 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: Be <[email protected]>
# SPDX-License-Identifier: MIT OR Apache-2.0
[submodule "vcpkg"]
path = vcpkg
url = https://github.com/microsoft/vcpkg.git
90 changes: 90 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-FileCopyrightText: 2021 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# SPDX-FileContributor: Andrew Hayzen <[email protected]>
# SPDX-FileContributor: Gerhard de Clercq <[email protected]>
# SPDX-FileContributor: Be <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0

Expand All @@ -10,11 +11,100 @@ cmake_minimum_required(VERSION 3.16)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()

Be-ing marked this conversation as resolved.
Show resolved Hide resolved
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

option(QT_DEFAULT_MAJOR_VERSION "Major version of Qt to use (6 or 5)" 6)

if(WIN32 OR APPLE)
option(VCPKG "Use vcpkg for dependencies" ON)
else()
option(VCPKG "Use vcpkg for dependencies" OFF)
endif()

if(VCPKG)
# Explicitly setting QT_DEFAULT_MAJOR_VERSION can fail on systems that have both Qt6
# and Qt5 installed, so only set it automatically when using vcpkg.
if((NOT QT_DEFAULT_MAJOR_VERSION EQUAL 5) AND (NOT QT_DEFAULT_MAJOR_VERSION EQUAL 6))
set(QT_DEFAULT_MAJOR_VERSION 6)
endif()

set(VCPKG_MANIFEST_FEATURES "qt${QT_DEFAULT_MAJOR_VERSION}")

include(InitializeVcpkg)

# These are required for binary caching to work reliably across machines.
set(VCPKG_FEATURE_FLAGS "-compilertracking")
set(VCPKG_INSTALL_OPTIONS "--x-abi-tools-use-exact-versions")

if(NOT DEFINED ENV{VCPKG_BINARY_SOURCES})
if(WIN32)
set(COMMAND_PREIFX "")
set(EXE_SUFFIX ".exe")
set(SCRIPT_SUFFIX ".bat")
set(DOTNET_RUNTIME "")
else()
set(COMMAND_PREFIX "./")
set(EXE_SUFFIX "")
set(SCRIPT_SUFFIX ".sh")
set(DOTNET_RUNTIME "mono")
endif()

# vcpkg can download NuGet, so bootstrap vcpkg if the executable is not found.
if(NOT EXISTS "${VCPKG_ROOT}/vcpkg${EXE_SUFFIX}")
message(STATUS "Bootstrapping vcpkg")
execute_process(
COMMAND "${COMMAND_PREFIX}bootstrap-vcpkg${SCRIPT_SUFFIX}"
WORKING_DIRECTORY ${VCPKG_ROOT}
)
endif()

message(STATUS "Setting up vcpkg binary caching with read-only access to GitHub Packages NuGet source")

execute_process(
COMMAND "${COMMAND_PREFIX}vcpkg${EXE_SUFFIX}" fetch nuget
WORKING_DIRECTORY ${VCPKG_ROOT}
OUTPUT_VARIABLE NUGET_FETCH_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "\n" ";" NUGET_FETCH_OUTPUT "${NUGET_FETCH_OUTPUT}")
list(POP_BACK NUGET_FETCH_OUTPUT NUGET_EXECUTABLE)

# NuGet will fail with an error when trying to add a source with the same name
# as one that already exists, so check that the NuGet source has not been added yet.
execute_process(
COMMAND ${DOTNET_RUNTIME} ${NUGET_EXECUTABLE} sources list
OUTPUT_VARIABLE NUGET_SOURCES_LIST
)
string(FIND "${NUGET_SOURCES_LIST}" "cxx-qt-github-packages" SEARCH_RESULT)
if(SEARCH_RESULT EQUAL -1)
# GitHub will deactivate a personal access token that gets committed to the repository.
# Hack around this by splitting up the PAT.
# This is safe because this PAT only has read:packages permission.
# TODO: create read-only personal access token for KDAB
set(GITHUB_PAT_READ_PACKAGES_SUFFIX DX2hOAAmXO4JGuT4WK5LQLBIGLSAdo13PDC1)
execute_process(
COMMAND ${DOTNET_RUNTIME} ${NUGET_EXECUTABLE} sources add
-name cxx-qt-github-packages
-source https://nuget.pkg.github.com/Be-ing/index.json
-username Be-ing
-password ghp_${GITHUB_PAT_READ_PACKAGES_SUFFIX}
)
endif()

set(ENV{VCPKG_BINARY_SOURCES} "clear;default,readwrite;nuget,cxx-qt-github-packages,read;")
endif()
else()
message(STATUS "Using dependencies from system without vcpkg")
endif()

project(cxx_qt)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(CompilerCaching)

# Enable extra Qt definitions for all projects
add_compile_definitions(
QT_NO_CAST_FROM_ASCII
Expand Down
7 changes: 7 additions & 0 deletions LICENSES/BSD-3-Clause.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ Ensure that you have the following installed
In a cxx-qt project, the build system is based on CMake, which uses Cargo under the hood.
Therefore, unlike a typical Rust project, CMake must be used to build cxx-qt.

On Windows and macOS, cxx-qt defaults to installing Qt from vcpkg. Prebuilt packages are
automatically downloaded from GitHub Packages (this will take several minutes the first time
you run CMake). If you already have Qt installed, you can disable this by adding
`-D VCPKG=OFF` to the CMake configure step (the first call to `cmake`).

cxx-qt defaults to building with Qt6. If you want to build with Qt5 when both are installed,
or you want to tell vcpkg to use Qt5, add `-D QT_DEFAULT_MAJOR_VERSION=5` to the CMake
configure step.

```bash
mkdir build/
cd build/
Expand Down
2 changes: 1 addition & 1 deletion clang_format_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function clang_format_files() {
if ! git check-ignore -q "$file"; then
clang-format --dry-run -Werror "$file"
fi
done < <(find "$DIR" -type f -name "$1" -a -not -path './.git/*' -print0)
done < <(find "$DIR" -type f -name "$1" -a -not -path "$DIR/.git/*" -not -path "$DIR/vcpkg/*" -not -path "$DIR/*/vcpkg_installed/*" -print0)
}

clang_format_files "*.cpp"
Expand Down
Loading