Packaging: containerised CI, Flatpak/AppImage, bundled simd, licence notices, and release-please (#53)
This commit is contained in:
+403
-18
@@ -3,31 +3,84 @@ name: Make Packages
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags: [ "*" ]
|
tags: [ "*" ]
|
||||||
|
workflow_dispatch: {}
|
||||||
|
# Called by release-please.yml once it has cut a release. A tag pushed by
|
||||||
|
# release-please carries the default GITHUB_TOKEN, and GitHub deliberately
|
||||||
|
# refuses to start a workflow from an event that token created -- so the
|
||||||
|
# `push: tags` trigger above never fires for a release-please tag. Being
|
||||||
|
# callable means the release build runs inside release-please's own run
|
||||||
|
# instead, with no personal access token to store on a public repo.
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
description: >-
|
||||||
|
Tag release-please just created. Supplies the package version and
|
||||||
|
names the release to upload to, both of which would otherwise come
|
||||||
|
from github.ref_name.
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-monocoque-debs:
|
build-monocoque-debs:
|
||||||
|
# Previously this matrix used `runs-on: ${{ matrix.os }}` with
|
||||||
|
# debian-latest/debian-stable as runner *labels*, which only resolve to
|
||||||
|
# self-hosted runners. With none online those two legs sat queued
|
||||||
|
# indefinitely (observed: four runs stuck 17-60min, only the
|
||||||
|
# ubuntu-latest leg ever completing) until cancelled by hand. Building
|
||||||
|
# each distro in a container on ordinary GitHub-hosted runners removes
|
||||||
|
# the self-hosted dependency entirely.
|
||||||
|
#
|
||||||
|
# matrix.os stays the distro *name* because it's load-bearing: it picks
|
||||||
|
# the per-distro control file under tools/distro/debian/dpkg/<os>/ and
|
||||||
|
# names the released .deb. matrix.image is what it actually builds in.
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, debian-latest, debian-stable]
|
include:
|
||||||
runs-on: ${{ matrix.os }}
|
- os: ubuntu-latest
|
||||||
|
image: ubuntu:latest
|
||||||
|
- os: debian-latest
|
||||||
|
image: debian:testing
|
||||||
|
- os: debian-stable
|
||||||
|
image: debian:stable-slim
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ matrix.image }}
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
# Must come before actions/checkout: these images are minimal and ship
|
||||||
- name: Checkout submodules
|
# no git, so checkout would fall back to a tarball download and silently
|
||||||
run: git submodule update --init --recursive
|
# skip submodules -- simapi and nappgui_src are both required to build.
|
||||||
- name: Update apt
|
# No sudo either; container jobs already run as root.
|
||||||
run: sudo apt update
|
- name: Install build dependencies
|
||||||
- name: Install Dependencies
|
run: |
|
||||||
run: sudo apt install -y libgtk-3-dev libuv1-dev libargtable2-dev libserialport-dev libconfig-dev libhidapi-dev liblua5.4-dev libxdg-basedir-dev libxml2-dev libpulse-dev libproc2-dev libcurl4-openssl-dev libglu1-mesa-dev
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates curl git \
|
||||||
|
build-essential cmake pkg-config \
|
||||||
|
libgtk-3-dev libuv1-dev libargtable2-dev libserialport-dev \
|
||||||
|
libconfig-dev libhidapi-dev liblua5.4-dev libxdg-basedir-dev \
|
||||||
|
libxml2-dev libpulse-dev libproc2-dev libcurl4-openssl-dev \
|
||||||
|
libglu1-mesa-dev
|
||||||
|
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# $GITHUB_WORKSPACE, not ${{ github.workspace }}: in a container job the
|
||||||
|
# expression still renders the *host* path (/home/runner/work/...) while
|
||||||
|
# the repo is actually mounted at /__w/... inside the container. Using
|
||||||
|
# the expression made cmake fail with `The source directory
|
||||||
|
# "/home/runner/work/monocoque/monocoque" does not exist`. The env var is
|
||||||
|
# set to the container-side path, so it's correct either way.
|
||||||
- name: Set build dir
|
- name: Set build dir
|
||||||
id: strings
|
id: strings
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
|
echo "build-output-dir=$GITHUB_WORKSPACE/build" >> "$GITHUB_OUTPUT"
|
||||||
github_sha_hash=${{ github.sha }}
|
github_sha_hash=${{ github.sha }}
|
||||||
echo "github-sha-short=${github_sha_hash:0:7}" >> $GITHUB_OUTPUT
|
echo "github-sha-short=${github_sha_hash:0:7}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
@@ -38,7 +91,7 @@ jobs:
|
|||||||
-DCMAKE_CXX_COMPILER=g++
|
-DCMAKE_CXX_COMPILER=g++
|
||||||
-DCMAKE_C_COMPILER=gcc
|
-DCMAKE_C_COMPILER=gcc
|
||||||
-DCMAKE_BUILD_TYPE=Release
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
-S ${{ github.workspace }}
|
-S "$GITHUB_WORKSPACE"
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release
|
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release
|
||||||
@@ -51,48 +104,380 @@ jobs:
|
|||||||
mkdir -p PKG_SOURCE/usr/share/applications
|
mkdir -p PKG_SOURCE/usr/share/applications
|
||||||
mkdir -p PKG_SOURCE/usr/share/pixmaps
|
mkdir -p PKG_SOURCE/usr/share/pixmaps
|
||||||
mkdir -p PKG_SOURCE/usr/share/icons/hicolor/scalable/apps
|
mkdir -p PKG_SOURCE/usr/share/icons/hicolor/scalable/apps
|
||||||
|
mkdir -p PKG_SOURCE/usr/share/monocoque
|
||||||
- name: Download xpm icon
|
- name: Download xpm icon
|
||||||
run: |
|
run: |
|
||||||
curl -sSL https://repo.spacefreak18.xyz/monocoque/icons/monocoque.xpm -o PKG_SOURCE/usr/share/pixmaps/monocoque.xpm
|
curl -sSL https://repo.spacefreak18.xyz/monocoque/icons/monocoque.xpm -o PKG_SOURCE/usr/share/pixmaps/monocoque.xpm
|
||||||
- name: Download svg icon
|
- name: Download svg icon
|
||||||
run: |
|
run: |
|
||||||
curl -sSL https://repo.spacefreak18.xyz/monocoque/icons/monocoque.svg -o PKG_SOURCE/usr/share/icons/hicolor/scalable/apps/monocoque.svg
|
curl -sSL https://repo.spacefreak18.xyz/monocoque/icons/monocoque.svg -o PKG_SOURCE/usr/share/icons/hicolor/scalable/apps/monocoque.svg
|
||||||
|
- name: Determine package version
|
||||||
|
id: pkgver
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
RELEASE_TAG: ${{ inputs.release_tag }}
|
||||||
|
run: |
|
||||||
|
# The control files carry a hardcoded `Version: 1` that nobody
|
||||||
|
# maintains, so every .deb ever released claims version 1 regardless
|
||||||
|
# of its tag. Take the version from the tag instead.
|
||||||
|
#
|
||||||
|
# Guarded rather than used blindly: a Debian version must start with a
|
||||||
|
# digit, so a branch build (workflow_dispatch) or a non-release tag
|
||||||
|
# like `pkgtest-5` would make dpkg-deb fail outright. Anything that
|
||||||
|
# doesn't look like a version falls back to 0.0.0.
|
||||||
|
v=""
|
||||||
|
# RELEASE_TAG is set only when release-please calls this workflow;
|
||||||
|
# its tag exists but the run itself is on a branch, so GITHUB_REF_*
|
||||||
|
# would report master and fall through to 0.0.0.
|
||||||
|
v="${RELEASE_TAG#v}"
|
||||||
|
[ -z "$v" ] && [ "$GITHUB_REF_TYPE" = tag ] && v="${GITHUB_REF_NAME#v}"
|
||||||
|
case "$v" in
|
||||||
|
[0-9]*) ;;
|
||||||
|
*) v="0.0.0" ;;
|
||||||
|
esac
|
||||||
|
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "packaging as version $v"
|
||||||
|
|
||||||
- name: Copy script files around to stop .github from being added to the package then build the package
|
- name: Copy script files around to stop .github from being added to the package then build the package
|
||||||
run: |
|
run: |
|
||||||
cp ./tools/distro/debian/dpkg/${{ matrix.os }}/control ./PKG_SOURCE/DEBIAN/control
|
cp ./tools/distro/debian/dpkg/${{ matrix.os }}/control ./PKG_SOURCE/DEBIAN/control
|
||||||
|
sed -i "s/^Version:.*/Version: ${{ steps.pkgver.outputs.version }}/" ./PKG_SOURCE/DEBIAN/control
|
||||||
cp ./tools/distro/debian/dpkg/copyright ./PKG_SOURCE/DEBIAN/copyright
|
cp ./tools/distro/debian/dpkg/copyright ./PKG_SOURCE/DEBIAN/copyright
|
||||||
cp ./build/monocoque ./PKG_SOURCE/usr/bin/monocoque
|
cp ./build/monocoque ./PKG_SOURCE/usr/bin/monocoque
|
||||||
cp ./build/gmonocoque ./PKG_SOURCE/usr/bin/gmonocoque
|
cp ./build/gmonocoque ./PKG_SOURCE/usr/bin/gmonocoque
|
||||||
cp ./tools/monocoque.desktop ./PKG_SOURCE/usr/share/applications/monocoque.desktop
|
cp ./tools/monocoque.desktop ./PKG_SOURCE/usr/share/applications/monocoque.desktop
|
||||||
dpkg-deb --build PKG_SOURCE monocoque-${{ matrix.os }}.deb
|
dpkg-deb --build PKG_SOURCE monocoque-${{ matrix.os }}.deb
|
||||||
|
echo "--- control as packaged ---"
|
||||||
|
dpkg-deb --field monocoque-${{ matrix.os }}.deb Package Version
|
||||||
|
|
||||||
- name: Release the Package
|
- name: Release the Package
|
||||||
|
# Only a tag can publish a release; without this a workflow_dispatch run
|
||||||
|
# builds everything correctly and then reports failure on a step that
|
||||||
|
# cannot work, which makes a green build look broken.
|
||||||
|
if: github.ref_type == 'tag' || inputs.release_tag != ''
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
|
tag_name: ${{ inputs.release_tag || github.ref_name }}
|
||||||
files: monocoque-${{ matrix.os }}.deb
|
files: monocoque-${{ matrix.os }}.deb
|
||||||
|
# release-please writes the release body from the changelog it just
|
||||||
|
# generated. Letting this action generate its own notes as well would
|
||||||
|
# overwrite them, so it only does so for a hand-pushed tag.
|
||||||
|
generate_release_notes: ${{ inputs.release_tag == '' }}
|
||||||
|
|
||||||
|
|
||||||
build-monocoque-rpms:
|
build-monocoque-rpms:
|
||||||
|
# Same self-hosted-label problem as the deb jobs above (fedora-43 was a
|
||||||
|
# runner label with nothing online to claim it); now a container on an
|
||||||
|
# ordinary GitHub-hosted runner, with fedora-44 added alongside 43.
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [fedora-43]
|
include:
|
||||||
runs-on: ${{ matrix.os }}
|
- os: fedora-43
|
||||||
|
image: fedora:43
|
||||||
|
- os: fedora-44
|
||||||
|
image: fedora:44
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ matrix.image }}
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
|
# The -devel list is the one fedora.spec's own header comment documents,
|
||||||
|
# plus gtk3/libcurl/mesa-libGLU to match its `Requires:` line -- the spec
|
||||||
|
# configures with -DBUILD_GUI=on, so the GUI's deps are build deps too.
|
||||||
|
#
|
||||||
|
# Retried because this pulls openh264 from Fedora's third-party Cisco
|
||||||
|
# repo (ciscobinary.openh264.org), which is a single-mirror CDN outside
|
||||||
|
# Fedora's own infrastructure and has proven flaky: the fedora-43 leg of
|
||||||
|
# the first run died on `Curl error (7): Could not connect to server`
|
||||||
|
# for it while fedora-44 downloaded the very same package fine in the
|
||||||
|
# same run -- i.e. transient, not a dependency or package-name problem.
|
||||||
|
# Not disabling that repo outright: openh264 is still pulled in even
|
||||||
|
# with weak deps off, so something here requires it outright (which
|
||||||
|
# package wasn't traced) and dropping the repo would likely break
|
||||||
|
# dependency resolution rather than fix anything.
|
||||||
|
- name: Install build dependencies
|
||||||
|
run: |
|
||||||
|
for attempt in 1 2 3; do
|
||||||
|
dnf install -y --setopt=install_weak_deps=False \
|
||||||
|
rpm-build cmake gcc gcc-c++ make git curl \
|
||||||
|
pulseaudio-libs-devel argtable-devel libconfig-devel hidapi-devel \
|
||||||
|
libserialport-devel lua-devel libuv-devel libxdg-basedir-devel \
|
||||||
|
libxml2-devel procps-ng-devel gtk3-devel libcurl-devel \
|
||||||
|
mesa-libGLU-devel && exit 0
|
||||||
|
echo "dnf install failed (attempt $attempt), retrying in 15s..."
|
||||||
|
sleep 15
|
||||||
|
done
|
||||||
|
echo "dnf install failed after 3 attempts" >&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
# submodules: recursive is new here. It didn't matter while %prep cloned
|
||||||
|
# upstream and ran `git submodule update` itself; now that the staged
|
||||||
|
# checkout is what gets built, an empty nappgui_src fails configure with
|
||||||
|
# "does not contain a CMakeLists.txt file". Missed by the local fedora:44
|
||||||
|
# rehearsal, which mounted a working tree that already had its submodules.
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
- name: create rpmbuild dirs
|
- name: create rpmbuild dirs
|
||||||
run: mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
run: mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
||||||
- name: get spec file
|
|
||||||
run: curl -o ~/fedora.spec https://raw.githubusercontent.com/Spacefreak18/monocoque/refs/heads/master/tools/distro/fedora/rpm/fedora.spec
|
# The spec's %prep used to `git clone` upstream master, so the rpm's
|
||||||
|
# contents tracked master rather than the tag being built -- an rpm built
|
||||||
|
# from a tag would quietly ship master's code. Staged here and copied by
|
||||||
|
# %prep instead, so a package's contents are the commit it was built from.
|
||||||
|
- name: Stage the checked-out tree as the rpm source
|
||||||
|
run: |
|
||||||
|
rm -rf ~/rpmbuild/SOURCES/monocoque
|
||||||
|
cp -r "$GITHUB_WORKSPACE" ~/rpmbuild/SOURCES/monocoque
|
||||||
|
rm -rf ~/rpmbuild/SOURCES/monocoque/.github
|
||||||
|
|
||||||
|
# Uses the spec from the checked-out tree instead of curl'ing it from
|
||||||
|
# upstream's master branch, so a tag builds the spec that tag contains.
|
||||||
|
#
|
||||||
|
# The spec's `Version: 0.0.5` is stale and hand-maintained -- real tags are
|
||||||
|
# well past it, so released rpms have been installing as monocoque-0.0.5.
|
||||||
|
# Stamped from the tag here rather than edited in the spec, so the file
|
||||||
|
# stays a working default for local rpmbuild while CI releases carry the
|
||||||
|
# real version. Same digit guard as the deb job: rpm versions can't start
|
||||||
|
# with a non-digit, and scratch tags / branch builds would break it.
|
||||||
|
#
|
||||||
|
# NOTE (pre-existing, deliberately not fixed here): the spec's own %prep
|
||||||
|
# still does a fresh `git clone` of upstream master for the *sources*,
|
||||||
|
# so the rpm's contents track master rather than the tag being built.
|
||||||
|
# Worth fixing separately -- it needs the spec parameterised, which is a
|
||||||
|
# bigger change than getting these jobs running again.
|
||||||
- name: run spec file
|
- name: run spec file
|
||||||
run: rpmbuild -ba ~/fedora.spec
|
shell: bash
|
||||||
|
env:
|
||||||
|
RELEASE_TAG: ${{ inputs.release_tag }}
|
||||||
|
run: |
|
||||||
|
v=""
|
||||||
|
# RELEASE_TAG is set only when release-please calls this workflow;
|
||||||
|
# its tag exists but the run itself is on a branch, so GITHUB_REF_*
|
||||||
|
# would report master and fall through to 0.0.0.
|
||||||
|
v="${RELEASE_TAG#v}"
|
||||||
|
[ -z "$v" ] && [ "$GITHUB_REF_TYPE" = tag ] && v="${GITHUB_REF_NAME#v}"
|
||||||
|
case "$v" in
|
||||||
|
[0-9]*) ;;
|
||||||
|
*) v="0.0.0" ;;
|
||||||
|
esac
|
||||||
|
echo "packaging as version $v"
|
||||||
|
sed -i "s/^Version:.*/Version: $v/" tools/distro/fedora/rpm/fedora.spec
|
||||||
|
rpmbuild -ba tools/distro/fedora/rpm/fedora.spec
|
||||||
|
|
||||||
|
# Glob rather than a hardcoded monocoque-0.0.5-1.x86_64.rpm: the filename
|
||||||
|
# tracks the spec's Version/Release, which is now stamped per-tag above.
|
||||||
- name: rename file
|
- name: rename file
|
||||||
run: cp ~/rpmbuild/RPMS/x86_64/monocoque-0.0.5-1.x86_64.rpm $GITHUB_WORKSPACE/monocoque-${{ matrix.os }}.rpm
|
run: |
|
||||||
|
cp ~/rpmbuild/RPMS/x86_64/monocoque-*.rpm "$GITHUB_WORKSPACE/monocoque-${{ matrix.os }}.rpm"
|
||||||
|
echo "--- rpm identity as built ---"
|
||||||
|
rpm -qp --qf '%{NAME} %{VERSION}-%{RELEASE}\n' "$GITHUB_WORKSPACE/monocoque-${{ matrix.os }}.rpm"
|
||||||
|
|
||||||
- name: Release the Package
|
- name: Release the Package
|
||||||
|
# Only a tag can publish a release; without this a workflow_dispatch run
|
||||||
|
# builds everything correctly and then reports failure on a step that
|
||||||
|
# cannot work, which makes a green build look broken.
|
||||||
|
if: github.ref_type == 'tag' || inputs.release_tag != ''
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
|
tag_name: ${{ inputs.release_tag || github.ref_name }}
|
||||||
files: monocoque-${{ matrix.os }}.rpm
|
files: monocoque-${{ matrix.os }}.rpm
|
||||||
|
# release-please writes the release body from the changelog it just
|
||||||
|
# generated. Letting this action generate its own notes as well would
|
||||||
|
# overwrite them, so it only does so for a hand-pushed tag.
|
||||||
|
generate_release_notes: ${{ inputs.release_tag == '' }}
|
||||||
|
|
||||||
|
|
||||||
|
build-monocoque-appimage:
|
||||||
|
# An AppImage only runs where glibc is at least as new as the one it
|
||||||
|
# linked against, so it wants the OLDEST base that can build the code --
|
||||||
|
# building on current Ubuntu silently excludes older distros and defeats
|
||||||
|
# the point of shipping one.
|
||||||
|
#
|
||||||
|
# That floor is set by the compiler, not by choice: simapi's F1 2018
|
||||||
|
# headers use C23 enum-with-fixed-underlying-type (`enum TrackID :
|
||||||
|
# uint8_t`), which GCC only implements from 13 onwards. ubuntu-22.04
|
||||||
|
# ships GCC 11 and fails outright with `expected identifier or '(' before
|
||||||
|
# ':' token` -- confirmed by a real run, and no -std= value rescues it
|
||||||
|
# (verified separately: the construct is gated on compiler version, not
|
||||||
|
# on the standard flag). ubuntu-24.04 / GCC 13 is therefore the oldest
|
||||||
|
# usable base, giving a glibc 2.39 floor.
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# librsvg2-common and libgtk-3-bin are for linuxdeploy's gtk plugin, not
|
||||||
|
# the build itself -- it needs an svg pixbuf loader and
|
||||||
|
# gtk-update-icon-cache to assemble a self-contained GTK runtime.
|
||||||
|
- name: Install build dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends \
|
||||||
|
build-essential cmake pkg-config \
|
||||||
|
libgtk-3-dev libuv1-dev libargtable2-dev libserialport-dev \
|
||||||
|
libconfig-dev libhidapi-dev liblua5.4-dev libxdg-basedir-dev \
|
||||||
|
libxml2-dev libpulse-dev libproc2-dev libcurl4-openssl-dev \
|
||||||
|
libglu1-mesa-dev \
|
||||||
|
desktop-file-utils file patchelf wget \
|
||||||
|
librsvg2-common libgtk-3-bin
|
||||||
|
|
||||||
|
# -std=gnu2x for the C23 enum syntax above: GCC 13 implements it but
|
||||||
|
# still defaults to gnu17, unlike GCC 15+ (which the container-based
|
||||||
|
# deb/rpm legs get, and which accept it without the flag). gnu2x rather
|
||||||
|
# than c2x so GNU extensions stay on -- simapi also relies on asprintf.
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake -B build -DBUILD_GUI=on -DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_C_FLAGS=-std=gnu2x -S .
|
||||||
|
cmake --build build --config Release
|
||||||
|
|
||||||
|
# Uses the install() rules rather than hand-copying binaries the way the
|
||||||
|
# deb job does -- that's what they were added for.
|
||||||
|
- name: Populate AppDir
|
||||||
|
run: |
|
||||||
|
DESTDIR="$PWD/AppDir" cmake --install build --prefix /usr
|
||||||
|
# Icon basename must match the desktop file's `Icon=monocoque`.
|
||||||
|
# tools/monocoque.svg is the square copy shared with the Flatpak
|
||||||
|
# build; the published 100x50 artwork is rejected by icon tooling.
|
||||||
|
install -Dm644 tools/monocoque.svg \
|
||||||
|
AppDir/usr/share/icons/hicolor/scalable/apps/monocoque.svg
|
||||||
|
|
||||||
|
# APPIMAGE_EXTRACT_AND_RUN=1 because these tools are themselves
|
||||||
|
# AppImages and there is no FUSE on the runner to mount them with.
|
||||||
|
- name: Build AppImage
|
||||||
|
env:
|
||||||
|
APPIMAGE_EXTRACT_AND_RUN: 1
|
||||||
|
RELEASE_TAG: ${{ inputs.release_tag }}
|
||||||
|
run: |
|
||||||
|
# An AppImage carries no package metadata, so its filename is the only
|
||||||
|
# place a version can live -- hence versioning the output name here
|
||||||
|
# rather than stamping a field as the deb/rpm jobs do. Same digit
|
||||||
|
# guard, so scratch tags and branch builds still produce a valid name.
|
||||||
|
v=""
|
||||||
|
# RELEASE_TAG is set only when release-please calls this workflow;
|
||||||
|
# its tag exists but the run itself is on a branch, so GITHUB_REF_*
|
||||||
|
# would report master and fall through to 0.0.0.
|
||||||
|
v="${RELEASE_TAG#v}"
|
||||||
|
[ -z "$v" ] && [ "$GITHUB_REF_TYPE" = tag ] && v="${GITHUB_REF_NAME#v}"
|
||||||
|
case "$v" in
|
||||||
|
[0-9]*) ;;
|
||||||
|
*) v="0.0.0" ;;
|
||||||
|
esac
|
||||||
|
export OUTPUT="monocoque-${v}-x86_64.AppImage"
|
||||||
|
echo "packaging as $OUTPUT"
|
||||||
|
|
||||||
|
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||||
|
wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-gtk/raw/master/linuxdeploy-plugin-gtk.sh
|
||||||
|
chmod +x linuxdeploy-x86_64.AppImage linuxdeploy-plugin-gtk.sh
|
||||||
|
|
||||||
|
# Deploy dependencies first, without packaging, so there is a populated
|
||||||
|
# AppDir to take licences from -- an AppImage distributes every library
|
||||||
|
# it bundles, so their copyright files have to travel with it. A .deb
|
||||||
|
# needs none of this because its dependencies stay separate packages.
|
||||||
|
PATH="$PWD:$PATH" ./linuxdeploy-x86_64.AppImage \
|
||||||
|
--appdir AppDir \
|
||||||
|
--plugin gtk \
|
||||||
|
--desktop-file AppDir/usr/share/applications/monocoque.desktop \
|
||||||
|
--icon-file tools/monocoque.svg
|
||||||
|
|
||||||
|
tools/appimage-collect-licenses.sh AppDir
|
||||||
|
|
||||||
|
# monocoque itself and its vendored components are built here rather
|
||||||
|
# than installed from packages, so dpkg cannot account for them.
|
||||||
|
install -Dm644 LICENSE.rst AppDir/usr/share/doc/monocoque/LICENSE.rst
|
||||||
|
install -Dm644 tools/distro/debian/dpkg/copyright AppDir/usr/share/doc/monocoque/copyright
|
||||||
|
install -Dm644 src/monocoque/mgui/nappgui_src/LICENSE AppDir/usr/share/doc/nappgui/LICENSE
|
||||||
|
|
||||||
|
# Now package the AppDir, licences included.
|
||||||
|
PATH="$PWD:$PATH" ./linuxdeploy-x86_64.AppImage \
|
||||||
|
--appdir AppDir \
|
||||||
|
--output appimage
|
||||||
|
ls -la monocoque*.AppImage
|
||||||
|
echo "--- licence files in the image ---"
|
||||||
|
find AppDir/usr/share/doc -name copyright | wc -l
|
||||||
|
|
||||||
|
- name: Upload the AppImage as a build artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: monocoque-x86_64.AppImage
|
||||||
|
path: monocoque*.AppImage
|
||||||
|
|
||||||
|
- name: Release the Package
|
||||||
|
# Only a tag can publish a release; without this a workflow_dispatch run
|
||||||
|
# builds everything correctly and then reports failure on a step that
|
||||||
|
# cannot work, which makes a green build look broken.
|
||||||
|
if: github.ref_type == 'tag' || inputs.release_tag != ''
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
tag_name: ${{ inputs.release_tag || github.ref_name }}
|
||||||
|
files: monocoque*.AppImage
|
||||||
|
# release-please writes the release body from the changelog it just
|
||||||
|
# generated. Letting this action generate its own notes as well would
|
||||||
|
# overwrite them, so it only does so for a hand-pushed tag.
|
||||||
|
generate_release_notes: ${{ inputs.release_tag == '' }}
|
||||||
|
|
||||||
|
|
||||||
|
build-monocoque-flatpak:
|
||||||
|
# Folded in from the standalone flatpak.yml so every artifact lands on
|
||||||
|
# one release. Kept as continue-on-error because it is the newest and
|
||||||
|
# least battle-tested leg: a Flatpak failure must never turn a release
|
||||||
|
# red or block the deb/rpm/AppImage artifacts, which are independent
|
||||||
|
# jobs and upload regardless.
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
continue-on-error: true
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
# No submodules: recursive here -- the manifest fetches simapi and
|
||||||
|
# nappgui_src itself as explicit `type: git` sources (pinned commits,
|
||||||
|
# reproducible regardless of what's checked out on disk). Confirmed
|
||||||
|
# via a failed CI run: recursive submodule checkout populates those
|
||||||
|
# paths with real .git files first, which then collides with
|
||||||
|
# flatpak-builder's own git source trying to clone into the same spot
|
||||||
|
# ("cannot overwrite non-directory .git with directory").
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# ppa:flatpak/stable, not Ubuntu's own package: 22.04's flatpak-builder
|
||||||
|
# predates freedesktop Sdk 25.08 dropping the legacy appstream-compose
|
||||||
|
# binary in favour of `appstreamcli compose`, and fails at the finish
|
||||||
|
# stage without that fallback.
|
||||||
|
- name: Install flatpak-builder + freedesktop runtime/SDK
|
||||||
|
run: |
|
||||||
|
sudo add-apt-repository -y ppa:flatpak/stable
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y flatpak flatpak-builder
|
||||||
|
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
|
sudo flatpak install -y --noninteractive flathub org.freedesktop.Platform//25.08 org.freedesktop.Sdk//25.08
|
||||||
|
|
||||||
|
- name: Build .flatpak
|
||||||
|
working-directory: flatpak
|
||||||
|
run: |
|
||||||
|
flatpak-builder --force-clean --repo=repo build-dir io.github.spacefreak18.monocoque.yml
|
||||||
|
flatpak build-bundle repo monocoque.flatpak io.github.spacefreak18.monocoque
|
||||||
|
|
||||||
|
- name: Upload .flatpak as a build artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: monocoque.flatpak
|
||||||
|
path: flatpak/monocoque.flatpak
|
||||||
|
|
||||||
|
- name: Release the Package
|
||||||
|
if: github.ref_type == 'tag' || inputs.release_tag != ''
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
tag_name: ${{ inputs.release_tag || github.ref_name }}
|
||||||
|
files: flatpak/monocoque.flatpak
|
||||||
|
# release-please writes the release body from the changelog it just
|
||||||
|
# generated. Letting this action generate its own notes as well would
|
||||||
|
# overwrite them, so it only does so for a hand-pushed tag.
|
||||||
|
generate_release_notes: ${{ inputs.release_tag == '' }}
|
||||||
|
|
||||||
#arch-build:
|
#arch-build:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
name: PR Build & Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Checkout submodules
|
||||||
|
run: git submodule update --init --recursive
|
||||||
|
- name: Update apt
|
||||||
|
run: sudo apt update
|
||||||
|
- name: Install dependencies
|
||||||
|
# Same list as ci.yaml's ubuntu-latest leg, minus the GUI-only deps
|
||||||
|
# (libgtk-3-dev, libglu1-mesa-dev) and libcurl4-openssl-dev — this
|
||||||
|
# workflow builds the CLI + test suite only, not the GUI.
|
||||||
|
run: sudo apt install -y libuv1-dev libargtable2-dev libserialport-dev libconfig-dev libhidapi-dev liblua5.4-dev libxdg-basedir-dev libxml2-dev libpulse-dev libproc2-dev
|
||||||
|
- name: Configure CMake
|
||||||
|
run: cmake -B build -DENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --config Debug
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --test-dir build --output-on-failure
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
name: release-please
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-please:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
release_created: ${{ steps.release.outputs.release_created }}
|
||||||
|
tag_name: ${{ steps.release.outputs.tag_name }}
|
||||||
|
steps:
|
||||||
|
- uses: googleapis/release-please-action@v4
|
||||||
|
id: release
|
||||||
|
with:
|
||||||
|
config-file: release-please-config.json
|
||||||
|
manifest-file: .release-please-manifest.json
|
||||||
|
|
||||||
|
# Builds and uploads the packages for the release that was just cut.
|
||||||
|
#
|
||||||
|
# This calls ci.yaml rather than relying on its `push: tags` trigger,
|
||||||
|
# because a tag pushed with the default GITHUB_TOKEN does not start a new
|
||||||
|
# workflow -- GitHub blocks that deliberately, to stop workflows triggering
|
||||||
|
# each other in a loop. Calling it keeps the whole release inside one run
|
||||||
|
# and avoids storing a personal access token on a public repository.
|
||||||
|
build-release:
|
||||||
|
needs: release-please
|
||||||
|
if: needs.release-please.outputs.release_created == 'true'
|
||||||
|
uses: ./.github/workflows/ci.yaml
|
||||||
|
with:
|
||||||
|
release_tag: ${{ needs.release-please.outputs.tag_name }}
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
@@ -3,3 +3,12 @@
|
|||||||
/src/monocoque/simulatorapi/simapi
|
/src/monocoque/simulatorapi/simapi
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# flatpak-builder outputs from local builds -- CI regenerates these.
|
||||||
|
# flatpak/repo in particular is an OSTree store: ~1000 binary objects.
|
||||||
|
/flatpak/repo/
|
||||||
|
/flatpak/build-dir/
|
||||||
|
/flatpak/.flatpak-builder/
|
||||||
|
# The bundle itself. Missing from this list once already, and a `git add -A`
|
||||||
|
# duly committed a 6MB build artifact.
|
||||||
|
*.flatpak
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{ ".": "0.3.6" }
|
||||||
+17
-55
@@ -12,6 +12,7 @@ SET_SOURCE_FILES_PROPERTIES( src/monocoque.c PROPERTIES LANGUAGE C)
|
|||||||
|
|
||||||
option(BUILD_GUI "Build GUI support" OFF)
|
option(BUILD_GUI "Build GUI support" OFF)
|
||||||
option(BUILD_SHARED "Build monocoque shared library" OFF)
|
option(BUILD_SHARED "Build monocoque shared library" OFF)
|
||||||
|
option(ENABLE_TESTS "Build test suite" OFF)
|
||||||
|
|
||||||
|
|
||||||
project(monocoque)
|
project(monocoque)
|
||||||
@@ -72,9 +73,15 @@ pkg_check_modules(LIBPROC2 libproc2)
|
|||||||
if (LIBPROCPS_FOUND)
|
if (LIBPROCPS_FOUND)
|
||||||
#add_compile_definitions(USE_OLD_PID_VAL=0)
|
#add_compile_definitions(USE_OLD_PID_VAL=0)
|
||||||
elseif (LIBPROC2_FOUND)
|
elseif (LIBPROC2_FOUND)
|
||||||
if (LIBPROC2_VERSION VERSION_GREATER_EQUAL "4.0.5")
|
# Some distro packagings (e.g. the freedesktop Flatpak SDK) ship a
|
||||||
#add_compile_definitions(USE_OLD_PID_VAL=0)
|
# libproc2.pc with `Version: UNKNOWN` rather than a real version
|
||||||
else()
|
# string. VERSION_GREATER_EQUAL against that always evaluates false,
|
||||||
|
# silently falling through to the old (pre-4.0.5) PIDS_VAL API and
|
||||||
|
# failing to compile against an actually-current libproc2 whose real
|
||||||
|
# header has already moved to the new 3-argument macro. Only take the
|
||||||
|
# old-API branch when the version string is genuinely parseable and
|
||||||
|
# actually old.
|
||||||
|
if (LIBPROC2_VERSION MATCHES "^[0-9]" AND LIBPROC2_VERSION VERSION_LESS "4.0.5")
|
||||||
add_compile_definitions(USE_OLD_PID_VAL=1)
|
add_compile_definitions(USE_OLD_PID_VAL=1)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
@@ -107,57 +114,6 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#add_executable(listusb tests/testlibusb.c)
|
|
||||||
#target_include_directories(listusb PUBLIC)
|
|
||||||
#target_link_libraries(listusb portaudio hidapi-hidraw)
|
|
||||||
#add_test(listusb list-usb-devices listusb)
|
|
||||||
|
|
||||||
#add_executable(testrevburner tests/testrevburner.c)
|
|
||||||
#target_include_directories(testrevburner PUBLIC)
|
|
||||||
#target_link_libraries(testrevburner hidapi-hidraw)
|
|
||||||
#add_test(testrevburner testrevburner)
|
|
||||||
|
|
||||||
#add_executable(listsound tests/pa_devs.c)
|
|
||||||
#target_include_directories(listsound PUBLIC)
|
|
||||||
#target_link_libraries(listsound m portaudio)
|
|
||||||
#add_test(list-sound-devices listsound)
|
|
||||||
#
|
|
||||||
#add_executable(longsine tests/patest_longsine.c)
|
|
||||||
#target_include_directories(longsine PUBLIC ${LIBXML_INCLUDE_DIR})
|
|
||||||
#target_link_libraries(longsine m portaudio)
|
|
||||||
#add_test(longsine longsine)
|
|
||||||
#
|
|
||||||
#add_executable(parserevburnerxml tests/revburnerparsetest.c)
|
|
||||||
#target_include_directories(parserevburnerxml PUBLIC ${LIBXML_INCLUDE_DIR})
|
|
||||||
#target_link_libraries(parserevburnerxml portaudio xml2)
|
|
||||||
#add_test(parserevburnerxml parserevburnerxml)
|
|
||||||
#
|
|
||||||
add_executable(setmem tests/setmem.c)
|
|
||||||
target_include_directories(setmem PUBLIC)
|
|
||||||
target_link_libraries(setmem)
|
|
||||||
add_test(setmem setmem)
|
|
||||||
|
|
||||||
add_executable(getmem tests/getmem.c)
|
|
||||||
target_include_directories(getmem PUBLIC)
|
|
||||||
target_link_libraries(getmem)
|
|
||||||
add_test(getmem getmem)
|
|
||||||
#
|
|
||||||
#add_executable(setsimdata tests/setsimdata.c)
|
|
||||||
#target_include_directories(setsimdata PUBLIC)
|
|
||||||
#target_link_libraries(setsimdata)
|
|
||||||
#add_test(setsimdata setsimdata)
|
|
||||||
#
|
|
||||||
#add_executable(hidtest tests/hidtest.c)
|
|
||||||
#target_include_directories(hidtest PUBLIC)
|
|
||||||
#target_link_libraries(hidtest hidapi-hidraw)
|
|
||||||
#add_test(hidtest hidtest)
|
|
||||||
#
|
|
||||||
add_executable(simlighttest tests/simlighttest.c)
|
|
||||||
target_include_directories(simlighttest PUBLIC)
|
|
||||||
target_link_libraries(simlighttest serialport)
|
|
||||||
add_test(simlighttest simlighttest)
|
|
||||||
|
|
||||||
|
|
||||||
# used for enabling additional compiler options if supported
|
# used for enabling additional compiler options if supported
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
@@ -221,6 +177,12 @@ endif()
|
|||||||
# unit tests --only enable if requested AND we're not building as a sub-project
|
# unit tests --only enable if requested AND we're not building as a sub-project
|
||||||
if(ENABLE_TESTS AND NOT MONOCOQUE_SUBPROJECT)
|
if(ENABLE_TESTS AND NOT MONOCOQUE_SUBPROJECT)
|
||||||
message(STATUS "[monocoque] Unit Tests Enabled")
|
message(STATUS "[monocoque] Unit Tests Enabled")
|
||||||
add_subdirectory(tests)
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS monocoque-cli RUNTIME DESTINATION bin)
|
||||||
|
if(BUILD_GUI)
|
||||||
|
install(TARGETS monocoque-gui RUNTIME DESTINATION bin)
|
||||||
|
endif()
|
||||||
|
install(FILES tools/monocoque.desktop DESTINATION share/applications)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=Monocoque
|
||||||
|
Comment=Device manager for racing sims
|
||||||
|
Exec=gmonocoque
|
||||||
|
Icon=io.github.spacefreak18.monocoque
|
||||||
|
Terminal=false
|
||||||
|
Categories=Game;Development;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<component type="desktop-application">
|
||||||
|
<id>io.github.spacefreak18.monocoque</id>
|
||||||
|
<name>Monocoque</name>
|
||||||
|
<summary>Device manager for racing sims</summary>
|
||||||
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
|
<project_license>GPL-3.0-only</project_license>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Monocoque bridges telemetry from supported racing simulators to
|
||||||
|
peripheral devices such as haptic shakers, LED strips, shift lights,
|
||||||
|
and sim wind fans, and exposes a local API for third-party dashboard
|
||||||
|
and configuration tools.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
<launchable type="desktop-id">io.github.spacefreak18.monocoque.desktop</launchable>
|
||||||
|
<provides>
|
||||||
|
<binary>monocoque</binary>
|
||||||
|
<binary>gmonocoque</binary>
|
||||||
|
</provides>
|
||||||
|
<url type="homepage">https://spacefreak18.github.io/simapi/monocoque.html</url>
|
||||||
|
<url type="vcs-browser">https://github.com/Spacefreak18/monocoque</url>
|
||||||
|
<content_rating type="oars-1.1" />
|
||||||
|
<releases>
|
||||||
|
<release version="0.3.6" date="2026-08-21" />
|
||||||
|
</releases>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,320 @@
|
|||||||
|
# Flatpak manifest for monocoque -- NOT submitted anywhere (Flathub or
|
||||||
|
# otherwise) yet. Built 2026-08-30 on the patterns proven working for the
|
||||||
|
# sibling typiql-tauri/typiql project's own Flatpak pipeline (see this
|
||||||
|
# repo's .github/workflows/flatpak.yml header for the full list of bugs
|
||||||
|
# found and fixed here, monocoque-specific beyond what that sibling project
|
||||||
|
# already covered). VERIFIED LOCALLY end-to-end: built, installed, and ran
|
||||||
|
# both `monocoque --help` and `gmonocoque` from the resulting bundle. Not
|
||||||
|
# yet verified against real CI or real hardware (HID/serial/USB device
|
||||||
|
# access under the sandbox).
|
||||||
|
#
|
||||||
|
# org.freedesktop.Platform, not org.gnome.Platform: monocoque's GUI
|
||||||
|
# (gmonocoque) only needs GTK3, which freedesktop.Platform//25.08 already
|
||||||
|
# ships -- no need for the heavier GNOME runtime typiql needs for WebKitGTK.
|
||||||
|
# simd is NOT bundled. It is a separate daemon with its own packaging, and
|
||||||
|
# monocoque does not need it inside the sandbox to use it: simapi_get_sim()
|
||||||
|
# checks /dev/shm/SIMAPI.DAT before it ever scans /proc, so a simd running on
|
||||||
|
# the host -- however it was installed -- publishes telemetry this sandbox
|
||||||
|
# reads directly. That is what --device=shm below is for, and it is the only
|
||||||
|
# thing this manifest needs in order to work with simd.
|
||||||
|
#
|
||||||
|
# simapi itself is still present, but only as monocoque's own statically
|
||||||
|
# linked submodule, exactly as upstream's CMakeLists builds it. There is no
|
||||||
|
# separate simapi module here.
|
||||||
|
app-id: io.github.spacefreak18.monocoque
|
||||||
|
runtime: org.freedesktop.Platform
|
||||||
|
runtime-version: '25.08'
|
||||||
|
sdk: org.freedesktop.Sdk
|
||||||
|
command: gmonocoque
|
||||||
|
finish-args:
|
||||||
|
# --socket=x11, not fallback-x11: nappgui (the GUI toolkit gmonocoque uses)
|
||||||
|
# goes to X11 even when a Wayland display is available. fallback-x11 is
|
||||||
|
# deliberately inactive whenever Wayland works, so under a Wayland session
|
||||||
|
# DISPLAY stayed empty and gmonocoque died with `cannot open display` --
|
||||||
|
# confirmed on a real launch, with WAYLAND_DISPLAY=wayland-0 present and the
|
||||||
|
# socket visible inside the sandbox. Granting real X11 routes it through
|
||||||
|
# XWayland instead. --socket=wayland is kept so the toolkit can use it
|
||||||
|
# directly if that ever changes.
|
||||||
|
- --socket=x11
|
||||||
|
- --socket=wayland
|
||||||
|
# Standard companion to X11 access: without it MIT-SHM is unavailable and
|
||||||
|
# some toolkits fall over.
|
||||||
|
- --share=ipc
|
||||||
|
- --socket=pulseaudio
|
||||||
|
# HID/serial/USB access for wheels, pedals, shifters, and shaker/LED
|
||||||
|
# devices -- known risk area, Flatpak's sandboxing of raw device nodes is
|
||||||
|
# not always well-behaved; needs real hardware testing, not just a
|
||||||
|
# successful build.
|
||||||
|
- --device=all
|
||||||
|
# Retained, but not for the reason first written here: the GraphQL API on
|
||||||
|
# port 9000 is served by typiql's own Rust backend, not by monocoque --
|
||||||
|
# monocoque has no network code of its own, and the only libcurl in the
|
||||||
|
# binary is vendored nappgui's HTTP module, which nothing here calls. The
|
||||||
|
# two programs talk through ~/.config/monocoque and the process table, not
|
||||||
|
# a socket. This flag can probably be dropped.
|
||||||
|
- --share=network
|
||||||
|
# monocoque builds its paths from $HOME directly (e.g.
|
||||||
|
# "%s/.config/monocoque/diameters.config" in monocoque-cli.c), not from
|
||||||
|
# XDG_CONFIG_HOME, so it reads and writes the host's real directories.
|
||||||
|
# Without these grants a real launch failed with
|
||||||
|
# Failed to read config file '/home/david/.config/monocoque/monocoque.config'
|
||||||
|
# slog_open_file: Failed to open file: /home/david/.cache/monocoque/...log
|
||||||
|
# -- the manifest previously granted no filesystem access at all. Sharing
|
||||||
|
# the real config directory is also what makes a Flatpak monocoque and a
|
||||||
|
# native one agree, and what lets typiql configure it.
|
||||||
|
- --filesystem=xdg-config/monocoque:create
|
||||||
|
- --filesystem=xdg-cache/monocoque:create
|
||||||
|
# Host /dev/shm, where a host simd publishes telemetry as POSIX shared memory
|
||||||
|
# (/dev/shm/SIMAPI.DAT, mapped in simapi's simmapper.c). This is the flag
|
||||||
|
# that makes a Flatpak monocoque work with a simd installed on the host, so
|
||||||
|
# it matters more now that simd is not bundled, not less.
|
||||||
|
#
|
||||||
|
# shm is its own device option and is NOT implied by --device=all above --
|
||||||
|
# measured, with simd running: `ls /dev/shm` inside this sandbox returned 0
|
||||||
|
# entries against 18 on the host. The failure it caused is silent rather
|
||||||
|
# than loud: `monocoque play` started, read its config, connected
|
||||||
|
# pulseaudio, and then sat at "setting initial app state" forever, never
|
||||||
|
# logging "Opening universal shared memory api", because simd looked absent.
|
||||||
|
# The identical run with this flag reached that line one second in.
|
||||||
|
- --device=shm
|
||||||
|
|
||||||
|
modules:
|
||||||
|
- name: libconfig
|
||||||
|
buildsystem: cmake-ninja
|
||||||
|
config-opts:
|
||||||
|
- -DBUILD_TESTS=OFF
|
||||||
|
# libconfig 1.7.3's CMakeLists.txt predates CMake 3.5's minimum
|
||||||
|
# version policy; confirmed via a failed local build.
|
||||||
|
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||||
|
post-install:
|
||||||
|
- sh -c 'f=$(ls -1 COPYING COPYING.txt COPYING.LIB LICENSE LICENSE.txt LICENSE.md LICENCE licence.txt 2>/dev/null | head -1); if [ -n "$f" ]; then install -Dm644 "$f" /app/share/licenses/libconfig/$(basename "$f"); else echo "WARNING: no licence file found for libconfig"; fi'
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://github.com/hyperrealm/libconfig/archive/refs/tags/v1.7.3.tar.gz
|
||||||
|
sha256: 68757e37c567fd026330c8a8449aa5f9cac08a642f213f2687186b903bd7e94e
|
||||||
|
|
||||||
|
- name: argtable2
|
||||||
|
buildsystem: cmake-ninja
|
||||||
|
config-opts:
|
||||||
|
# Same CMake-minimum-version issue as libconfig -- this one's
|
||||||
|
# CMakeLists.txt is even older (2011).
|
||||||
|
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||||
|
# 2011-era code missing <ctype.h>/<strings.h> includes for
|
||||||
|
# isspace/toupper/bzero; GCC 14+ made implicit-function-declaration a
|
||||||
|
# hard error by default where it used to just warn. Confirmed via a
|
||||||
|
# failed local build.
|
||||||
|
- -DCMAKE_C_FLAGS=-Wno-error=implicit-function-declaration
|
||||||
|
# add_library(argtable2 ...) has no explicit STATIC/SHARED, so it
|
||||||
|
# defaults to CMake's global BUILD_SHARED_LIBS (off by default -> a
|
||||||
|
# static .a). monocoque's own target_link_libraries() lists argtable2
|
||||||
|
# before helper (which needs its symbols, e.g. arg_end/arg_parse in
|
||||||
|
# parameters.c) -- fine for a shared library (all symbols always
|
||||||
|
# available regardless of link-line position, which is what real
|
||||||
|
# distro packages of this ship), but a static archive only pulls
|
||||||
|
# symbols already needed by things linked *before* it, so helper's
|
||||||
|
# later reference to argtable2's symbols never resolves. Confirmed
|
||||||
|
# via a failed local build ("undefined reference to arg_end" etc.
|
||||||
|
# from helper's parameters.c, even though libargtable2.a genuinely
|
||||||
|
# contained those symbols). Building shared instead matches how this
|
||||||
|
# dependency normally ships and avoids the link-order sensitivity
|
||||||
|
# entirely, rather than reordering every target_link_libraries() call
|
||||||
|
# in CMakeLists.txt.
|
||||||
|
- -DBUILD_SHARED_LIBS=ON
|
||||||
|
# This CMake port has no install() rules at all (confirmed: no
|
||||||
|
# CMakeLists.txt in the tree calls install()), so the default
|
||||||
|
# cmake-ninja `ninja install` step silently does nothing -- monocoque's
|
||||||
|
# own build then fails on a missing argtable2.h. build-commands here
|
||||||
|
# replace the default install step: `ninja` still does the real
|
||||||
|
# compile, then copy the header and whatever library form actually got
|
||||||
|
# built (glob rather than a fixed versioned filename, since the exact
|
||||||
|
# .so version suffix isn't predictable without a build).
|
||||||
|
build-commands:
|
||||||
|
- ninja
|
||||||
|
- install -Dm644 src/argtable2.h /app/include/argtable2.h
|
||||||
|
- |
|
||||||
|
for f in src/libargtable2.so* src/libargtable2.a; do
|
||||||
|
if [ -e "$f" ]; then cp -P "$f" /app/lib/; fi
|
||||||
|
done
|
||||||
|
true
|
||||||
|
post-install:
|
||||||
|
- sh -c 'f=$(ls -1 COPYING COPYING.txt COPYING.LIB LICENSE LICENSE.txt LICENSE.md LICENCE licence.txt 2>/dev/null | head -1); if [ -n "$f" ]; then install -Dm644 "$f" /app/share/licenses/argtable2/$(basename "$f"); else echo "WARNING: no licence file found for argtable2"; fi'
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://sourceforge.net/projects/argtable/files/argtable/argtable-2.13/argtable2-13.tar.gz/download
|
||||||
|
sha256: 8f77e8a7ced5301af6e22f47302fdbc3b1ff41f2b83c43c77ae5ca041771ddbf
|
||||||
|
dest-filename: argtable2-13.tar.gz
|
||||||
|
|
||||||
|
- name: lua5.4
|
||||||
|
# Lua's own Makefile, not CMake/autotools. `posix` (not `linux`) avoids
|
||||||
|
# a readline dependency only needed for the interactive REPL binary,
|
||||||
|
# which monocoque doesn't use -- only the library.
|
||||||
|
buildsystem: simple
|
||||||
|
build-commands:
|
||||||
|
- make posix MYCFLAGS=-fPIC
|
||||||
|
- make install INSTALL_TOP=/app
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://www.lua.org/ftp/lua-5.4.7.tar.gz
|
||||||
|
sha256: 9fbf5e28ef86c69858f6d3d34eccc32e911c1a28b4120ff3e84aaa70cfbf1e30
|
||||||
|
|
||||||
|
- name: libserialport
|
||||||
|
buildsystem: autotools
|
||||||
|
# No pre-generated configure script in the git-archive tarball, only
|
||||||
|
# autogen.sh.
|
||||||
|
build-commands:
|
||||||
|
- ./autogen.sh
|
||||||
|
post-install:
|
||||||
|
- sh -c 'f=$(ls -1 COPYING COPYING.txt COPYING.LIB LICENSE LICENSE.txt LICENSE.md LICENCE licence.txt 2>/dev/null | head -1); if [ -n "$f" ]; then install -Dm644 "$f" /app/share/licenses/libserialport/$(basename "$f"); else echo "WARNING: no licence file found for libserialport"; fi'
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://github.com/sigrokproject/libserialport/archive/refs/tags/libserialport-0.1.2.tar.gz
|
||||||
|
sha256: cbb1192a09ff31d34e7efdb17a2f50d9d1974461c0b81c29bb449515d78d8950
|
||||||
|
|
||||||
|
- name: libxdg-basedir
|
||||||
|
buildsystem: autotools
|
||||||
|
build-commands:
|
||||||
|
- ./autogen.sh
|
||||||
|
post-install:
|
||||||
|
- sh -c 'f=$(ls -1 COPYING COPYING.txt COPYING.LIB LICENSE LICENSE.txt LICENSE.md LICENCE licence.txt 2>/dev/null | head -1); if [ -n "$f" ]; then install -Dm644 "$f" /app/share/licenses/libxdg-basedir/$(basename "$f"); else echo "WARNING: no licence file found for libxdg-basedir"; fi'
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://github.com/devnev/libxdg-basedir/archive/refs/tags/libxdg-basedir-1.2.3.tar.gz
|
||||||
|
sha256: ff30c60161f7043df4dcc6e7cdea8e064e382aa06c73dcc3d1885c7d2c77451d
|
||||||
|
|
||||||
|
- name: hidapi
|
||||||
|
buildsystem: cmake-ninja
|
||||||
|
config-opts:
|
||||||
|
# Same CMake-minimum-version issue as libconfig/argtable2, despite
|
||||||
|
# this otherwise being a current, actively maintained release.
|
||||||
|
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||||
|
# monocoque links hidapi-hidraw specifically -- no need for the
|
||||||
|
# libusb-backed variant, which would pull in an extra dependency.
|
||||||
|
- -DHIDAPI_WITH_LIBUSB=OFF
|
||||||
|
- -DHIDAPI_WITH_HIDRAW=ON
|
||||||
|
post-install:
|
||||||
|
- sh -c 'f=$(ls -1 COPYING COPYING.txt COPYING.LIB LICENSE LICENSE.txt LICENSE.md LICENCE licence.txt 2>/dev/null | head -1); if [ -n "$f" ]; then install -Dm644 "$f" /app/share/licenses/hidapi/$(basename "$f"); else echo "WARNING: no licence file found for hidapi"; fi'
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://github.com/libusb/hidapi/archive/refs/tags/hidapi-0.14.0.tar.gz
|
||||||
|
sha256: a5714234abe6e1f53647dd8cba7d69f65f71c558b7896ed218864ffcf405bcbd
|
||||||
|
|
||||||
|
- name: glu
|
||||||
|
buildsystem: meson
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://gitlab.freedesktop.org/mesa/glu/-/archive/glu-9.0.3/glu-glu-9.0.3.tar.gz
|
||||||
|
sha256: 7e919cbc1b2677b01d65fc28fd36a19d1f3e23d76663020e0f3b82b991475e8b
|
||||||
|
|
||||||
|
- name: libuv
|
||||||
|
buildsystem: cmake-ninja
|
||||||
|
config-opts:
|
||||||
|
- -DBUILD_TESTING=OFF
|
||||||
|
post-install:
|
||||||
|
- sh -c 'f=$(ls -1 COPYING COPYING.txt COPYING.LIB LICENSE LICENSE.txt LICENSE.md LICENCE licence.txt 2>/dev/null | head -1); if [ -n "$f" ]; then install -Dm644 "$f" /app/share/licenses/libuv/$(basename "$f"); else echo "WARNING: no licence file found for libuv"; fi'
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://github.com/libuv/libuv/archive/refs/tags/v1.49.2.tar.gz
|
||||||
|
sha256: 388ffcf3370d4cf7c4b3a3205504eea06c4be5f9e80d2ab32d19f8235accc1cf
|
||||||
|
|
||||||
|
- name: monocoque
|
||||||
|
buildsystem: cmake-ninja
|
||||||
|
config-opts:
|
||||||
|
- -DBUILD_GUI=on
|
||||||
|
- -DCMAKE_BUILD_TYPE=Release
|
||||||
|
# CMakeLists.txt links most of the dependencies built as separate
|
||||||
|
# flatpak modules above (hidapi-hidraw, serialport, argtable2, config,
|
||||||
|
# uv, xdg-basedir) by bare library name with no explicit -L, relying on
|
||||||
|
# the linker's default search path -- fine on a real system where these
|
||||||
|
# install to /usr/lib, but /app/lib isn't in that default path.
|
||||||
|
# -DCMAKE_EXE_LINKER_FLAGS=-L/app/lib didn't work: CMake appends
|
||||||
|
# EXE_LINKER_FLAGS at the *end* of the link command, after the -l
|
||||||
|
# flags that need it, and ld resolves -l against -L directories seen
|
||||||
|
# so far, left to right -- confirmed via a failed local build showing
|
||||||
|
# the exact same missing-library set with that flag present but
|
||||||
|
# useless. LIBRARY_PATH is a GCC driver environment variable, applied
|
||||||
|
# to its search regardless of where in the command line things land.
|
||||||
|
build-options:
|
||||||
|
env:
|
||||||
|
LIBRARY_PATH: /app/lib
|
||||||
|
sources:
|
||||||
|
# One level up from flatpak/manifest.yml is the repo root -- unlike
|
||||||
|
# typiql-tauri/typiql's dual-checkout ($GITHUB_WORKSPACE containing
|
||||||
|
# two separate repos side by side, needing an extra level), monocoque
|
||||||
|
# is checked out on its own with the standard single-repo layout, so
|
||||||
|
# this doesn't need the same `../..`/`../../..` juggling that session
|
||||||
|
# got wrong twice before finding the right depth for that project.
|
||||||
|
- type: dir
|
||||||
|
path: ..
|
||||||
|
# Skip the submodule paths. If the tree being built has them checked
|
||||||
|
# out, the copy brings along a real `.git` *file* at each path, and the
|
||||||
|
# git sources below then fail to clone into the same spot: "cannot
|
||||||
|
# overwrite non-directory .git with directory". Without this the
|
||||||
|
# manifest only builds from a checkout that deliberately omits
|
||||||
|
# submodules -- which is why CI's flatpak job checks out without them,
|
||||||
|
# and why a local build right after `git submodule update --init`
|
||||||
|
# breaks. Skipping makes it work either way.
|
||||||
|
skip:
|
||||||
|
- src/monocoque/simulatorapi/simapi
|
||||||
|
- src/monocoque/mgui/nappgui_src
|
||||||
|
# Two git submodules, each pinned to the exact commit .gitmodules/the
|
||||||
|
# tree tracks -- confirmed via a failed local build that the `dir`
|
||||||
|
# source above doesn't pull submodule content in (same class of issue
|
||||||
|
# as typiql-tauri/typiql's own submodules, src/lib/per-form etc.).
|
||||||
|
- type: git
|
||||||
|
url: https://github.com/spacefreak18/simapi
|
||||||
|
commit: 50fd181681862256780b2a0f74ef4bc459ed631a
|
||||||
|
dest: src/monocoque/simulatorapi/simapi
|
||||||
|
# nappgui_src is add_subdirectory()'d directly into monocoque's own
|
||||||
|
# CMake tree (src/monocoque/mgui/CMakeLists.txt), not a separately
|
||||||
|
# installed library -- so it's a source here, not its own flatpak
|
||||||
|
# module.
|
||||||
|
- type: git
|
||||||
|
url: https://github.com/frang75/nappgui_src
|
||||||
|
commit: 29c7bd3e0243eb38aa9a7e2eafe6cf74830c4ee8
|
||||||
|
dest: src/monocoque/mgui/nappgui_src
|
||||||
|
- type: file
|
||||||
|
path: io.github.spacefreak18.monocoque.desktop
|
||||||
|
- type: file
|
||||||
|
path: io.github.spacefreak18.monocoque.metainfo.xml
|
||||||
|
# Icon comes from tools/monocoque.svg via the `dir` source above (no
|
||||||
|
# separate file source needed). That file is a square 100x100 copy of
|
||||||
|
# the upstream artwork -- the published monocoque.svg the deb job
|
||||||
|
# downloads is 100x50, which Flatpak's export rejects outright, while
|
||||||
|
# appstreamcli separately hard-requires any desktop-application to
|
||||||
|
# have an icon at all (both confirmed via failed real CI runs). It is
|
||||||
|
# padded via a <g transform="translate(0,25)">, not stretched. Shared
|
||||||
|
# with the AppImage job, which has the same square-icon need.
|
||||||
|
post-install:
|
||||||
|
# This package's own licence, the vendored nappgui's (a source rather
|
||||||
|
# than a module, so the per-module collection above misses it), and the
|
||||||
|
# notices file naming every bundled dependency's origin.
|
||||||
|
- install -Dm644 LICENSE.rst /app/share/licenses/monocoque/LICENSE.rst
|
||||||
|
# The Debian copyright file is upstream's own account of what is in this
|
||||||
|
# source tree and under what terms -- slog (MIT), nappgui (MIT), simapi
|
||||||
|
# (LGPL) -- which a bundle has to carry because it distributes all of
|
||||||
|
# them, unlike a .deb whose dependencies are separate packages. Shipped
|
||||||
|
# verbatim rather than restated.
|
||||||
|
- install -Dm644 tools/distro/debian/dpkg/copyright /app/share/licenses/monocoque/copyright
|
||||||
|
# lua and glu ship no licence file in their tarballs -- Lua's MIT text
|
||||||
|
# lives in doc/readme.html, glu's SGI Free B only in source headers -- so
|
||||||
|
# checked-in copies are installed from here, where the repo is the build
|
||||||
|
# directory. (Doing it in their own modules fails: those build
|
||||||
|
# out-of-tree, so their source directory is not the working directory.)
|
||||||
|
- install -Dm644 packaging/licenses/lua-5.4-LICENSE.txt /app/share/licenses/lua5.4/LICENSE
|
||||||
|
- install -Dm644 packaging/licenses/glu-LICENSE.txt /app/share/licenses/glu/LICENSE
|
||||||
|
- install -Dm644 src/monocoque/mgui/nappgui_src/LICENSE /app/share/licenses/nappgui/LICENSE
|
||||||
|
- sh -c 'python3 tools/generate-third-party-notices.py flatpak/io.github.spacefreak18.monocoque.yml > /tmp/notices.md && install -Dm644 /tmp/notices.md /app/share/licenses/THIRD-PARTY-NOTICES.md'
|
||||||
|
# Confirmed via a failed local build that flatpak-builder's cmake-ninja
|
||||||
|
# buildsystem runs the automatic build+install step regardless of
|
||||||
|
# whether build-commands are also given -- these run in *addition*,
|
||||||
|
# not instead. So the fix for simlighttest (a stray, always-on scratch
|
||||||
|
# test executable that failed to link -lserialport, a pre-existing
|
||||||
|
# CMakeLists.txt bug unrelated to Flatpak) had to be commenting it out
|
||||||
|
# at the source, not overriding the build here. With that gone, the
|
||||||
|
# automatic build+install (using this repo's own new install() rules)
|
||||||
|
# already installs monocoque/gmonocoque correctly; these build-commands
|
||||||
|
# only need to add the extra files CMake doesn't know about.
|
||||||
|
build-commands:
|
||||||
|
- install -Dm644 io.github.spacefreak18.monocoque.desktop /app/share/applications/io.github.spacefreak18.monocoque.desktop
|
||||||
|
- install -Dm644 io.github.spacefreak18.monocoque.metainfo.xml /app/share/metainfo/io.github.spacefreak18.monocoque.metainfo.xml
|
||||||
|
- install -Dm644 tools/monocoque.svg /app/share/icons/hicolor/scalable/apps/io.github.spacefreak18.monocoque.svg
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
|
||||||
|
Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice including the dates of first publication and
|
||||||
|
either this permission notice or a reference to
|
||||||
|
http://oss.sgi.com/projects/FreeB/
|
||||||
|
shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Silicon Graphics, Inc.
|
||||||
|
shall not be used in advertising or otherwise to promote the sale, use or
|
||||||
|
other dealings in this Software without prior written authorization from
|
||||||
|
Silicon Graphics, Inc.
|
||||||
|
/
|
||||||
|
Pixel storage modes */
|
||||||
|
typedef struct {
|
||||||
|
GLint pack_alignment;
|
||||||
|
GLint pack_row_length;
|
||||||
|
GLint pack_skip_rows;
|
||||||
|
GLint pack_skip_pixels;
|
||||||
|
GLint pack_lsb_first;
|
||||||
|
GLint pack_swap_bytes;
|
||||||
|
GLint pack_skip_images;
|
||||||
|
GLint pack_image_height;
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright © 1994–2026 Lua.org, PUC-Rio.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
||||||
|
"packages": {
|
||||||
|
".": {
|
||||||
|
"release-type": "simple",
|
||||||
|
"package-name": "monocoque",
|
||||||
|
|
||||||
|
"//": "The 79 existing tags are bare semver (0.3.6), not v0.3.6, and there is only one package here. Both flags keep release-please tagging in that same series instead of starting a parallel one.",
|
||||||
|
"include-component-in-tag": false,
|
||||||
|
"include-v-in-tag": false,
|
||||||
|
|
||||||
|
"//bump": "While the major version is 0, a breaking change bumps the minor (0.3.6 -> 0.4.0) rather than declaring 1.0.0. Reaching 1.0.0 stays a deliberate act.",
|
||||||
|
"bump-minor-pre-major": true,
|
||||||
|
|
||||||
|
"draft": false,
|
||||||
|
"changelog-sections": [
|
||||||
|
{ "type": "feat", "section": "Features" },
|
||||||
|
{ "type": "fix", "section": "Bug Fixes" },
|
||||||
|
{ "type": "perf", "section": "Performance Improvements", "hidden": true },
|
||||||
|
{ "type": "revert", "section": "Reverts", "hidden": true },
|
||||||
|
{ "type": "docs", "section": "Documentation", "hidden": true },
|
||||||
|
{ "type": "style", "section": "Styles", "hidden": true },
|
||||||
|
{ "type": "chore", "section": "Miscellaneous Chores", "hidden": true },
|
||||||
|
{ "type": "refactor", "section": "Code Refactoring", "hidden": true },
|
||||||
|
{ "type": "test", "section": "Tests", "hidden": true },
|
||||||
|
{ "type": "build", "section": "Build System", "hidden": true },
|
||||||
|
{ "type": "ci", "section": "Continuous Integration", "hidden": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -245,6 +245,8 @@ DeviceSettings;
|
|||||||
|
|
||||||
int strtogame(const char* game, MonocoqueSettings* ms);
|
int strtogame(const char* game, MonocoqueSettings* ms);
|
||||||
|
|
||||||
|
int strtodevsubsubtype(const char* device_subsubtype, DeviceSettings* ds);
|
||||||
|
|
||||||
int devsetup(const char* device_type, const char* device_subtype, const char* config_files, MonocoqueSettings* ms, DeviceSettings* ds, config_setting_t* device_settings);
|
int devsetup(const char* device_type, const char* device_subtype, const char* config_files, MonocoqueSettings* ms, DeviceSettings* ds, config_setting_t* device_settings);
|
||||||
|
|
||||||
int settingsfree(DeviceSettings ds);
|
int settingsfree(DeviceSettings ds);
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Automated CI test suite — only built/run when ENABLE_TESTS is on (see
|
||||||
|
# root CMakeLists.txt). Manual, interactive, and hardware-dependent scratch
|
||||||
|
# tools live in tests/manual/ instead and are never built by this file.
|
||||||
|
|
||||||
|
add_executable(confighelper_test confighelper_test.c)
|
||||||
|
# helper (confighelper.c specifically) references slog/xml2/simulatorapi
|
||||||
|
# symbols elsewhere in the same translation unit — static libs resolve per
|
||||||
|
# object file, so all of these are needed even though this test only
|
||||||
|
# exercises strtodevsubsubtype.
|
||||||
|
target_link_libraries(confighelper_test helper config slog xml2 simulatorapi m proc2)
|
||||||
|
add_test(NAME confighelper_test COMMAND confighelper_test)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// Proof-of-plumbing test for the new CTest wiring — not an attempt at
|
||||||
|
// comprehensive coverage. Exercises strtodevsubsubtype (helper/confighelper.c),
|
||||||
|
// a pure string->enum mapping with no I/O/hardware, including the R8/R3
|
||||||
|
// aliasing onto SIMDEVSUBTYPE_MOZAR5 and the fallback for unrecognized input.
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../src/monocoque/helper/confighelper.h"
|
||||||
|
|
||||||
|
static int failures = 0;
|
||||||
|
|
||||||
|
static void check(const char* input, DeviceSubSubType expected)
|
||||||
|
{
|
||||||
|
DeviceSettings ds = {0};
|
||||||
|
strtodevsubsubtype(input, &ds);
|
||||||
|
if (ds.dev_subsubtype != expected)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FAIL: strtodevsubsubtype(\"%s\") = %d, expected %d\n",
|
||||||
|
input, ds.dev_subsubtype, expected);
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
check("MozaR5", SIMDEVSUBTYPE_MOZAR5);
|
||||||
|
check("MozaR8", SIMDEVSUBTYPE_MOZAR5); // aliased onto the same protocol as R5
|
||||||
|
check("MozaR3", SIMDEVSUBTYPE_MOZAR5); // same
|
||||||
|
check("MozaNew", SIMDEVSUBTYPE_MOZA_NEW);
|
||||||
|
check("MozaKSProWheel", SIMDEVSUBTYPE_MOZA_KS_PRO_WHEEL);
|
||||||
|
check("CammusC5", SIMDEVSUBTYPE_CAMMUSC5);
|
||||||
|
check("CammusC12", SIMDEVSUBTYPE_CAMMUSC12);
|
||||||
|
check("LogitechG29", SIMDEVSUBTYPE_LOGITECH_G29);
|
||||||
|
check("not-a-real-subtype", SIMDEVSUBTYPE_UNKNOWN);
|
||||||
|
check("", SIMDEVSUBTYPE_UNKNOWN);
|
||||||
|
|
||||||
|
if (failures > 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%d check(s) failed\n", failures);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("confighelper_test: all checks passed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Executable
+75
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Collect licence and copyright information for everything an AppImage bundles.
|
||||||
|
#
|
||||||
|
# usage: tools/appimage-collect-licenses.sh <AppDir>
|
||||||
|
#
|
||||||
|
# A .deb declares only what it ships, because its dependencies remain separate
|
||||||
|
# packages carrying their own copyright files. An AppImage carries those
|
||||||
|
# libraries inside it, so their notices have to travel with it -- and most of
|
||||||
|
# them here are LGPL (GTK, glib, pango and friends), where the obligation also
|
||||||
|
# covers saying where the corresponding source can be had.
|
||||||
|
#
|
||||||
|
# The mapping is mechanical rather than researched: every bundled library came
|
||||||
|
# from a Debian/Ubuntu package on the build host, so dpkg can name it, and the
|
||||||
|
# archive already holds a copyright file for each. Run this after linuxdeploy
|
||||||
|
# has populated the AppDir and before it packages the image.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
APPDIR="${1:?AppDir path}"
|
||||||
|
DOCDIR="$APPDIR/usr/share/doc"
|
||||||
|
MANIFEST="$DOCDIR/BUNDLED-LIBRARIES.txt"
|
||||||
|
|
||||||
|
mkdir -p "$DOCDIR"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "Libraries bundled in this AppImage"
|
||||||
|
echo "=================================="
|
||||||
|
echo
|
||||||
|
echo "Each library below was taken from the Debian/Ubuntu package named"
|
||||||
|
echo "beside it on the build host. That package's copyright file is included"
|
||||||
|
echo "under usr/share/doc/<package>/copyright in this image."
|
||||||
|
echo
|
||||||
|
echo "The corresponding source for any of them can be obtained with:"
|
||||||
|
echo " apt-get source <package>=<version>"
|
||||||
|
echo "from the distribution and release recorded below."
|
||||||
|
echo
|
||||||
|
echo "Build host: $( (. /etc/os-release && echo "$PRETTY_NAME") 2>/dev/null || echo unknown)"
|
||||||
|
echo
|
||||||
|
printf '%-44s %-34s %s\n' "LIBRARY" "PACKAGE" "VERSION"
|
||||||
|
} > "$MANIFEST"
|
||||||
|
|
||||||
|
found=0
|
||||||
|
unowned=0
|
||||||
|
|
||||||
|
while IFS= read -r so; do
|
||||||
|
base="$(basename "$so")"
|
||||||
|
pkg=""
|
||||||
|
# Try the usual multiarch location first, then fall back to a name search.
|
||||||
|
for candidate in "/usr/lib/x86_64-linux-gnu/$base" "/lib/x86_64-linux-gnu/$base" "/usr/lib/$base"; do
|
||||||
|
pkg="$(dpkg -S "$candidate" 2>/dev/null | head -1 | cut -d: -f1 || true)"
|
||||||
|
[ -n "$pkg" ] && break
|
||||||
|
done
|
||||||
|
if [ -z "$pkg" ]; then
|
||||||
|
pkg="$(dpkg -S "$base" 2>/dev/null | head -1 | cut -d: -f1 || true)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$pkg" ]; then
|
||||||
|
ver="$(dpkg-query -W -f='${Version}' "$pkg" 2>/dev/null || echo unknown)"
|
||||||
|
printf '%-44s %-34s %s\n' "$base" "$pkg" "$ver" >> "$MANIFEST"
|
||||||
|
if [ -f "/usr/share/doc/$pkg/copyright" ] && [ ! -f "$DOCDIR/$pkg/copyright" ]; then
|
||||||
|
install -Dm644 "/usr/share/doc/$pkg/copyright" "$DOCDIR/$pkg/copyright"
|
||||||
|
fi
|
||||||
|
found=$((found + 1))
|
||||||
|
else
|
||||||
|
# Built by this job rather than installed from a package -- its licence is
|
||||||
|
# collected separately, from its own source tree.
|
||||||
|
printf '%-44s %-34s %s\n' "$base" "(built from source in this job)" "-" >> "$MANIFEST"
|
||||||
|
unowned=$((unowned + 1))
|
||||||
|
fi
|
||||||
|
done < <(find "$APPDIR" -name '*.so*' -type f | sort)
|
||||||
|
|
||||||
|
echo >> "$MANIFEST"
|
||||||
|
echo "$found libraries from distribution packages, $unowned built in this job." >> "$MANIFEST"
|
||||||
|
|
||||||
|
echo "collected copyright for $found bundled libraries ($unowned built here)"
|
||||||
|
echo "manifest: $MANIFEST"
|
||||||
@@ -5,4 +5,4 @@ Priority: optional
|
|||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
||||||
Description: Racing Simulator Device Manager
|
Description: Racing Simulator Device Manager
|
||||||
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2,libxdg-basedir1,libhidapi-hidraw0,libgtk-3-0t64,libcurl4t64,libglu1-mesa
|
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2-16,libxdg-basedir1,libhidapi-hidraw0,libgtk-3-0t64,libcurl4t64,libglu1-mesa
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ Priority: optional
|
|||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
||||||
Description: Racing Simulator Device Manager
|
Description: Racing Simulator Device Manager
|
||||||
Depends: libpulse0,libconfig9,libargtable2-0,liblua5.4-0,libuv1,libserialport0,libxml2,libxdg-basedir1,libhidapi-hidraw0,libglu1-mesa,libcurl4,libgtk-3-0
|
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2-16,libxdg-basedir1,libhidapi-hidraw0,libglu1-mesa,libcurl4t64,libgtk-3-0t64
|
||||||
|
|||||||
@@ -15,14 +15,21 @@ Requires: pulseaudio-libs argtable libconfig hidapi libserialport libuv libxdg-b
|
|||||||
%description
|
%description
|
||||||
A device manager for Racing sims
|
A device manager for Racing sims
|
||||||
|
|
||||||
|
# Builds whatever tree has been staged at %{_sourcedir}/monocoque, cloning it
|
||||||
|
# from upstream master only if nothing is staged. The unconditional clone this
|
||||||
|
# replaced meant an rpm's contents tracked master rather than the tag being
|
||||||
|
# built -- so a fix on the branch being released was absent from its own
|
||||||
|
# release. CI stages the checked-out tree; a bare `rpmbuild -ba` on a
|
||||||
|
# workstation still works exactly as before.
|
||||||
%prep
|
%prep
|
||||||
rm -rf $RPM_BUILD_DIR/monocoque
|
rm -rf $RPM_BUILD_DIR/monocoque
|
||||||
rm -rf $RPM_SOURCE_DIR/monocoque
|
if [ ! -d $RPM_SOURCE_DIR/monocoque ]; then
|
||||||
cd $RPM_SOURCE_DIR
|
cd $RPM_SOURCE_DIR
|
||||||
git clone https://github.com/spacefreak18/monocoque
|
git clone https://github.com/spacefreak18/monocoque
|
||||||
cd monocoque
|
cd monocoque
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
cd ..
|
cd ..
|
||||||
|
fi
|
||||||
cp -r $RPM_SOURCE_DIR/monocoque $RPM_BUILD_DIR/
|
cp -r $RPM_SOURCE_DIR/monocoque $RPM_BUILD_DIR/
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
|||||||
Executable
+59
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate a third-party notices file from the Flatpak manifest.
|
||||||
|
|
||||||
|
A .deb lists only what it actually ships, because its dependencies are separate
|
||||||
|
packages carrying their own copyright files. A Flatpak or AppImage distributes
|
||||||
|
those libraries itself, so the notices have to travel with the artifact -- and
|
||||||
|
for the LGPL ones (libconfig, argtable2, libserialport, orcania, yder) that
|
||||||
|
includes saying where the corresponding source can be obtained.
|
||||||
|
|
||||||
|
The manifest already pins every dependency by URL and sha256, which is exactly
|
||||||
|
that information, so this is generated from it rather than maintained by hand
|
||||||
|
where it would drift.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
manifest = Path(sys.argv[1] if len(sys.argv) > 1
|
||||||
|
else "flatpak/io.github.spacefreak18.monocoque.yml")
|
||||||
|
text = manifest.read_text()
|
||||||
|
|
||||||
|
entries, name = [], None
|
||||||
|
for line in text.splitlines():
|
||||||
|
m = re.match(r"^ - name: (\S+)", line)
|
||||||
|
if m:
|
||||||
|
name = m.group(1)
|
||||||
|
entries.append({"name": name, "url": None, "sha256": None, "commit": None, "tag": None})
|
||||||
|
elif entries:
|
||||||
|
for key in ("url", "sha256", "commit", "tag"):
|
||||||
|
k = re.match(rf"^\s+{key}: (\S+)", line)
|
||||||
|
if k and entries[-1][key] is None:
|
||||||
|
entries[-1][key] = k.group(1)
|
||||||
|
|
||||||
|
out = [
|
||||||
|
"# Third-party notices",
|
||||||
|
"",
|
||||||
|
"This package bundles the libraries below. Each one's own licence text is",
|
||||||
|
"installed alongside it under `/app/share/licenses/<name>/`.",
|
||||||
|
"",
|
||||||
|
"Where a bundled library is under the LGPL, the corresponding source is the",
|
||||||
|
"exact archive listed here, identified by URL and SHA-256; the same version",
|
||||||
|
"can be rebuilt from it, and the Flatpak links these libraries dynamically.",
|
||||||
|
"",
|
||||||
|
"| Component | Source | Checksum / revision |",
|
||||||
|
"|---|---|---|",
|
||||||
|
]
|
||||||
|
for e in entries:
|
||||||
|
if not e["url"]:
|
||||||
|
continue
|
||||||
|
rev = e["sha256"] or e["commit"] or e["tag"] or ""
|
||||||
|
out.append(f"| {e['name']} | {e['url']} | `{rev[:16]}{'…' if len(rev) > 16 else ''}` |")
|
||||||
|
|
||||||
|
out += [
|
||||||
|
"",
|
||||||
|
"Generated by tools/generate-third-party-notices.py from the Flatpak",
|
||||||
|
"manifest -- do not edit by hand.",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
print("\n".join(out))
|
||||||
@@ -3,7 +3,7 @@ Version=1.0
|
|||||||
Type=Application
|
Type=Application
|
||||||
Name=Monocoque
|
Name=Monocoque
|
||||||
Comment=Launch Monocoque
|
Comment=Launch Monocoque
|
||||||
Exec=/usr/bin/gmonocoque
|
Exec=gmonocoque
|
||||||
Icon=monocoque
|
Icon=monocoque
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Categories=Game;Development;
|
Categories=Game;Development;
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100%" height="100%">
|
||||||
|
<!-- Square Flatpak icon canvas wrapping the real monocoque.svg artwork
|
||||||
|
(fetched from https://repo.spacefreak18.xyz/monocoque/icons/monocoque.svg,
|
||||||
|
viewBox 0 0 100 50), vertically centered via translate(0,25) rather
|
||||||
|
than stretched. Flatpak's export step requires square icons and
|
||||||
|
appstreamcli additionally requires any desktop-application to have
|
||||||
|
one at all, confirmed via two failed real CI runs. -->
|
||||||
|
<g transform="translate(0,25)">
|
||||||
|
<!-- Main Body / Chassis -->
|
||||||
|
<path d="M 25 28 C 35 28, 40 22, 55 22 L 72 24 C 76 24, 80 28, 85 28 L 85 34 L 25 34 Z" fill="#E10600" />
|
||||||
|
|
||||||
|
<!-- Nose Cone -->
|
||||||
|
<path d="M 25 28 L 12 30 C 10 30.5, 10 32.5, 12 33 L 25 34 Z" fill="#C00500" />
|
||||||
|
|
||||||
|
<!-- Front Wing -->
|
||||||
|
<rect x="5" y="31" width="10" height="4" rx="1" fill="#1A1A1A" />
|
||||||
|
<path d="M 12 31 L 12 35" stroke="#FFFFFF" stroke-width="1" />
|
||||||
|
|
||||||
|
<!-- Rear Wing -->
|
||||||
|
<path d="M 82 28 L 84 15 L 92 15 L 90 28 Z" fill="#1A1A1A" />
|
||||||
|
<rect x="80" y="13" width="14" height="4" rx="0.5" fill="#1A1A1A" />
|
||||||
|
|
||||||
|
<!-- Engine Cover / Airbox Intake -->
|
||||||
|
<path d="M 58 22 C 58 16, 64 16, 66 16 L 70 24 Z" fill="#E10600" />
|
||||||
|
<ellipse cx="61" cy="19" rx="2" ry="1.5" fill="#1A1A1A" />
|
||||||
|
|
||||||
|
<!-- Cockpit / Driver Helmet -->
|
||||||
|
<path d="M 48 23 C 48 20, 54 20, 54 23 Z" fill="#1A1A1A" />
|
||||||
|
<circle cx="52" cy="19" r="2.5" fill="#FFFFFF" />
|
||||||
|
<path d="M 51.5 17.5 L 54.5 18.5 L 53.5 20.5 L 51.5 19.5 Z" fill="#1A1A1A" /> <!-- Visor -->
|
||||||
|
|
||||||
|
<!-- Bargeboard / Sidepod Detail -->
|
||||||
|
<path d="M 38 27 L 55 25 L 58 34 L 36 34 Z" fill="#B00400" />
|
||||||
|
|
||||||
|
<!-- Wheels (Tires & Rims) -->
|
||||||
|
<!-- Rear Wheel -->
|
||||||
|
<circle cx="78" cy="32" r="11" fill="#1A1A1A" />
|
||||||
|
<circle cx="78" cy="32" r="5" fill="#4A4A4A" />
|
||||||
|
<circle cx="78" cy="32" r="2" fill="#D4AF37" />
|
||||||
|
|
||||||
|
<!-- Front Wheel -->
|
||||||
|
<circle cx="22" cy="33" r="9" fill="#1A1A1A" />
|
||||||
|
<circle cx="22" cy="33" r="4.2" fill="#4A4A4A" />
|
||||||
|
<circle cx="22" cy="33" r="1.8" fill="#D4AF37" />
|
||||||
|
|
||||||
|
<!-- Ground Shadow -->
|
||||||
|
<ellipse cx="50" cy="44" rx="42" ry="2" fill="#000000" fill-opacity="0.2" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
0.3.6
|
||||||
Reference in New Issue
Block a user