Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Jan 12, 2025
1 parent 0450da0 commit 4bb005d
Show file tree
Hide file tree
Showing 15 changed files with 283 additions and 0 deletions.
89 changes: 89 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Linux

on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 1 * *' # build at least once a month

env:
artifactPackage: CppBuildPackQt-x86_64.AppImage
qtVersion: 6.8.1

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
BuildType: [Debug, Release]
steps:
- name: Install System Packages
run: |
sudo apt update
sudo apt install libvulkan-dev
- name: Install Cmake
uses: lukka/get-cmake@latest
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: ${{ env.qtVersion }}
host: linux
target: desktop
arch: linux_gcc_64
dir: ${{ runner.temp }}
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Configure
run: cmake --fresh -S . -B build/${{ matrix.BuildType }} -DCMAKE_BUILD_TYPE=${{ matrix.BuildType }}
- name: Build
run: cmake --build build/${{ matrix.BuildType }} --target all --config ${{matrix.BuildType}}
- name: Package
run: NO_STRIP=true DESTDIR=${{ github.workspace }}/build/${{ matrix.BuildType }}/AppDir/ cmake --build build/${{ matrix.BuildType }} --target install
- name: Cache Artifact
uses: actions/cache@v4
with:
path: ./build/${{ matrix.BuildType }}/
key: ${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.BuildType }}
- name: Upload Package
uses: actions/upload-artifact@v4
with:
name: Package-${{ matrix.BuildType }}
path: ./build/${{ matrix.BuildType }}/${{ env.artifactPackage }}

test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Install Cmake
uses: lukka/get-cmake@latest
- name: Get Cached Artifact
uses: actions/cache@v4
with:
path: ./build/Debug/
key: ${{ github.run_id }}-${{ github.run_attempt }}-Debug
- name: Test
run: ctest --test-dir build/Debug --output-on-failure --verbose

release:
needs: test
if: needs.test.result == 'success' && github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Get Cached Artifact
uses: actions/cache@v4
with:
path: ./build/Release/
key: ${{ github.run_id }}-${{ github.run_attempt }}-Release
- name: Create Version Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: build/Release/${{ env.artifactPackage }}
- name: Create Continuous Release
uses: softprops/action-gh-release@v2
with:
files: build/Release/${{ env.artifactPackage }}
tag_name: continuous-build
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
build_docker/
90 changes: 90 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
cmake_minimum_required(VERSION 3.24)

### SETUP
project(CppBuildPackQt
VERSION 1.0
HOMEPAGE_URL "https://github.com/xyz"
DESCRIPTION "My template for applications built with cmake"
LANGUAGES CXX)

find_package(Qt6
REQUIRED COMPONENTS
Core
Gui
Quick
Qml
)
qt_standard_project_setup(REQUIRES 6.5)
qt_policy(SET QTP0004 NEW)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

## TARGETS
qt_add_executable(${CMAKE_PROJECT_NAME})
add_subdirectory(src/)

target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Gui Qt6::Quick Qt6::Qml)

### TEST
if(CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
NDEBUG
QT_NO_DEBUG
QT_NO_DEBUG_OUTPUT
)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
enable_testing()
add_subdirectory(test/)
endif()

### INSTALL
include(GNUInstallDirs)
include(InstallRequiredSystemLibraries)

