Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/actions/static-opencv/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Static OpenCV for camera_linux
description: >
Make sure the minimal static OpenCV used by camera_linux is in /opt/opencv-static.
The CI image ships it; if the image predates it, build it here and cache the result.

runs:
using: composite
steps:
- name: Check CI image for static OpenCV
id: image
shell: bash
run: |
if scripts/linux/build_opencv_static.sh --check-only /opt/opencv-static; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
echo "::notice::CI image has no /opt/opencv-static (image not rebuilt yet?); building it in this job"
fi

- name: Restore static OpenCV cache
if: steps.image.outputs.present != 'true'
uses: actions/cache@v5
with:
path: /opt/opencv-static
key: opencv-static-${{ hashFiles('scripts/linux/build_opencv_static.sh') }}

- name: Build static OpenCV
if: steps.image.outputs.present != 'true'
shell: bash
run: scripts/linux/build_opencv_static.sh /opt/opencv-static
1 change: 1 addition & 0 deletions .github/workflows/build-ci-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [main, staging]
paths:
- 'Dockerfile'
- 'scripts/linux/build_opencv_static.sh'
- '.github/workflows/build-ci-image.yaml'
workflow_dispatch:

Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ jobs:
CHANGE_NOW: ${{ secrets.CHANGE_NOW }}
run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart

- name: Static OpenCV for camera_linux
uses: ./.github/actions/static-opencv

- name: Build
env:
USE_SYSTEM_SECURE_STORAGE_DEPS: "1"
STACKWALLET_OPENCV_DIR: /opt/opencv-static/lib/cmake/opencv4
run: flutter build linux --release --verbose

- name: Prepare Linux release bundle
Expand Down Expand Up @@ -479,9 +483,13 @@ jobs:
CHANGE_NOW: ${{ secrets.CHANGE_NOW }}
run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart

- name: Static OpenCV for camera_linux
uses: ./.github/actions/static-opencv

- name: Build
env:
USE_SYSTEM_SECURE_STORAGE_DEPS: "1"
STACKWALLET_OPENCV_DIR: /opt/opencv-static/lib/cmake/opencv4
run: flutter build linux --release --verbose

- name: Prepare Linux release bundle
Expand Down Expand Up @@ -546,9 +554,13 @@ jobs:
CHANGE_NOW: ${{ secrets.CHANGE_NOW }}
run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart

- name: Static OpenCV for camera_linux
uses: ./.github/actions/static-opencv

- name: Build
env:
USE_SYSTEM_SECURE_STORAGE_DEPS: "1"
STACKWALLET_OPENCV_DIR: /opt/opencv-static/lib/cmake/opencv4
run: flutter build linux --release --verbose

