-
Notifications
You must be signed in to change notification settings - Fork 44
Add AppImage support for GSmartControl #112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| name: Build AppImage | ||
|
|
||
| on: | ||
| # Triggers the workflow on push or pull request events but only for the main branch | ||
| push: | ||
| branches: [ main ] | ||
| pull_request: | ||
| branches: [ main ] | ||
| # Allows you to run this workflow manually from the Actions tab | ||
| workflow_dispatch: | ||
|
|
||
| env: | ||
| BUILD_TYPE: RelWithDebInfo | ||
|
|
||
| jobs: | ||
| build-appimage: | ||
| runs-on: ubuntu-22.04 | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Update Package Database | ||
| run: sudo apt-get update | ||
|
|
||
| - name: Install Dependencies | ||
| run: sudo apt-get install libgtkmm-3.0-dev gettext wget file | ||
|
|
||
| - name: Download linuxdeploy | ||
| run: | | ||
| wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage | ||
| chmod +x linuxdeploy-x86_64.AppImage | ||
| sudo mv linuxdeploy-x86_64.AppImage /usr/local/bin/linuxdeploy | ||
|
|
||
| - name: Download appimagetool | ||
| run: | | ||
| wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage | ||
| chmod +x appimagetool-x86_64.AppImage | ||
| sudo mv appimagetool-x86_64.AppImage /usr/local/bin/appimagetool | ||
|
ashaduri marked this conversation as resolved.
|
||
|
|
||
| - name: Create Build Directory | ||
| run: cmake -E make_directory build-appimage | ||
|
|
||
| - name: Configure CMake for AppImage | ||
| shell: bash | ||
| working-directory: ${{github.workspace}}/build-appimage | ||
| env: | ||
| CC: gcc-11 | ||
| CXX: g++-11 | ||
| run: > | ||
| cmake $GITHUB_WORKSPACE | ||
| -DCMAKE_BUILD_TYPE=$BUILD_TYPE | ||
| -DCMAKE_INSTALL_PREFIX=/usr | ||
| -DAPP_BUILD_APPIMAGE=ON | ||
| -DCMAKE_TOOLCHAIN_FILE="$GITHUB_WORKSPACE/toolchains/linux-dev.cmake" | ||
|
|
||
| - name: Build | ||
| shell: bash | ||
| working-directory: ${{github.workspace}}/build-appimage | ||
| run: cmake --build . --config $BUILD_TYPE -j$(nproc) | ||
|
|
||
| - name: Install to AppDir | ||
| shell: bash | ||
| working-directory: ${{github.workspace}}/build-appimage | ||
| run: DESTDIR=${{github.workspace}}/AppDir cmake --install . | ||
|
|
||
| - name: Setup AppDir structure | ||
| shell: bash | ||
| working-directory: ${{github.workspace}} | ||
| run: | | ||
| # Copy desktop file and icon to AppDir root | ||
| cp AppDir/usr/share/applications/dev.shaduri.gsmartcontrol.desktop AppDir/ | ||
| cp AppDir/usr/share/icons/hicolor/256x256/apps/gsmartcontrol.png AppDir/ | ||
|
|
||
| # Create AppRun script | ||
| cat > AppDir/AppRun << 'EOF' | ||
| #!/bin/bash | ||
| SELF=$(readlink -f "$0") | ||
| HERE=${SELF%/*} | ||
| export LD_LIBRARY_PATH="$HERE/usr/lib:${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" | ||
| export PATH="$HERE/usr/bin:${PATH:+:$PATH}" | ||
| export GSETTINGS_SCHEMA_DIR="$HERE/usr/share/glib-2.0/schemas:${GSETTINGS_SCHEMA_DIR:+:$GSETTINGS_SCHEMA_DIR}" | ||
| export GDK_PIXBUF_MODULEDIR="$HERE/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" | ||
| export GDK_PIXBUF_MODULE_FILE="$HERE/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" | ||
| exec "$HERE/usr/bin/gsmartcontrol" "$@" | ||
| EOF | ||
| chmod +x AppDir/AppRun | ||
|
|
||
| - name: Bundle dependencies with linuxdeploy | ||
| shell: bash | ||
| working-directory: ${{github.workspace}} | ||
| run: | | ||
| linuxdeploy --appdir AppDir \ | ||
| --executable AppDir/usr/bin/gsmartcontrol \ | ||
| --desktop-file AppDir/dev.shaduri.gsmartcontrol.desktop \ | ||
| --icon-file AppDir/gsmartcontrol.png | ||
|
|
||
| - name: Update GDK pixbuf cache | ||
| shell: bash | ||
| working-directory: ${{github.workspace}} | ||
| continue-on-error: true | ||
| run: | | ||
| if [ -d "AppDir/usr/lib/gdk-pixbuf-2.0" ]; then | ||
| gdk-pixbuf-query-loaders > AppDir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache || true | ||
| fi | ||
|
|
||
| - name: Get version | ||
| id: version | ||
| shell: bash | ||
| run: | | ||
| VERSION=$(grep "CMAKE_PROJECT_VERSION" version.txt | cut -d'=' -f2 | tr -d ' ') | ||
|
ashaduri marked this conversation as resolved.
Outdated
|
||
| echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | ||
| echo "Version: $VERSION" | ||
|
|
||
| - name: Create AppImage | ||
| shell: bash | ||
| working-directory: ${{github.workspace}} | ||
| run: | | ||
| ARCH=x86_64 appimagetool AppDir GSmartControl-${{ steps.version.outputs.VERSION }}-x86_64.AppImage | ||
|
|
||
| - name: Upload AppImage artifact | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: GSmartControl AppImage | ||
| path: ${{github.workspace}}/GSmartControl-*-x86_64.AppImage | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,7 +7,13 @@ | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Generate files | ||||||||||||||||||||||||||
| configure_file("gsmartcontrol.appdata.in.xml" "gsmartcontrol.appdata.xml" ESCAPE_QUOTES @ONLY) | ||||||||||||||||||||||||||
| configure_file("gsmartcontrol.in.desktop" "gsmartcontrol.desktop" ESCAPE_QUOTES @ONLY) | ||||||||||||||||||||||||||
| if (APP_BUILD_APPIMAGE) | ||||||||||||||||||||||||||
| set(APPIMAGE_EXEC_LINE "Exec=\"@CMAKE_INSTALL_FULL_BINDIR@/gsmartcontrol\"") | ||||||||||||||||||||||||||
| configure_file("gsmartcontrol.in.desktop" "dev.shaduri.gsmartcontrol.desktop" ESCAPE_QUOTES @ONLY) | ||||||||||||||||||||||||||
| else() | ||||||||||||||||||||||||||
| set(APPIMAGE_EXEC_LINE "Exec=\"@CMAKE_INSTALL_FULL_BINDIR@/gsmartcontrol-root\"") | ||||||||||||||||||||||||||
|
ashaduri marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||
| configure_file("gsmartcontrol.in.desktop" "gsmartcontrol.desktop" ESCAPE_QUOTES @ONLY) | ||||||||||||||||||||||||||
|
Comment on lines
+13
to
+18
|
||||||||||||||||||||||||||
| configure_file("gsmartcontrol.in.desktop" "dev.shaduri.gsmartcontrol.desktop" ESCAPE_QUOTES @ONLY) | |
| else() | |
| set(APPIMAGE_DESKTOP_ID "gsmartcontrol") | |
| set(APPIMAGE_EXEC_LINE "Exec=\"${CMAKE_INSTALL_FULL_BINDIR}/gsmartcontrol-root\"") | |
| configure_file("gsmartcontrol.appdata.in.xml" "gsmartcontrol.appdata.xml" ESCAPE_QUOTES @ONLY) | |
| configure_file("gsmartcontrol.in.desktop" "gsmartcontrol.desktop" ESCAPE_QUOTES @ONLY) | |
| configure_file("gsmartcontrol.in.desktop" "dev.shaduri.gsmartcontrol.desktop" @ONLY) | |
| else() | |
| set(APPIMAGE_DESKTOP_ID "gsmartcontrol") | |
| set(APPIMAGE_EXEC_LINE "Exec=\"${CMAKE_INSTALL_FULL_BINDIR}/gsmartcontrol-root\"") | |
| configure_file("gsmartcontrol.appdata.in.xml" "gsmartcontrol.appdata.xml" ESCAPE_QUOTES @ONLY) | |
| configure_file("gsmartcontrol.in.desktop" "gsmartcontrol.desktop" @ONLY) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # GSmartControl AppImage Build | ||
|
|
||
| This directory contains scripts and configurations for building GSmartControl as an AppImage. | ||
|
|
||
| ## What is AppImage? | ||
|
|
||
| AppImage is a format for distributing portable software on Linux without requiring installation. AppImages are self-contained applications that can run on most Linux distributions. | ||
|
|
||
| ## Building the AppImage | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| You need to have the following installed: | ||
| - cmake (>= 3.14) | ||
| - g++ or clang with C++20 support | ||
| - GTK3 and gtkmm-3.0 development packages | ||
| - smartmontools (for runtime) | ||
| - linuxdeploy and appimagetool (the script will download them if not available) | ||
|
|
||
| On Ubuntu/Debian: | ||
| ```bash | ||
| sudo apt-get install cmake g++ libgtkmm-3.0-dev gettext smartmontools | ||
| ``` | ||
|
|
||
| On Fedora: | ||
| ```bash | ||
| sudo dnf install cmake gcc-c++ gtkmm30-devel gettext smartmontools | ||
| ``` | ||
|
|
||
| ### Build Steps | ||
|
|
||
| From the repository root directory, run: | ||
|
|
||
| ```bash | ||
| ./packaging/appimage/build-appimage.sh | ||
| ``` | ||
|
|
||
| The script will: | ||
| 1. Configure CMake with `-DAPP_BUILD_APPIMAGE=ON` | ||
| 2. Build the application | ||
| 3. Create an AppDir with the proper structure | ||
| 4. Bundle dependencies using linuxdeploy | ||
| 5. Create the final AppImage file | ||
|
|
||
| ### Output | ||
|
|
||
| The script creates an AppImage file named `GSmartControl-<version>-<arch>.AppImage` in the repository root. | ||
|
|
||
| ## Running the AppImage | ||
|
|
||
| **Important:** GSmartControl requires root privileges to access disk drives. You must run the AppImage with sudo: | ||
|
|
||
| ```bash | ||
| sudo ./GSmartControl-<version>-x86_64.AppImage | ||
| ``` | ||
|
|
||
| ### Why sudo is required? | ||
|
|
||
| - AppImage format does not support embedded privilege escalation scripts | ||
| - The binary must be executed directly as root to access `/dev/sd*` and `/dev/nvme*` devices | ||
| - This is different from traditional package installations which use the `gsmartcontrol-root` wrapper script | ||
|
|
||
| ## AppImage-Specific Changes | ||
|
|
||
| When building with `-DAPP_BUILD_APPIMAGE=ON`, the following changes are applied: | ||
|
|
||
| 1. **Data file paths**: Uses relative paths from binary location (`bin/../share/...`) | ||
| 2. **Desktop file**: | ||
| - Uses rDNS format: `dev.shaduri.gsmartcontrol.desktop` | ||
| - Executes binary directly without `gsmartcontrol-root` wrapper | ||
| 3. **Binary location**: Installed to `bin/` instead of `sbin/` | ||
| 4. **No wrapper script**: `gsmartcontrol-root` is not installed | ||
|
|
||
| ## Compatibility | ||
|
|
||
| The AppImage should work on: | ||
| - Fedora Atomic (Silverblue, Kinoite, etc.) | ||
| - Most modern Linux distributions with GTK3 support | ||
| - Systems with read-only root filesystems | ||
|
|
||
| Tested architectures: | ||
| - x86_64 (Intel/AMD 64-bit) | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### "Permission denied" when running AppImage | ||
| Make the AppImage executable: | ||
| ```bash | ||
| chmod +x GSmartControl-*.AppImage | ||
| ``` | ||
|
|
||
| ### "No drives detected" | ||
| Make sure to run with sudo: | ||
| ```bash | ||
| sudo ./GSmartControl-*.AppImage | ||
| ``` | ||
|
|
||
| ### GTK theme issues | ||
| You may need to install GTK3 themes on your system. The AppImage bundles the necessary libraries but uses system themes when available. | ||
|
|
||
| ## Notes for Developers | ||
|
|
||
| - The AppImage build uses the same source code as regular builds | ||
| - The `BuildEnv::is_appimage_build()` function can be used to detect AppImage builds at runtime | ||
| - Icon and UI file paths are resolved at runtime relative to the binary location | ||
| - The AppImage includes all necessary GTK3 and gtkmm libraries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workflow downloads
linuxdeployandappimagetoolfromcontinuouswithout checksum verification, which is a supply-chain risk and doesn’t match the PR description (pinned versions + SHA256 verification). Pin the exact release assets and verify SHA256 before installing them into/usr/local/bin.