mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 12:13:27 +00:00
Port AppImage build to use appimage-builder (#1785)
* Initial port to appimage-builder
* Almost
* Fix appimage build on arm64
* Custom patch for external binaries run under appimage
- Disable bubblewrap sandbox when running under appimage
- Change cwd to APPDIR when running under appimage
* AppImage Works (for the first lunch, then it crashes with Stack Smash 😭)
* Fix stack smashing, now AppImage almos fully works \o/ (gstreamer is still broken)
- Temporarily disable the volume watcher when running under appimage (Workaround for the stack smash error)
- Wrap gnu lic version check for appimage under conditional compile for glibc targets
- Add error handling for the justUpdatedCheck
- Fix VITE_LANDING_ORIGIN being undefined
* On non glibc systems default to runtime/compat
* Use glibc version 2.8 instead of 0 for non-gnu systems
* Fix video playback not working due to broken GstRegistry
* Build and publish new AppImage release artifact
- Fix model location when building deb
- Improve model path resolution logic
- Remove patchelf dependency from setup script
- Fix incorrectly ignore gstreamer dependency in AppImage recipe
* Fix clippy complaining about `get_path_relative_to_exe`
- Read GLIBC_FAKE_VERSION or use 2.8 for musl in appimage (while the code is there, this is not really supported for now)
* Remove appimage tauri target from release CI
* Remove setup-buildx-action, not relly needed
* typo fix
* Fix git describe command running on cwd instead of the repo root dir
* Attempt fix weird git permissions errors in CI+docker
* Pass CI env to docker appimage
* Only use git after installing it
* Pass target to appimage build script
* Fix permission after creating appimage
* -_-
* Swap envvar with github ci var
* Format
* Add instruction on how to manually build an AppImage
* Fix typos
* docs: add note about running podman with `--privileged` if there's a permission denied error
* docs: fix typo and link directly to appimage-building `README.md`
* refactor: streamline code and make it a bit cleaner
---------
Co-authored-by: jake <77554505+brxken128@users.noreply.github.com>
This commit is contained in:
parent
352828ada3
commit
556ddbd4f8
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
|
@ -28,14 +28,14 @@ jobs:
|
|||
# target: aarch64-pc-windows-msvc
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
bundles: deb,appimage
|
||||
bundles: deb
|
||||
os: linux
|
||||
arch: x86_64
|
||||
# - host: ubuntu-20.04
|
||||
# target: x86_64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
# bundles: deb # no appimage for now unfortunetly
|
||||
# bundles: deb
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-musl
|
||||
name: Desktop - Main ${{ matrix.settings.target }}
|
||||
|
@ -113,6 +113,16 @@ jobs:
|
|||
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
|
||||
- name: Build AppImage in Docker
|
||||
if: ${{ runner.os == 'Linux' && ( matrix.settings.target == 'x86_64-unknown-linux-gnu' || matrix.settings.target == 'aarch64-unknown-linux-gnu' ) }}
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
docker run --rm -v $(pwd):/srv -e 'CI=true' -e 'TARGET=${{ matrix.settings.target }}' -w /srv debian:bookworm scripts/appimage/build_appimage.sh
|
||||
cd 'target/${{ matrix.settings.target }}/release/bundle/appimage'
|
||||
sudo chown "$(id -u):$(id -g)" -R .
|
||||
tar -czf Updater.AppImage.tar.gz *.AppImage
|
||||
pnpm tauri signer sign -k '${{ secrets.TAURI_PRIVATE_KEY }}' -p '${{ secrets.TAURI_KEY_PASSWORD }}' "$(pwd)/Updater.AppImage.tar.gz"
|
||||
|
||||
- name: Publish Artifacts
|
||||
uses: ./.github/actions/publish-artifacts
|
||||
with:
|
||||
|
|
|
@ -95,6 +95,10 @@ To run the mobile app:
|
|||
- `pnpm ios` (runs on iOS Emulator)
|
||||
- `pnpm start` (runs the metro bundler)
|
||||
|
||||
##### AppImage
|
||||
|
||||
Specific instructions on how to build an AppImage release are located [here](scripts/appimage/README.md)
|
||||
|
||||
### Pull Request
|
||||
|
||||
Once you have finished making your changes, create a pull request (PR) to submit them.
|
||||
|
@ -134,7 +138,7 @@ error: terminated(1): /us/bin/xcrun --sdk macos --show-sdk-platform-path output
|
|||
xcrun: error: unable to lookup item 'PlatformPath' from command line tools installation xcrun: error: unable to lookup item 'PlatformPath' in SDK '/Library/Developer /CommandLineTools/SDKs/MacOSX.sdk'
|
||||
```
|
||||
|
||||
Ensure that macOS is fully updated, and that you have XCode installed (via the app store).
|
||||
Ensure that macOS is fully updated, and that you have Xcode installed (via the app store).
|
||||
|
||||
Once that has completed, run `xcode-select --install` in the terminal to install the command line tools. If they are already installed, ensure that you update macOS to the latest version available.
|
||||
|
||||
|
|
|
@ -11,4 +11,5 @@ libc = "0.2"
|
|||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
# WARNING: gtk should follow the same version used by tauri
|
||||
gtk = "=0.15"
|
||||
# https://github.com/tauri-apps/tauri/blob/441eb4f4a5f9af206752c2e287975eb8d5ccfd01/core/tauri/Cargo.toml#L95
|
||||
gtk = { version = "0.15", features = [ "v3_20" ] }
|
||||
|
|
|
@ -2,12 +2,28 @@ use std::{
|
|||
collections::HashSet,
|
||||
env,
|
||||
ffi::{CStr, OsStr, OsString},
|
||||
mem,
|
||||
io, mem,
|
||||
os::unix::ffi::OsStrExt,
|
||||
path::{Path, PathBuf},
|
||||
ptr,
|
||||
};
|
||||
|
||||
fn version(version_str: &str) -> i32 {
|
||||
let mut version_parts: Vec<i32> = version_str
|
||||
.split('.')
|
||||
.take(4) // Take up to 4 components
|
||||
.map(|part| part.parse().unwrap_or(0))
|
||||
.collect();
|
||||
|
||||
// Pad with zeros if needed
|
||||
version_parts.resize_with(4, Default::default);
|
||||
|
||||
(version_parts[0] * 1_000_000_000)
|
||||
+ (version_parts[1] * 1_000_000)
|
||||
+ (version_parts[2] * 1_000)
|
||||
+ version_parts[3]
|
||||
}
|
||||
|
||||
pub fn get_current_user_home() -> Option<PathBuf> {
|
||||
use libc::{getpwuid_r, getuid, passwd, ERANGE};
|
||||
|
||||
|
@ -175,6 +191,56 @@ pub fn normalize_environment() {
|
|||
],
|
||||
)
|
||||
.expect("PATH must be successfully normalized");
|
||||
|
||||
if let Ok(appdir) = get_appdir() {
|
||||
println!("Running from APPIMAGE");
|
||||
|
||||
// Workaround for https://github.com/AppImageCrafters/appimage-builder/issues/175
|
||||
env::set_current_dir(appdir.join({
|
||||
let appimage_libc_version = version(
|
||||
std::env::var("APPDIR_LIBC_VERSION")
|
||||
.expect("AppImage Libc version must be set")
|
||||
.as_str(),
|
||||
);
|
||||
|
||||
let system_lic_version = version({
|
||||
#[cfg(target_env = "gnu")]
|
||||
{
|
||||
use libc::gnu_get_libc_version;
|
||||
|
||||
let ptr = unsafe { gnu_get_libc_version() };
|
||||
if ptr.is_null() {
|
||||
panic!("Couldn't read glic version");
|
||||
}
|
||||
|
||||
unsafe { CStr::from_ptr(ptr) }
|
||||
.to_str()
|
||||
.expect("Couldn't read glic version")
|
||||
}
|
||||
#[cfg(not(target_env = "gnu"))]
|
||||
{
|
||||
// Use the same version as gcompat
|
||||
// https://git.adelielinux.org/adelie/gcompat/-/blob/current/libgcompat/version.c
|
||||
std::env::var("GLIBC_FAKE_VERSION").unwrap_or_else(|_| "2.8".to_string())
|
||||
}
|
||||
});
|
||||
|
||||
if system_lic_version < appimage_libc_version {
|
||||
"runtime/compat"
|
||||
} else {
|
||||
"runtime/default"
|
||||
}
|
||||
}))
|
||||
.expect("Failed to set current directory to $APPDIR");
|
||||
|
||||
// Bubblewrap does not work from inside appimage
|
||||
env::set_var("WEBKIT_FORCE_SANDBOX", "0");
|
||||
env::set_var("WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS", "1");
|
||||
|
||||
// FIX-ME: This is required because appimage-builder generates a broken GstRegistry, which breaks video playback
|
||||
env::remove_var("GST_REGISTRY");
|
||||
env::remove_var("GST_REGISTRY_UPDATE");
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn remove_prefix_from_pathlist(
|
||||
|
@ -205,13 +271,19 @@ pub fn is_snap() -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
fn get_appdir() -> io::Result<PathBuf> {
|
||||
if let Some(appdir) = std::env::var_os("APPDIR").map(PathBuf::from) {
|
||||
if appdir.is_absolute() && appdir.is_dir() {
|
||||
return Ok(appdir);
|
||||
}
|
||||
}
|
||||
|
||||
Err(io::Error::new(io::ErrorKind::NotFound, "AppDir not found"))
|
||||
}
|
||||
|
||||
// Check if appimage by looking if APPDIR is set and is a valid directory
|
||||
pub fn is_appimage() -> bool {
|
||||
if let Some(appdir) = std::env::var_os("APPDIR").map(PathBuf::from) {
|
||||
appdir.is_absolute() && appdir.is_dir()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
get_appdir().is_ok()
|
||||
}
|
||||
|
||||
// Check if flatpak by looking if FLATPAK_ID is set and not empty and that the .flatpak-info file exists
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"longDescription": "Cross-platform universal file explorer, powered by an open-source virtual distributed filesystem.",
|
||||
"deb": {
|
||||
"files": {
|
||||
"/usr/share/models/yolov8s.onnx": "../../.deps/models/yolov8s.onnx"
|
||||
"/usr/share/spacedrive/models/yolov8s.onnx": "../../.deps/models/yolov8s.onnx"
|
||||
},
|
||||
"depends": ["libc6"]
|
||||
},
|
||||
|
|
|
@ -6,5 +6,7 @@ export const env = createEnv({
|
|||
client: {
|
||||
VITE_LANDING_ORIGIN: z.string().default('https://www.spacedrive.com')
|
||||
},
|
||||
runtimeEnv: import.meta.env
|
||||
runtimeEnv: import.meta.env,
|
||||
skipValidation: false,
|
||||
emptyStringAsUndefined: true
|
||||
});
|
||||
|
|
|
@ -96,15 +96,23 @@ export function createUpdater() {
|
|||
|
||||
if (lastVersion !== version) {
|
||||
localStorage.setItem(SD_VERSION_LOCALSTORAGE, version);
|
||||
let tagline = null;
|
||||
|
||||
const { frontmatter } = await fetch(
|
||||
`${import.meta.env.VITE_LANDING_ORIGIN}/api/releases/${version}`
|
||||
).then((r) => r.json());
|
||||
try {
|
||||
const request = await fetch(
|
||||
`${import.meta.env.VITE_LANDING_ORIGIN}/api/releases/${version}`
|
||||
);
|
||||
const { frontmatter } = await request.json();
|
||||
tagline = frontmatter?.tagline;
|
||||
} catch (error) {
|
||||
console.warn('Failed to fetch release info');
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
toast.success(
|
||||
{
|
||||
title: `Updated successfully, you're on version ${version}`,
|
||||
body: frontmatter?.tagline
|
||||
body: tagline
|
||||
},
|
||||
{
|
||||
duration: 10 * 1000,
|
||||
|
|
|
@ -41,5 +41,6 @@ export const env = createEnv({
|
|||
},
|
||||
// In dev or in eslint disable checking.
|
||||
// Kinda sucks for in dev but you don't need the whole setup to change the docs.
|
||||
skipValidation: process.env.VERCEL !== '1'
|
||||
skipValidation: process.env.VERCEL !== '1',
|
||||
emptyStringAsUndefined: true
|
||||
});
|
||||
|
|
|
@ -133,8 +133,8 @@ impl Libraries {
|
|||
.load(library_id, &db_path, config_path, None, true, node)
|
||||
.await?;
|
||||
|
||||
// This is compleaty breaking on linux now, no ideia why, but it will be irrelevant in a short while
|
||||
// So let's leave it disable for now
|
||||
// FIX-ME: Linux releases crashes with *** stack smashing detected *** if spawn_volume_watcher is enabled
|
||||
// No ideia why, but this will be irrelevant after the UDisk API is implemented, so let's leave it disabled for now
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
use crate::volume::watcher::spawn_volume_watcher;
|
||||
|
|
|
@ -14,12 +14,14 @@ pub(crate) fn get_path_relative_to_exe(path: impl AsRef<Path>) -> PathBuf {
|
|||
.into()
|
||||
})
|
||||
.parent()
|
||||
.and_then(|parent_path| {
|
||||
parent_path
|
||||
.join(path.as_ref())
|
||||
.canonicalize()
|
||||
.map_err(|e| error!("{e:#?}"))
|
||||
.ok()
|
||||
})
|
||||
.unwrap_or_else(|| path.as_ref().to_path_buf())
|
||||
.map_or_else(
|
||||
|| path.as_ref().to_path_buf(),
|
||||
|parent| {
|
||||
let path = parent.join(path.as_ref());
|
||||
path.canonicalize().unwrap_or_else(|e| {
|
||||
error!("Failed to canonilize relative path to exe, return raw path and hope: {e:#?}");
|
||||
path
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
2
scripts/appimage/.gitignore
vendored
Normal file
2
scripts/appimage/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
AppDir
|
||||
appimage-build
|
165
scripts/appimage/AppImageBuilder.yml
Normal file
165
scripts/appimage/AppImageBuilder.yml
Normal file
|
@ -0,0 +1,165 @@
|
|||
# Reference:
|
||||
# https://appimage-builder.readthedocs.io/en/latest/reference/version_1.html
|
||||
|
||||
version: 1
|
||||
|
||||
script: |
|
||||
set -eu
|
||||
# Clean up directories created by the recipe
|
||||
rm "$TARGET_APPDIR" -rf || true
|
||||
rm "$REPO_DIR" -rf || true
|
||||
# Create a temporary Debian repository folder to put the generated Debian
|
||||
# packages on, so we can install it like any other packages
|
||||
mkdir -p "$REPO_DIR"
|
||||
_deb="$(find "${TARGET_APPIMAGE_DIR}/../deb" -type f -name '*.deb' | sort -t '_' -k '2,2' -V | tail -n 1)"
|
||||
cp -f "$_deb" "$REPO_DIR"
|
||||
CWD="$PWD" && cd "$REPO_DIR" && apt-ftparchive packages . > Packages && cd "$CWD"
|
||||
# The following two commands are a workaround for the local APT package not
|
||||
# being saved to the archives directory, as expected by appimage-builder
|
||||
mkdir -p appimage-build/apt/archives
|
||||
cp -f "$_deb" appimage-build/apt/archives
|
||||
|
||||
AppDir:
|
||||
path: !ENV '${TARGET_APPDIR}'
|
||||
|
||||
app_info:
|
||||
id: com.spacedrive
|
||||
name: Spacedrive
|
||||
icon: spacedrive
|
||||
version: !ENV '${VERSION}'
|
||||
exec: usr/bin/spacedrive
|
||||
exec_args: $@
|
||||
|
||||
apt:
|
||||
arch: !ENV ${TARGET_APPIMAGE_APT_ARCH}
|
||||
sources:
|
||||
- sourceline: !ENV 'deb [arch=${TARGET_APPIMAGE_APT_ARCH}] http://deb.debian.org/debian bookworm main'
|
||||
key_url: 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1f89983e0081fde018f3cc9673a4f27b8dd47936'
|
||||
- sourceline: !ENV 'deb [arch=${TARGET_APPIMAGE_APT_ARCH}] http://security.debian.org/debian-security bookworm-security main'
|
||||
key_url: 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1f89983e0081fde018f3cc9673a4f27b8dd47936'
|
||||
- sourceline: !ENV 'deb [arch=${TARGET_APPIMAGE_APT_ARCH}] http://deb.debian.org/debian bookworm-updates main'
|
||||
key_url: 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xac530d520f2f3269f5e98313a48449044aad5c5d'
|
||||
- sourceline: !ENV 'deb [trusted=yes] file:${REPO_DIR}/ ./'
|
||||
|
||||
include:
|
||||
- spacedrive
|
||||
- gstreamer1.0-plugins-good
|
||||
- gstreamer1.0-plugins-ugly
|
||||
- gstreamer1.0-packagekit
|
||||
# This package is necessary to avoid this: https://github.com/AppImageCrafters/appimage-builder/pull/191
|
||||
- shared-mime-info
|
||||
|
||||
exclude:
|
||||
- systemd
|
||||
- systemd-sysv
|
||||
- util-linux
|
||||
- util-linux-extra
|
||||
- xkb-data
|
||||
- fdisk
|
||||
- dmsetup
|
||||
- mount
|
||||
- dbus-daemon
|
||||
- perl-base
|
||||
- readline-common
|
||||
- libpam-modules
|
||||
- avahi-daemon
|
||||
- adwaita-icon-theme
|
||||
- humanity-icon-theme
|
||||
- sensible-utils
|
||||
- dconf-service
|
||||
- ubuntu-mono
|
||||
- fonts-*-core
|
||||
- bubblewrap
|
||||
- gstreamer1.0-plugins-bad
|
||||
- gstreamer1.0-libav
|
||||
|
||||
files:
|
||||
exclude:
|
||||
# Development, localization, documentation and configuration files
|
||||
- usr/include
|
||||
- usr/share/bug
|
||||
- usr/share/man
|
||||
- usr/share/doc
|
||||
- usr/share/doc-base
|
||||
- usr/share/lintian
|
||||
- usr/share/sounds
|
||||
- usr/share/bash-completion
|
||||
- usr/share/zsh
|
||||
- usr/share/applications
|
||||
- usr/share/pkgconfig
|
||||
- usr/share/pam
|
||||
- usr/share/pam-configs
|
||||
- usr/share/polkit-1
|
||||
- usr/share/util-linux
|
||||
- usr/share/initramfs-tools
|
||||
- usr/share/locale
|
||||
- usr/share/systemd
|
||||
- usr/lib/systemd
|
||||
- usr/lib/*-linux-gnu/systemd
|
||||
- usr/lib/udev
|
||||
- usr/lib/*.d
|
||||
- usr/lib/kernel
|
||||
- usr/lib/tmpfiles.d
|
||||
# using our own ALSA can cause issues, and the API is pretty stable anyway
|
||||
- usr/lib/*/libasound.so.*
|
||||
# produced by library compilation
|
||||
- usr/lib/*.a
|
||||
# produced by library compilation
|
||||
- usr/lib/cmake
|
||||
# produced by library compilation
|
||||
- usr/lib/pkgconfig
|
||||
- etc
|
||||
- var
|
||||
# systemd, pam, lsb, modprobe.d, udev and misc daemon files
|
||||
- lib/systemd
|
||||
- lib/*-linux-gnu/security
|
||||
- lib/udev
|
||||
- lib/lsb
|
||||
- lib/modprobe.d
|
||||
# Unneeded utility programs and libraries
|
||||
- usr/sbin
|
||||
# Remove any binary but spacedrive
|
||||
- usr/bin/[!s]*
|
||||
- usr/bin/s[!p]*
|
||||
- usr/bin/sp[!a]*
|
||||
- usr/bin/spa[!c]*
|
||||
- usr/bin/spac[!e]*
|
||||
- sbin
|
||||
- bin
|
||||
|
||||
runtime:
|
||||
path_mappings:
|
||||
- !ENV '/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu/webkit2gtk-4.0/injected-bundle/libwebkit2gtkinjectedbundle.so:$APPDIR/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu/webkit2gtk-4.0/injected-bundle/libwebkit2gtkinjectedbundle.so'
|
||||
|
||||
# Patch webkit2gtk so it works under appimage
|
||||
after_bundle: |
|
||||
set -eux
|
||||
|
||||
# libwebkit2gtk Patch for WebKit binaries
|
||||
mv "${TARGET_APPDIR}/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu/webkit2gtk-4.0/WebKitWebProcess" "${TARGET_APPDIR}/usr/bin/WebKitWebProcess"
|
||||
mv "${TARGET_APPDIR}/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu/webkit2gtk-4.0/WebKitNetworkProcess" "${TARGET_APPDIR}/usr/bin/WebKitNetworkProcess"
|
||||
if [ "$TARGET_APPIMAGE_ARCH" == 'aarch64' ]; then
|
||||
find "${TARGET_APPDIR}/usr/lib/aarch64-linux-gnu" -type f -name 'libwebkit2gtk-4.0.so*' -exec sed -i -e "s|/usr/lib/aarch64-linux-gnu/webkit2gtk-4.0\([^/][^i][^n]\)|../../././././././././././././././usr/bin\1|g" '{}' \;
|
||||
else
|
||||
find "${TARGET_APPDIR}/usr/lib/x86_64-linux-gnu" -type f -name 'libwebkit2gtk-4.0.so*' -exec sed -i -e "s|/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0\([^/][^i][^n]\)|../.././././././././././././././usr/bin/\1|g" '{}' \;
|
||||
fi
|
||||
|
||||
# libwebkit2gtk Patch for gstreamer binaries
|
||||
mv "${TARGET_APPDIR}/usr/libexec/pk-gstreamer-install" "${TARGET_APPDIR}/usr/bin/pk-gstreamer-install"
|
||||
ln -sf pk-gstreamer-install "${TARGET_APPDIR}/usr/bin/gst-install-plugins-helper"
|
||||
mv "${TARGET_APPDIR}/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper" "${TARGET_APPDIR}/usr/bin/gst-ptp-helper"
|
||||
mv "${TARGET_APPDIR}/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner" "${TARGET_APPDIR}/usr/bin/gst-plugin-scanner"
|
||||
find "${TARGET_APPDIR}/usr/lib/${TARGET_APPIMAGE_ARCH}-linux-gnu" -type f -name 'libwebkit2gtk-4.0.so*' -exec sed -i -e "s|/usr/libexec/gstreamer-1.0|../../././././././usr/bin/|g" '{}' \;
|
||||
|
||||
after_runtime: |
|
||||
set -eux
|
||||
|
||||
find "$TARGET_APPDIR" -type d -empty -delete
|
||||
|
||||
# Tests don't work due to Tauri security checks we can't work around:
|
||||
# https://github.com/tauri-apps/tauri/blob/35264b4c1801b381e0b867c1c35540f0fbb43365/core/tauri-utils/src/lib.rs#L202
|
||||
|
||||
AppImage:
|
||||
arch: !ENV '${TARGET_APPIMAGE_ARCH}'
|
||||
sign-key: None
|
||||
update-information: None
|
30
scripts/appimage/README.md
Normal file
30
scripts/appimage/README.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# AppImage build script and files
|
||||
|
||||
This directory contains the script and recipe to build an AppImage from a Spacedrive `.deb` using [appimage-builder](https://appimage-builder.readthedocs.io/en/latest/index.html).
|
||||
|
||||
## Instructions (Requires a Linux environment)
|
||||
|
||||
- Install one of the following container runtimes:
|
||||
|
||||
- [Podman](https://podman.io/docs/installation#installing-on-linux)
|
||||
|
||||
- [Docker](https://docs.docker.com/engine/install/#supported-platforms)
|
||||
|
||||
- Set up your development environment following the steps in the [CONTRIBUTING](../../CONTRIBUTING.md) guide
|
||||
|
||||
- Build a production release of Spacedrive by invoking `pnpm tauri` in a terminal window inside the Spacedrive repository root
|
||||
|
||||
> After the build finishes you should end up with a `.deb` archive in `target/release/bundle/deb`
|
||||
|
||||
- Change your current work directory to `scripts/appimage`
|
||||
|
||||
- Execute the `build_appimage.sh` script inside a `debian:bookworm` container
|
||||
|
||||
- Podman: `podman run --rm -v "$(CDPATH='' cd ../.. && pwd -P):/srv" -w /srv debian:bookworm scripts/appimage/build_appimage.sh`
|
||||
- You may have to run Podman with `podman run --privileged` if you get a permission denied error
|
||||
|
||||
- Docker: `docker run --rm -v "$(CDPATH='' cd ../.. && pwd -P):/srv" -w /srv debian:bookworm scripts/appimage/build_appimage.sh`
|
||||
|
||||
> If you are running a system with selinux enforcing you will need mount the `/srv` volume with the `Z` flag to avoid `Permission denied` errors. [more info](https://docs.podman.io/en/latest/markdown/podman-run.1.html#volume-v-source-volume-host-dir-container-dir-options)
|
||||
|
||||
> After the script finishes you should end up with an `.AppImage` executable in `target/release/bundle/appimage`
|
92
scripts/appimage/build_appimage.sh
Executable file
92
scripts/appimage/build_appimage.sh
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Creates an AppImage with the specified Rust package binary and its dependencies.
|
||||
# AppImage is an universal Linux application distribution format, similar
|
||||
# to macOS bundles, which packs an application and its dependencies to
|
||||
# allow running it across a wide variety of distros with no system changes
|
||||
# and little user hassle.
|
||||
#
|
||||
# Relevant documentation:
|
||||
# https://docs.appimage.org/packaging-guide/index.html
|
||||
# https://appimage-builder.readthedocs.io/en/latest/index.html
|
||||
|
||||
set -eEuo pipefail
|
||||
|
||||
if [ "${CI:-}" = "true" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
_root="$(CDPATH='' cd "$(dirname -- "$0")" && pwd -P)"
|
||||
readonly _root
|
||||
|
||||
# The appimage-builder recipe to use to generate the AppImage.
|
||||
readonly RECIPE="${_root}/AppImageBuilder.yml"
|
||||
|
||||
# The directory where the generated AppImage bundles will be stored.
|
||||
readonly TARGET_APPIMAGE_DIR="${_root}/../../target/${TARGET:-.}/release/bundle/appimage"
|
||||
export TARGET_APPIMAGE_DIR
|
||||
|
||||
alias wget='wget -nc -nv --show-progress -P "$APPIMAGE_WORKDIR"'
|
||||
|
||||
# Create a temporary working directory for this AppImage script
|
||||
APPIMAGE_WORKDIR=$(mktemp -d -t spacedrive-appimagebuild.XXX)
|
||||
readonly APPIMAGE_WORKDIR
|
||||
trap '{ rm -rf "$APPIMAGE_WORKDIR" || true; } && { rm -rf appimage-build AppDir || true; }' EXIT INT TERM
|
||||
|
||||
# Install required system dependencies
|
||||
echo 'Installind required system dependencies...'
|
||||
apt-get update && apt-get install -yq \
|
||||
git \
|
||||
zsync \
|
||||
dpkg-dev \
|
||||
apt-utils \
|
||||
libffi-dev \
|
||||
squashfs-tools \
|
||||
libglib2.0-bin \
|
||||
gstreamer1.0-tools \
|
||||
libgdk-pixbuf2.0-bin \
|
||||
gtk-update-icon-cache
|
||||
|
||||
if [ "${CI:-}" = "true" ]; then
|
||||
git config --global --add safe.directory '*'
|
||||
fi
|
||||
|
||||
# gdk-pixbuf-query-loaders is not in PATH by default
|
||||
ln -fs /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders /usr/local/bin/gdk-pixbuf-query-loaders
|
||||
|
||||
export TARGET_APPIMAGE_ARCH="${TARGET_APPIMAGE_ARCH:-$(uname -m)}"
|
||||
|
||||
if ! command -v appimage-builder >/dev/null 2>&1; then
|
||||
apt-get install -yq python3 python3-dev python3-venv
|
||||
|
||||
# Set up a virtual environment so that we do not pollute the global Python
|
||||
# packages list with the packages we need to install
|
||||
echo 'Setting up temporary Python virtual environment...'
|
||||
python3 -m venv "$APPIMAGE_WORKDIR/.venv"
|
||||
. "$APPIMAGE_WORKDIR/.venv/bin/activate"
|
||||
|
||||
export MAKEFLAGS="-j$(nproc)"
|
||||
|
||||
pip3 install wheel setuptools --upgrade
|
||||
|
||||
echo 'Install appimage-build in temporary Python virtual environment...'
|
||||
pip3 install git+https://github.com/AppImageCrafters/appimage-builder.git
|
||||
fi
|
||||
|
||||
echo 'Running appimage-builder...'
|
||||
export TARGET_APPIMAGE_APT_ARCH="${TARGET_APPIMAGE_APT_ARCH:-$(dpkg-architecture -q DEB_HOST_ARCH)}"
|
||||
export TARGET_APPDIR="${APPIMAGE_WORKDIR}/AppDir"
|
||||
export REPO_DIR="$APPIMAGE_WORKDIR/pkgs"
|
||||
|
||||
XDG_DATA_DIRS="$(pwd)/AppDir/usr/share:/usr/share:/usr/local/share:/var/lib/flatpak/exports/share"
|
||||
export XDG_DATA_DIRS
|
||||
|
||||
VERSION="$(CDPATH='' cd "${_root}/../.." && git describe --tags --dirty=-custom --always)"
|
||||
export VERSION
|
||||
|
||||
mkdir -p "$TARGET_APPIMAGE_DIR"
|
||||
|
||||
appimage-builder --recipe "$RECIPE" --skip-test
|
||||
|
||||
echo "> Moving generated AppImage to $TARGET_APPIMAGE_DIR"
|
||||
mv -f ./*.AppImage* "$TARGET_APPIMAGE_DIR"
|
|
@ -136,7 +136,7 @@ case "$(uname)" in
|
|||
echo "Installing dependencies with apt..."
|
||||
|
||||
# Tauri dependencies
|
||||
set -- build-essential curl wget file patchelf openssl libssl-dev libgtk-3-dev librsvg2-dev \
|
||||
set -- build-essential curl wget file openssl libssl-dev libgtk-3-dev librsvg2-dev \
|
||||
libwebkit2gtk-4.0-dev libayatana-appindicator3-dev
|
||||
|
||||
# Webkit2gtk requires gstreamer plugins for video playback to work
|
||||
|
@ -155,7 +155,7 @@ case "$(uname)" in
|
|||
echo "Installing dependencies with pacman..."
|
||||
|
||||
# Tauri dependencies
|
||||
set -- base-devel curl wget file patchelf openssl gtk3 librsvg webkit2gtk libayatana-appindicator
|
||||
set -- base-devel curl wget file openssl gtk3 librsvg webkit2gtk libayatana-appindicator
|
||||
|
||||
# Webkit2gtk requires gstreamer plugins for video playback to work
|
||||
set -- "$@" gst-plugins-base gst-plugins-good gst-plugins-ugly
|
||||
|
@ -186,7 +186,7 @@ case "$(uname)" in
|
|||
fi
|
||||
|
||||
# Tauri dependencies
|
||||
set -- openssl openssl-dev curl wget file patchelf libappindicator-gtk3-devel librsvg2-devel
|
||||
set -- openssl openssl-dev curl wget file libappindicator-gtk3-devel librsvg2-devel
|
||||
|
||||
# Webkit2gtk requires gstreamer plugins for video playback to work
|
||||
set -- "$@" gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-good \
|
||||
|
@ -205,7 +205,7 @@ case "$(uname)" in
|
|||
echo "Alpine suport is experimental" >&2
|
||||
|
||||
# Tauri dependencies
|
||||
set -- build-base curl wget file patchelf openssl-dev gtk+3.0-dev librsvg-dev \
|
||||
set -- build-base curl wget file openssl-dev gtk+3.0-dev librsvg-dev \
|
||||
webkit2gtk-dev libayatana-indicator-dev
|
||||
|
||||
# Webkit2gtk requires gstreamer plugins for video playback to work
|
||||
|
|
Loading…
Reference in a new issue