- name: Prepare Linux release bundle
Expand Down Expand Up @@ -666,6 +678,7 @@ jobs:
tar -xzf "stack_wallet-linux-x86_64-${VERSION}.tar.gz"
mkdir -p AppDir
cp -r bundle/* AppDir/
python3 scripts/linux/prepare_release_bundle.py --check-only AppDir
cp appimage/stack_wallet/AppRun AppDir/AppRun
chmod +x AppDir/AppRun
cp appimage/stack_wallet/stack_wallet.desktop AppDir/
Expand Down Expand Up @@ -1124,6 +1137,7 @@ jobs:
tar -xzf "campfire-linux-x86_64-${VERSION}.tar.gz"
mkdir -p AppDir
cp -r bundle/* AppDir/
python3 scripts/linux/prepare_release_bundle.py --check-only AppDir
cp appimage/campfire/AppRun AppDir/AppRun
chmod +x AppDir/AppRun
cp appimage/campfire/campfire.desktop AppDir/
Expand Down Expand Up @@ -1584,6 +1598,7 @@ jobs:
tar -xzf "stack_duo-linux-x86_64-${VERSION}.tar.gz"
mkdir -p AppDir
cp -r bundle/* AppDir/
python3 scripts/linux/prepare_release_bundle.py --check-only AppDir
cp appimage/stack_duo/AppRun AppDir/AppRun
chmod +x AppDir/AppRun
cp appimage/stack_duo/stack_duo.desktop AppDir/
Expand Down
10 changes: 9 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
clang libclang-dev llvm \
libgcrypt20-dev libgirepository1.0-dev libgit2-dev libglib2.0-dev libgtk-3-dev \
libjsoncpp-dev liblzma-dev libncurses5-dev libncursesw5-dev \
libopencv-dev \
libsecret-1-dev libssl-dev libtss2-dev \
ocl-icd-opencl-dev opencl-headers valac zlib1g-dev \
g++-aarch64-linux-gnu gcc-aarch64-linux-gnu \
Expand Down Expand Up @@ -94,6 +93,15 @@ RUN git clone --depth 1 --branch 3.47.2 https://github.com/flutter/flutter.git "

RUN git config --system --add safe.directory '*'

# Minimal static OpenCV for the camera_linux QR plugin, so that the Linux tarball and
# AppImage carry OpenCV inside libopencv_wrapper.so instead of needing libopencv-dev's
# ~50 shared libraries on the user's machine. Linux builds point at it with
# STACKWALLET_OPENCV_DIR (see scripts/app_config/templates/linux/CMakeLists.txt).
COPY scripts/linux/build_opencv_static.sh /tmp/build_opencv_static.sh
RUN /tmp/build_opencv_static.sh /opt/opencv-static \
&& rm /tmp/build_opencv_static.sh
ENV STACKWALLET_OPENCV_DIR=/opt/opencv-static/lib/cmake/opencv4

RUN flutter --version && rustc --version && cargo --version && node --version && go version


Expand Down
19 changes: 17 additions & 2 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,17 @@ flutter run linux

#### Linux release bundle preparation

After `flutter build linux --release`, run this from the repository root before
archiving the bundle or using it to build an AppImage or Flatpak:
For a release bundle the QR scanner plugin (`camera_linux`) must not depend on
OpenCV libraries from the user's machine. Build a minimal static OpenCV once, and
point the Linux build at it (the CI image already has it in `/opt/opencv-static`):

```sh
scripts/linux/build_opencv_static.sh "$HOME/opencv-static"
export STACKWALLET_OPENCV_DIR="$HOME/opencv-static/lib/cmake/opencv4"
```

Then, after `flutter build linux --release`, run this from the repository root
before archiving the bundle or using it to build an AppImage or Flatpak:

```sh
sudo apt-get install binutils patchelf python3
Expand All @@ -204,6 +213,12 @@ stack. Other libraries are not patched automatically. Ubuntu 24.04's `patchelf`
supports the required `--clear-execstack` option. CI runs this before producing
the Linux tarball, so both downstream packagers inherit the prepared bundle.

It also requires `libcamera_linux.so` and `libopencv_wrapper.so` in `lib/`, sets
their RUNPATH to `$ORIGIN`, and fails unless they need nothing but the bundle and
baseline libraries (glibc, libstdc++) and load with the symbols the app looks up.
`--check-only` runs just that check, without patchelf, on any assembled bundle
such as an AppDir.

Standalone regression tests (also require a C compiler):

```sh
Expand Down
60 changes: 59 additions & 1 deletion flatpak/com.cypherstack.campfire.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,48 @@ finish-args:
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
- --device=all
- --filesystem=~/.campfire:create
- --talk-name=org.freedesktop.secrets
- --talk-name=org.freedesktop.Notifications

modules:
- name: opencv
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DCMAKE_BUILD_TYPE=Release
- -DBUILD_LIST=core,imgcodecs,imgproc,videoio
- -DBUILD_EXAMPLES=OFF
- -DBUILD_TESTS=OFF
- -DBUILD_PERF_TESTS=OFF
- -DBUILD_DOCS=OFF
- -DBUILD_opencv_python3=OFF
- -DBUILD_opencv_python_bindings_generator=OFF
- -DWITH_GTK=OFF
- -DWITH_QT=OFF
- -DWITH_OPENGL=OFF
- -DWITH_OPENCL=OFF
- -DWITH_CUDA=OFF
- -DWITH_FFMPEG=OFF
- -DWITH_GSTREAMER=OFF
- -DWITH_V4L=ON
# Offline build: the IPP ICV download would fail inside the sandbox.
- -DWITH_IPP=OFF
- -DBUILD_opencv_apps=OFF
# OpenCV defaults to /app/lib64 here; keep it in /app/lib, which is on the
# loader path and in the camera-linux RPATH below.
- -DOPENCV_LIB_INSTALL_PATH=lib
cleanup:
- /include
- /lib/cmake
- /share/opencv4
sources:
- type: git
url: https://github.com/opencv/opencv
tag: '4.10.0'
commit: 71d3237a093b60a27601c20e9ee6c3e52154e8b1

- name: campfire
buildsystem: simple
build-commands:
Expand All @@ -31,3 +67,25 @@ modules:
sources:
- type: dir
path: .

# The SDK links with --as-needed, which would drop libopencv_wrapper.so from
# libcamera_linux.so (camera_linux.c calls nothing) and leave the symbols
# Dart looks up undefined, so turn it off for this module.
- name: camera-linux
buildsystem: simple
build-commands:
- cmake -S src -B _build
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_PREFIX_PATH=/app
-DCMAKE_INSTALL_RPATH=/app/lib/campfire/lib:/app/lib
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
-DCMAKE_SHARED_LINKER_FLAGS=-Wl,--no-as-needed
- cmake --build _build --parallel
- install -Dm755 _build/libopencv_wrapper.so
/app/lib/campfire/lib/libopencv_wrapper.so
- install -Dm755 _build/libcamera_linux.so
/app/lib/campfire/lib/libcamera_linux.so
sources:
- type: git
url: https://github.com/cypherstack/camera-linux
commit: ecb412474c5d240347b04ac1eb9f019802ff7034
60 changes: 59 additions & 1 deletion flatpak/com.cypherstack.stackduo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,48 @@ finish-args:
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
- --device=all
- --filesystem=~/.stackduo:create
- --talk-name=org.freedesktop.secrets
- --talk-name=org.freedesktop.Notifications

modules:
- name: opencv
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DCMAKE_BUILD_TYPE=Release
- -DBUILD_LIST=core,imgcodecs,imgproc,videoio
- -DBUILD_EXAMPLES=OFF
- -DBUILD_TESTS=OFF
- -DBUILD_PERF_TESTS=OFF
- -DBUILD_DOCS=OFF
- -DBUILD_opencv_python3=OFF
- -DBUILD_opencv_python_bindings_generator=OFF
- -DWITH_GTK=OFF
- -DWITH_QT=OFF
- -DWITH_OPENGL=OFF
- -DWITH_OPENCL=OFF
- -DWITH_CUDA=OFF
- -DWITH_FFMPEG=OFF
- -DWITH_GSTREAMER=OFF
- -DWITH_V4L=ON
# Offline build: the IPP ICV download would fail inside the sandbox.
- -DWITH_IPP=OFF
- -DBUILD_opencv_apps=OFF
# OpenCV defaults to /app/lib64 here; keep it in /app/lib, which is on the
# loader path and in the camera-linux RPATH below.
- -DOPENCV_LIB_INSTALL_PATH=lib
cleanup:
- /include
- /lib/cmake
- /share/opencv4
sources:
- type: git
url: https://github.com/opencv/opencv
tag: '4.10.0'
commit: 71d3237a093b60a27601c20e9ee6c3e52154e8b1

- name: stack_duo
buildsystem: simple
build-commands:
Expand All @@ -31,3 +67,25 @@ modules:
sources:
- type: dir
path: .

# The SDK links with --as-needed, which would drop libopencv_wrapper.so from
# libcamera_linux.so (camera_linux.c calls nothing) and leave the symbols
# Dart looks up undefined, so turn it off for this module.
- name: camera-linux
buildsystem: simple
build-commands:
- cmake -S src -B _build
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_PREFIX_PATH=/app
-DCMAKE_INSTALL_RPATH=/app/lib/stack_duo/lib:/app/lib
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
-DCMAKE_SHARED_LINKER_FLAGS=-Wl,--no-as-needed
- cmake --build _build --parallel
- install -Dm755 _build/libopencv_wrapper.so
/app/lib/stack_duo/lib/libopencv_wrapper.so
- install -Dm755 _build/libcamera_linux.so
/app/lib/stack_duo/lib/libcamera_linux.so
sources:
- type: git
url: https://github.com/cypherstack/camera-linux
commit: ecb412474c5d240347b04ac1eb9f019802ff7034
67 changes: 66 additions & 1 deletion flatpak/com.cypherstack.stackwallet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,51 @@ finish-args:
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
- --device=all
- --filesystem=~/.stackwallet:create
- --talk-name=org.freedesktop.secrets
- --talk-name=org.freedesktop.Notifications

modules:
# Minimal OpenCV build — only the modules needed by camera_linux (VideoCapture + imencode).
# Keeps the Flatpak from pulling in the full 47-module system OpenCV dependency chain.
- name: opencv
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DCMAKE_BUILD_TYPE=Release
- -DBUILD_LIST=core,imgcodecs,imgproc,videoio
- -DBUILD_EXAMPLES=OFF
- -DBUILD_TESTS=OFF
- -DBUILD_PERF_TESTS=OFF
- -DBUILD_DOCS=OFF
- -DBUILD_opencv_python3=OFF
- -DBUILD_opencv_python_bindings_generator=OFF
- -DWITH_GTK=OFF
- -DWITH_QT=OFF
- -DWITH_OPENGL=OFF
- -DWITH_OPENCL=OFF
- -DWITH_CUDA=OFF
- -DWITH_FFMPEG=OFF
- -DWITH_GSTREAMER=OFF
- -DWITH_V4L=ON
# Offline build: the IPP ICV download would fail inside the sandbox.
- -DWITH_IPP=OFF
- -DBUILD_opencv_apps=OFF
# OpenCV defaults to /app/lib64 here; keep it in /app/lib, which is on the
# loader path and in the camera-linux RPATH below.
- -DOPENCV_LIB_INSTALL_PATH=lib
cleanup:
- /include
- /lib/cmake
- /share/opencv4
sources:
- type: git
url: https://github.com/opencv/opencv
tag: '4.10.0'
commit: 71d3237a093b60a27601c20e9ee6c3e52154e8b1

# Install the pre-built Flutter bundle.
- name: stack_wallet
buildsystem: simple
build-commands:
Expand All @@ -34,3 +73,29 @@ modules:
sources:
- type: dir
path: .

# Rebuild camera_linux and its OpenCV wrapper against the Flatpak-built OpenCV above,
# then overwrite the pre-built CI libs dropped by the stack_wallet module.
# RPATH includes both the app lib dir (for libopencv_wrapper.so) and /app/lib
# (for the OpenCV modules installed by the opencv module above).
# The SDK links with --as-needed, which would drop libopencv_wrapper.so from
# libcamera_linux.so (camera_linux.c calls nothing) and leave the symbols
# Dart looks up undefined, so turn it off for this module.
- name: camera-linux
buildsystem: simple
build-commands:
- cmake -S src -B _build
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_PREFIX_PATH=/app
-DCMAKE_INSTALL_RPATH=/app/lib/stack_wallet/lib:/app/lib
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
-DCMAKE_SHARED_LINKER_FLAGS=-Wl,--no-as-needed
- cmake --build _build --parallel
- install -Dm755 _build/libopencv_wrapper.so
/app/lib/stack_wallet/lib/libopencv_wrapper.so
- install -Dm755 _build/libcamera_linux.so
/app/lib/stack_wallet/lib/libcamera_linux.so
sources:
- type: git
url: https://github.com/cypherstack/camera-linux
commit: ecb412474c5d240347b04ac1eb9f019802ff7034
Loading
Loading