install(
TARGETS ${CMAKE_PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
BUNDLE DESTINATION .
)

qt_generate_deploy_qml_app_script(
TARGET ${CMAKE_PROJECT_NAME}
OUTPUT_SCRIPT deploy_script
MACOS_BUNDLE_POST_BUILD
NO_UNSUPPORTED_PLATFORM_ERROR
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
)
install(SCRIPT ${deploy_script})


if(LINUX)
configure_file(
${CMAKE_SOURCE_DIR}/pack/linux/${CMAKE_PROJECT_NAME}.desktop.in
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.desktop
@ONLY
)
install(
FILES ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications/
)
configure_file(
${CMAKE_SOURCE_DIR}/pack/linux/appimage/AppRun.in
${CMAKE_BINARY_DIR}/AppRun
@ONLY
)
install(
FILES ${CMAKE_SOURCE_DIR}/res/icons/appicon.png
DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps/
RENAME icon.png
)
set(CMAKE_INSTALL_PREFIX "/usr")
install(SCRIPT "${CMAKE_SOURCE_DIR}/cmake/CreateAppImage.cmake")
endif()
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# CppBuildPackQt

This is a minimal template project to build a [QtQuick](https://wiki.qt.io/Qt_Quick) / C++ application in a modern build and package environment. For now, only Linux is supported, but more platforms might be added when a contributer requires them. For Linux, the application is then packaged as a portable [AppImage](https://appimage.org/).

## Build and package
### Linux
To build and package, simply run in the project root directory:
1. `cmake -S . -B build`
2. `cmake --build build --target all`
3. `NO_STRIP=true DESTDIR=${PWD}/build/AppDir/ cmake --build build --target install`

For more realistic projects the list fo dependencies will become more complex, so may want to setup a ci/cd pipeline or create a docker image to build and package in. This simple example can be built with an existing docker image:
1. `docker run --rm -v ${PWD}:/project danger89/cmake:latest sh -c "cd /project && cmake -S . -B build_docker && cmake --build build_docker --target all && NO_STRIP=true DESTDIR=/project/build/AppDir/ cmake --build build_docker --target install"`

A ci/cd workflow for github is also added for the example.
8 changes: 8 additions & 0 deletions cmake/CPackSourceConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES
\\.git/
build/
".*~$"
)
set(CPACK_VERBATIM_VARIABLES YES)
include(CPack)
18 changes: 18 additions & 0 deletions cmake/CreateAppImage.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
message(STATUS "Creating AppImage")

set(APPDIR_PATH "${CMAKE_BINARY_DIR}/AppDir")
set(LINUXDEPLOY_PATH "${CMAKE_BINARY_DIR}/linuxdeploy-x86_64.AppImage")

if(NOT EXISTS "${LINUXDEPLOY_PATH}")
file(DOWNLOAD https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage "${LINUXDEPLOY_PATH}")
execute_process(COMMAND chmod a+x "${LINUXDEPLOY_PATH}")
endif()

execute_process(COMMAND ${LINUXDEPLOY_PATH}
--appimage-extract-and-run #workaround to execute in docker container
--appdir ${APPDIR_PATH}
--executable ${APPDIR_PATH}/usr/bin/CppBuildPackQt
--desktop-file ${APPDIR_PATH}/usr/share/applications/CppBuildPackQt.desktop
--custom-apprun ${CMAKE_BINARY_DIR}/AppRun
--output appimage
)
8 changes: 8 additions & 0 deletions pack/linux/CppBuildPackQt.desktop.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Version=@CMAKE_PROJECT_VERSION@
Name=@CMAKE_PROJECT_NAME@
Comment=@CMAKE_PROJECT_DESCRIPTION@
Exec=@CMAKE_PROJECT_NAME@
Icon=icon
Categories=Utility
11 changes: 11 additions & 0 deletions pack/linux/appimage/AppRun.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

if [ -z "$APPDIR" ]; then
APPDIR="$(dirname "$(readlink -f "$0")")"
fi

export QT_QPA_PLATFORM="xcb"
#export QT_QPA_PLATFORM=wayland

exec "${APPDIR}/usr/bin/@CMAKE_PROJECT_NAME@" "$@"

Binary file added res/icons/appicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
main.cpp
qml.qrc
)
12 changes: 12 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char** argv)
{
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();
}
9 changes: 9 additions & 0 deletions src/main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import QtQuick
import QtQuick.Window

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
}
5 changes: 5 additions & 0 deletions src/qml.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
5 changes: 5 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include(CTest)

add_executable(myTest test.cpp)

add_test(NAME myTest COMMAND myTest)
7 changes: 7 additions & 0 deletions test/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <iostream>

int main()
{
std::cout << "Hello Test!" << std::endl;
return 0;
}

0 comments on commit 4bb005d

Please sign in to comment.