Compare commits
8
Commits
0.3.3
..
45f2ef7fef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45f2ef7fef | ||
|
|
cd67cb1689 | ||
|
|
501d72fb1e | ||
|
|
340752857d | ||
|
|
1cd36de5d5 | ||
|
|
2431113131 | ||
|
|
722cc4eb4e | ||
|
|
48baedf202 |
+403
-18
@@ -3,31 +3,84 @@ name: Make Packages
|
||||
on:
|
||||
push:
|
||||
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:
|
||||
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:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, debian-latest, debian-stable]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
include:
|
||||
- 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:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive
|
||||
- name: Update apt
|
||||
run: sudo apt update
|
||||
- name: Install Dependencies
|
||||
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
|
||||
# Must come before actions/checkout: these images are minimal and ship
|
||||
# no git, so checkout would fall back to a tarball download and silently
|
||||
# skip submodules -- simapi and nappgui_src are both required to build.
|
||||
# No sudo either; container jobs already run as root.
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
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
|
||||
id: strings
|
||||
shell: bash
|
||||
run: |
|
||||
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
|
||||
echo "build-output-dir=$GITHUB_WORKSPACE/build" >> "$GITHUB_OUTPUT"
|
||||
github_sha_hash=${{ github.sha }}
|
||||
echo "github-sha-short=${github_sha_hash:0:7}" >> $GITHUB_OUTPUT
|
||||
|
||||
@@ -38,7 +91,7 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER=g++
|
||||
-DCMAKE_C_COMPILER=gcc
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-S ${{ github.workspace }}
|
||||
-S "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Build
|
||||
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/pixmaps
|
||||
mkdir -p PKG_SOURCE/usr/share/icons/hicolor/scalable/apps
|
||||
mkdir -p PKG_SOURCE/usr/share/monocoque
|
||||
- name: Download xpm icon
|
||||
run: |
|
||||
curl -sSL https://repo.spacefreak18.xyz/monocoque/icons/monocoque.xpm -o PKG_SOURCE/usr/share/pixmaps/monocoque.xpm
|
||||
- name: Download svg icon
|
||||
run: |
|
||||
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
|
||||
run: |
|
||||
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 ./build/monocoque ./PKG_SOURCE/usr/bin/monocoque
|
||||
cp ./build/gmonocoque ./PKG_SOURCE/usr/bin/gmonocoque
|
||||
cp ./tools/monocoque.desktop ./PKG_SOURCE/usr/share/applications/monocoque.desktop
|
||||
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
|
||||
# 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-${{ 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:
|
||||
# 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:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [fedora-43]
|
||||
runs-on: ${{ matrix.os }}
|
||||
include:
|
||||
- os: fedora-43
|
||||
image: fedora:43
|
||||
- os: fedora-44
|
||||
image: fedora:44
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
permissions:
|
||||
contents: write
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
# 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-${{ 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:
|
||||
# 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
|
||||
|
||||
.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_SHARED "Build monocoque shared library" OFF)
|
||||
option(ENABLE_TESTS "Build test suite" OFF)
|
||||
|
||||
|
||||
project(monocoque)
|
||||
@@ -72,9 +73,15 @@ pkg_check_modules(LIBPROC2 libproc2)
|
||||
if (LIBPROCPS_FOUND)
|
||||
#add_compile_definitions(USE_OLD_PID_VAL=0)
|
||||
elseif (LIBPROC2_FOUND)
|
||||
if (LIBPROC2_VERSION VERSION_GREATER_EQUAL "4.0.5")
|
||||
#add_compile_definitions(USE_OLD_PID_VAL=0)
|
||||
else()
|
||||
# Some distro packagings (e.g. the freedesktop Flatpak SDK) ship a
|
||||
# libproc2.pc with `Version: UNKNOWN` rather than a real version
|
||||
# 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)
|
||||
endif()
|
||||
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
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
@@ -221,6 +177,12 @@ endif()
|
||||
# unit tests --only enable if requested AND we're not building as a sub-project
|
||||
if(ENABLE_TESTS AND NOT MONOCOQUE_SUBPROJECT)
|
||||
message(STATUS "[monocoque] Unit Tests Enabled")
|
||||
add_subdirectory(tests)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
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)
|
||||
|
||||
@@ -81,6 +81,9 @@ for installation instructions***
|
||||
- xdg-basedir
|
||||
- lua
|
||||
- libproc2
|
||||
- libcurl4
|
||||
- libgtk3
|
||||
- libglu1-mesa
|
||||
- [simapi](https://github.com/spacefreak18/simapi)
|
||||
- [slog](https://github.com/kala13x/slog) (static)
|
||||
- [nappgui](https://github.com/frang75/nappgui_src) (static) (for GUI)
|
||||
|
||||
@@ -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 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,8 +211,16 @@ int sounddev_init(SoundDevice* sounddevice, const char* devname, SoundDeviceSett
|
||||
}
|
||||
|
||||
|
||||
usb_generic_shaker_init(sounddevice, mainloop, context, devname, sds.volume, sds.pan, sds.channels, streamname);
|
||||
//usb_generic_shaker_init(sounddevice);
|
||||
// Returned, not discarded: this function is declared int and used to fall
|
||||
// off its end, so new_sound_device() read whatever happened to be in the
|
||||
// return register and treated most devices as failures -- "Could not
|
||||
// initialize Sound Device" for 22 of 24 configured shakers, while their
|
||||
// PulseAudio streams had in fact connected. The devices were freed and
|
||||
// never fed telemetry, so the graph looked correct in qpwgraph and nothing
|
||||
// shook. Being undefined behaviour it varied by build, which is why the
|
||||
// same config worked against a locally compiled monocoque and not the
|
||||
// packaged one.
|
||||
return usb_generic_shaker_init(sounddevice, mainloop, context, devname, sds.volume, sds.pan, sds.channels, streamname);
|
||||
}
|
||||
|
||||
static const vtable engine_sound_simdevice_vtable = { &sounddev_engine_update, &sounddev_free };
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <poll.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "../devices/hapticeffect.h"
|
||||
#include "../simulatorapi/simapi/simapi/simdata.h"
|
||||
#include "../simulatorapi/simapi/simapi/simmapper.h"
|
||||
#include "../simulatorapi/simapi/simapi/simmap.h"
|
||||
#include "../slog/slog.h"
|
||||
|
||||
#define DEFAULT_UPDATE_RATE 240.0
|
||||
@@ -998,11 +1000,45 @@ void set_wheel_lock_simdata(SimData* simdata)
|
||||
simdata->tyrediameter[3] = 0.710475735564615;
|
||||
}
|
||||
|
||||
// Drives every initialized device with the current test simdata, then
|
||||
// mirrors that same simdata into the SIMAPI.DAT shared memory segment (if
|
||||
// available) so external tools - dashboards, telemetry viewers, anything
|
||||
// that reads SIMAPI.DAT the same way a real running sim would populate it -
|
||||
// can follow monocoque's own test sequence instead of seeing nothing.
|
||||
static void update_devices(SimDevice* devices, int numdevices, SimData* simdata, SimMap* testsimmap)
|
||||
{
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
if (testsimmap != NULL && testsimmap->addr != NULL)
|
||||
{
|
||||
simdata->mtick++;
|
||||
memcpy(testsimmap->addr, simdata, sizeof(SimData));
|
||||
}
|
||||
}
|
||||
|
||||
int tester(SimDevice* devices, int numdevices)
|
||||
{
|
||||
|
||||
slogi("preparing test with %i devices...", numdevices);
|
||||
SimData* simdata = malloc(sizeof(SimData));
|
||||
memset(simdata, 0, sizeof(SimData));
|
||||
simdata->simon = true;
|
||||
simdata->simstatus = SIMAPI_STATUS_ACTIVEPLAY;
|
||||
|
||||
SimMap* testsimmap = malloc(sizeof(SimMap));
|
||||
memset(testsimmap, 0, sizeof(SimMap));
|
||||
int shmerr = simapi_universalmap_open(testsimmap, simdata);
|
||||
if (shmerr != SIMAPI_ERROR_NONE)
|
||||
{
|
||||
slog_warn("Could not open shared telemetry memory for test mode (error %i) - test sequence will still drive local devices, but external tools won't see it", shmerr);
|
||||
free(testsimmap);
|
||||
testsimmap = NULL;
|
||||
}
|
||||
|
||||
struct termios newsettings, canonicalmode;
|
||||
tcgetattr(0, &canonicalmode);
|
||||
@@ -1044,38 +1080,20 @@ int tester(SimDevice* devices, int numdevices)
|
||||
for (int r = 0; r < 8000; r += 3)
|
||||
{
|
||||
simdata->rpms = 1000 + r;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
for (int r = 0; r < 8000; r += 3)
|
||||
{
|
||||
simdata->rpms = 9000 - r;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
fprintf(stdout, "Setting rpms to 1000\n");
|
||||
simdata->rpms = 1000;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Green Flag!\n");
|
||||
@@ -1084,24 +1102,12 @@ int tester(SimDevice* devices, int numdevices)
|
||||
fprintf(stdout, "Shifting into first gear\n");
|
||||
simdata->gear = SIMAPI_GEAR_FIRST;
|
||||
simdata->gearc[0] = 0x31;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Setting speed to 100\n");
|
||||
simdata->velocity = 100;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "testing wheel spin\n");
|
||||
@@ -1114,13 +1120,7 @@ int tester(SimDevice* devices, int numdevices)
|
||||
simdata->tyrediameter[1] = 0.633384434597093;
|
||||
simdata->tyrediameter[2] = 0.710475735564615;
|
||||
simdata->tyrediameter[3] = 0.710475735564615;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Testing wheel Lock\n");
|
||||
@@ -1129,13 +1129,7 @@ int tester(SimDevice* devices, int numdevices)
|
||||
simdata->tyreRPS[2] = 25;
|
||||
simdata->tyreRPS[3] = 25;
|
||||
simdata->velocity = 150;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Shifting into second gear\n");
|
||||
@@ -1150,13 +1144,7 @@ int tester(SimDevice* devices, int numdevices)
|
||||
simdata->abs = 0;
|
||||
simdata->gear = SIMAPI_GEAR_SECOND;
|
||||
simdata->gearc[0] = 0x32;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Testing abs brake lock Lock\n");
|
||||
@@ -1169,13 +1157,7 @@ int tester(SimDevice* devices, int numdevices)
|
||||
simdata->tyrediameter[2] = 0.710475735564615;
|
||||
simdata->tyrediameter[3] = 0.710475735564615;
|
||||
simdata->abs = .11;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Setting speed to 200\n");
|
||||
@@ -1189,13 +1171,7 @@ int tester(SimDevice* devices, int numdevices)
|
||||
simdata->tyrediameter[3] = -1;
|
||||
simdata->abs = 0;
|
||||
simdata->velocity = 200;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Yellow Flag!\n");
|
||||
@@ -1204,24 +1180,12 @@ int tester(SimDevice* devices, int numdevices)
|
||||
fprintf(stdout, "Shifting into third gear\n");
|
||||
simdata->gear = SIMAPI_GEAR_THIRD;
|
||||
simdata->gearc[0] = 0x33;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Setting rpms to 2000\n");
|
||||
simdata->rpms = 2000;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Blue Flag!\n");
|
||||
@@ -1229,47 +1193,23 @@ int tester(SimDevice* devices, int numdevices)
|
||||
|
||||
fprintf(stdout, "Setting rpms to 4000\n");
|
||||
simdata->rpms = 4000;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Shifting into fourth gear\n");
|
||||
simdata->gear = SIMAPI_GEAR_FOURTH;
|
||||
simdata->gearc[0] = 0x34;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Setting speed to 300\n");
|
||||
simdata->velocity = 300;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Setting rpms to 7000\n");
|
||||
simdata->rpms = 7000;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(3);
|
||||
|
||||
fprintf(stdout, "Red Flag!\n");
|
||||
@@ -1277,22 +1217,10 @@ int tester(SimDevice* devices, int numdevices)
|
||||
|
||||
fprintf(stdout, "Setting rpms to 8000\n");
|
||||
simdata->rpms = 8000;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
for(int x = 0; x < 100; x++)
|
||||
{
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
}
|
||||
sleep(3);
|
||||
|
||||
@@ -1300,18 +1228,30 @@ int tester(SimDevice* devices, int numdevices)
|
||||
simdata->rpms = 100;
|
||||
simdata->gear = SIMAPI_GEAR_NEUTRAL;
|
||||
simdata->gearc[0] = 0x4e;
|
||||
for (int x = 0; x < numdevices; x++)
|
||||
{
|
||||
if (devices[x].initialized == true)
|
||||
{
|
||||
devices[x].update(&devices[x], simdata);
|
||||
}
|
||||
}
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
sleep(1);
|
||||
|
||||
fflush(stdout);
|
||||
tcsetattr(0, TCSANOW, &canonicalmode);
|
||||
|
||||
// Not shm_unlink()'d - the segment itself stays behind, the same way a
|
||||
// real sim's shared memory file stays around after that sim exits - but
|
||||
// its *contents* are reset to an inactive frame first. Leaving the last
|
||||
// active-play frame in place made every external reader (e.g.
|
||||
// typiql-tauri) see this test run as a sim that's still actively
|
||||
// driving forever, since nothing else ever writes to SIMAPI.DAT again
|
||||
// until the next `monocoque test`/`monocoque play`.
|
||||
if (testsimmap != NULL)
|
||||
{
|
||||
simdata->simon = false;
|
||||
simdata->simstatus = SIMAPI_STATUS_OFF;
|
||||
update_devices(devices, numdevices, simdata, testsimmap);
|
||||
|
||||
munmap(testsimmap->addr, sizeof(SimData));
|
||||
close(testsimmap->fd);
|
||||
free(testsimmap);
|
||||
}
|
||||
|
||||
free(simdata);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -245,6 +245,8 @@ DeviceSettings;
|
||||
|
||||
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 settingsfree(DeviceSettings ds);
|
||||
|
||||
@@ -21,6 +21,11 @@ typedef struct pa_devicelist {
|
||||
char description[256];
|
||||
} pa_devicelist_t;
|
||||
|
||||
static int matches_any(const char *value)
|
||||
{
|
||||
return strcmp(value, "default") == 0 || strcmp(value, "all") == 0;
|
||||
}
|
||||
|
||||
int find_default_config(config_setting_t *configs)
|
||||
{
|
||||
int count = config_setting_length(configs);
|
||||
@@ -29,20 +34,20 @@ int find_default_config(config_setting_t *configs)
|
||||
{
|
||||
config_setting_t *entry = config_setting_get_elem(configs, i);
|
||||
|
||||
const char *sim;
|
||||
const char *api;
|
||||
const char *car;
|
||||
// A key that isn't in the entry doesn't constrain the match. This used
|
||||
// to require all three, which no real config has: conf/monocoque.config
|
||||
// -- the example the README points at -- sets sim and car and never
|
||||
// mentions api, so every entry was skipped, -1 came back, and the
|
||||
// caller dereferenced the NULL that produced.
|
||||
const char *sim = "default";
|
||||
const char *api = "default";
|
||||
const char *car = "default";
|
||||
|
||||
if (!config_setting_lookup_string(entry, "sim", &sim))
|
||||
continue;
|
||||
if (!config_setting_lookup_string(entry, "api", &api))
|
||||
continue;
|
||||
if (!config_setting_lookup_string(entry, "car", &car))
|
||||
continue;
|
||||
config_setting_lookup_string(entry, "sim", &sim);
|
||||
config_setting_lookup_string(entry, "api", &api);
|
||||
config_setting_lookup_string(entry, "car", &car);
|
||||
|
||||
if ((strcmp(sim, "default") == 0 || strcmp(sim, "all") == 0) &&
|
||||
(strcmp(api, "default") == 0 || strcmp(api, "all") == 0) &&
|
||||
(strcmp(car, "default") == 0 || strcmp(car, "all") == 0))
|
||||
if (matches_any(sim) && matches_any(api) && matches_any(car))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
@@ -137,11 +142,31 @@ void populate_device_list(ListBox *listbox, config_t* cfg)
|
||||
config = config_lookup(cfg, "configs");
|
||||
|
||||
int config_num = find_default_config(config);
|
||||
if (config_num < 0)
|
||||
{
|
||||
// No entry claims to be the default one: list the first, which is what
|
||||
// a single-entry config means anyway, rather than nothing.
|
||||
config_num = 0;
|
||||
}
|
||||
|
||||
config_setting_t* selectedconfig = config_setting_get_elem(config, config_num);
|
||||
if (selectedconfig == NULL)
|
||||
{
|
||||
fprintf(stderr, "No config entry to list devices for\n");
|
||||
return;
|
||||
}
|
||||
|
||||
config_setting_t* config_devices = NULL;
|
||||
config_devices = config_setting_lookup(selectedconfig, "devices");
|
||||
|
||||
if (config_devices == NULL)
|
||||
{
|
||||
// config_setting_lookup dereferences its argument, so reaching here
|
||||
// with a NULL selectedconfig used to segfault inside libconfig --
|
||||
// gmonocoque died on launch, before drawing a window, for anyone whose
|
||||
// config didn't produce a match above.
|
||||
fprintf(stderr, "Config entry has no devices section\n");
|
||||
return;
|
||||
}
|
||||
|
||||
count = config_setting_length(config_devices);
|
||||
|
||||
|
||||
@@ -88,8 +88,16 @@ int main(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
Parameters* p = NULL;
|
||||
p = malloc(sizeof(Parameters));
|
||||
MonocoqueSettings* ms = malloc(sizeof(MonocoqueSettings));;
|
||||
// calloc, not malloc: a --help or --version run jumps straight to
|
||||
// cleanup_final before a single field is set, and the cleanup path frees
|
||||
// every pointer in both structs. Uninitialised heap made that a free() of
|
||||
// whatever junk was there -- confirmed on Debian forky, where the
|
||||
// released .deb aborted with `free(): invalid pointer` in
|
||||
// monocoquesettingsfree() on `monocoque --help`. Older glibc happened not
|
||||
// to notice, which is the only reason this looked fine on stable and
|
||||
// Fedora.
|
||||
p = calloc(1, sizeof(Parameters));
|
||||
MonocoqueSettings* ms = calloc(1, sizeof(MonocoqueSettings));
|
||||
|
||||
ConfigError ppe = getParameters(argc, argv, p);
|
||||
if (ppe == E_SUCCESS_AND_EXIT || ppe == E_SOMETHING_BAD)
|
||||
|
||||
@@ -91,7 +91,10 @@ int monocoque_initialize(int argc, char** argv)
|
||||
}
|
||||
|
||||
p = NULL;
|
||||
p = malloc(sizeof(Parameters));
|
||||
// calloc, not malloc: freeparams() walks every pointer in this struct
|
||||
// on the early-exit paths, before getParameters has set them. See the
|
||||
// same change in monocoque-cli.c.
|
||||
p = calloc(1, sizeof(Parameters));
|
||||
p->config_dirpath = NULL;
|
||||
p->config_filepath = NULL;
|
||||
p->log_filename_str = NULL;
|
||||
|
||||
@@ -84,8 +84,16 @@ int main(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
Parameters* p = NULL;
|
||||
p = malloc(sizeof(Parameters));
|
||||
MonocoqueSettings* ms = malloc(sizeof(MonocoqueSettings));;
|
||||
// calloc, not malloc: a --help or --version run jumps straight to
|
||||
// cleanup_final before a single field is set, and the cleanup path frees
|
||||
// every pointer in both structs. Uninitialised heap made that a free() of
|
||||
// whatever junk was there -- confirmed on Debian forky, where the
|
||||
// released .deb aborted with `free(): invalid pointer` in
|
||||
// monocoquesettingsfree() on `monocoque --help`. Older glibc happened not
|
||||
// to notice, which is the only reason this looked fine on stable and
|
||||
// Fedora.
|
||||
p = calloc(1, sizeof(Parameters));
|
||||
MonocoqueSettings* ms = calloc(1, sizeof(MonocoqueSettings));
|
||||
|
||||
ConfigError ppe = getParameters(argc, argv, p);
|
||||
if (ppe == E_SUCCESS_AND_EXIT || ppe == E_SOMETHING_BAD)
|
||||
|
||||
@@ -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
|
||||
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
||||
Description: Racing Simulator Device Manager
|
||||
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2,libxdg-basedir1,libhidapi-hidraw0
|
||||
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
|
||||
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
||||
Description: Racing Simulator Device Manager
|
||||
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2,libxdg-basedir1,libhidapi-hidraw0
|
||||
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2,libxdg-basedir1,libhidapi-hidraw0,libgtk-3-0t64,libglu1-mesa,libcurl4t64
|
||||
|
||||
@@ -5,4 +5,4 @@ Priority: optional
|
||||
Architecture: amd64
|
||||
Maintainer: Paul Jones <paul@spacefreak18.xyz>
|
||||
Description: Racing Simulator Device Manager
|
||||
Depends: libpulse0,libconfig9,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2,libxdg-basedir1,libhidapi-hidraw0
|
||||
Depends: libpulse0,libconfig11,libargtable2-0,liblua5.4-0,libuv1t64,libserialport0,libxml2-16,libxdg-basedir1,libhidapi-hidraw0,libglu1-mesa,libcurl4t64,libgtk-3-0t64
|
||||
|
||||
@@ -135,9 +135,33 @@ log_info "Installing packages inside container (this may take a few minutes)..."
|
||||
distrobox enter --root "$CONTAINER" -- bash -c '
|
||||
set -euo pipefail
|
||||
|
||||
# Enable the multilib repo for 32-bit runtime support — Proton bridge
|
||||
# apps (e.g. acbridge.exe) are 32-bit wine processes and fail with a
|
||||
# bare "No such file or directory" (not a permissions/PATH error) when
|
||||
# /lib/ld-linux.so.2, the 32-bit dynamic linker, is missing. A fresh
|
||||
# Arch container image does not ship multilib enabled by default, and
|
||||
# (confirmed on a real install) not even the commented-out [multilib]
|
||||
# stanza is present to uncomment — it has to be appended outright.
|
||||
# Idempotent so re-running this script is still safe.
|
||||
if ! grep -q "^\[multilib\]" /etc/pacman.conf; then
|
||||
echo "Enabling multilib repository (needed for 32-bit wine/Proton bridge support)..."
|
||||
cat >> /etc/pacman.conf << "PACMANCONF_EOF"
|
||||
|
||||
[multilib]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
PACMANCONF_EOF
|
||||
fi
|
||||
|
||||
# Install build dependencies
|
||||
echo "Installing build dependencies..."
|
||||
sudo pacman -Syu --needed --noconfirm base-devel git mingw-w64-gcc
|
||||
# wine + lib32-glibc pull in the well-tested 32-bit dependency chain
|
||||
# the Proton-bundled wine build each game uses needs to actually
|
||||
# execute (this Arch wine package is not run directly — each game
|
||||
# launches its own Proton version bridge via BridgeScripts.txt-style
|
||||
# commands — installing the package is just the simplest reliable way
|
||||
# to get every lib32-* dependency it needs without hand-picking each
|
||||
# one).
|
||||
sudo pacman -Syu --needed --noconfirm base-devel git mingw-w64-gcc wine lib32-glibc
|
||||
|
||||
# Install yay (AUR helper) if not present
|
||||
if ! command -v yay &>/dev/null; then
|
||||
@@ -252,5 +276,5 @@ echo " start-simd & start-monocoque & $INSTALL_DIR/simshmbridge/assets/a
|
||||
echo ""
|
||||
echo " For tools that automate steps 1 and 3 (Moza auto-detection, Steam launch"
|
||||
echo " option configuration, unified game launcher), visit:"
|
||||
echo " https://github.com/cescofry/simracing-utilities"
|
||||
echo " https://github.com/cescofry/simracing-utilties"
|
||||
echo ""
|
||||
|
||||
@@ -10,19 +10,26 @@ URL: https://spacefreak18.github.io/simapi
|
||||
Distribution: Fedora Linux
|
||||
Vendor: spacefreak18
|
||||
Packager: Paul Jones <paul@spacefreak18.xyz>
|
||||
Requires: pulseaudio-libs argtable libconfig hidapi libserialport libuv libxdg-basedir lua-libs libxml2 procps-ng gtk3
|
||||
Requires: pulseaudio-libs argtable libconfig hidapi libserialport libuv libxdg-basedir lua-libs libxml2 procps-ng gtk3 libcurl mesa-libGL
|
||||
|
||||
%description
|
||||
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
|
||||
rm -rf $RPM_BUILD_DIR/monocoque
|
||||
rm -rf $RPM_SOURCE_DIR/monocoque
|
||||
cd $RPM_SOURCE_DIR
|
||||
git clone https://github.com/spacefreak18/monocoque
|
||||
cd monocoque
|
||||
git submodule update --init --recursive
|
||||
cd ..
|
||||
if [ ! -d $RPM_SOURCE_DIR/monocoque ]; then
|
||||
cd $RPM_SOURCE_DIR
|
||||
git clone https://github.com/spacefreak18/monocoque
|
||||
cd monocoque
|
||||
git submodule update --init --recursive
|
||||
cd ..
|
||||
fi
|
||||
cp -r $RPM_SOURCE_DIR/monocoque $RPM_BUILD_DIR/
|
||||
|
||||
%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
|
||||
Name=Monocoque
|
||||
Comment=Launch Monocoque
|
||||
Exec=/usr/bin/gmonocoque
|
||||
Exec=gmonocoque
|
||||
Icon=monocoque
|
||||
Terminal=false
|
||||
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