%global debug_package %{nil} %global __requires_exclude_from ^%{_libexecdir}/%{name}/.*$ %global __provides_exclude_from ^%{_libexecdir}/%{name}/.*$ %global flutter_version 3.41.9 %global rust_toolchain 1.97.1 Name: localsend Version: 1.18.1 Release: 1%{?dist} Summary: An open source cross-platform alternative to AirDrop License: Apache-2.0 URL: https://localsend.org Source0: https://github.com/localsend/localsend/archive/refs/tags/v%{version}.tar.gz Source1: localsend.service Source2: fake-rustup.sh Source3: localsend.desktop # tray_manager 0.5.3 is a pub.dev dependency fetched live during the build # (not part of localsend's own tree), so it can't be applied via the usual # prep-time autopatch mechanism -- the target file doesn't exist until # `flutter pub get` fetches it. It's applied manually in the build section # instead; see the comment there. It calls the # now-deprecated app_indicator_new() unconditionally; Fedora's # libayatana-appindicator3 headers mark that G_GNUC_DEPRECATED, and the # plugin's own CMakeLists compiles with -Werror, turning the warning into a # fatal build error. Verified with a real mock build (fedora-44-aarch64). Patch0: 0002-tray_manager-ayatana-deprecated-appindicator-new.patch ExclusiveArch: aarch64 BuildRequires: git BuildRequires: curl BuildRequires: unzip BuildRequires: clang BuildRequires: gcc-c++ BuildRequires: cmake BuildRequires: ninja-build BuildRequires: pkgconf-pkg-config BuildRequires: patchelf BuildRequires: gtk3-devel BuildRequires: libayatana-appindicator-gtk3-devel BuildRequires: xdg-user-dirs BuildRequires: cargo = %{rust_toolchain} BuildRequires: rust = %{rust_toolchain} BuildRequires: mesa-libGL-devel BuildRequires: systemd-rpm-macros Requires: gtk3 Requires: libayatana-appindicator-gtk3 Requires: xdg-user-dirs Requires(post): systemd Requires(preun): systemd Requires(postun): systemd %description LocalSend is an open source cross-platform app that lets you share files and messages with nearby devices without an internet connection. This package builds the Flutter-based desktop client (with its Rust protocol core, built via cargokit) from source for Linux, plus a systemd --user unit that starts it in the background the same way LocalSend's own login-autostart does: systemctl --user enable --now localsend %prep # Not %%autosetup -p1: Patch0 targets a pub-cache dependency that isn't # part of this source tree yet, so nothing here can auto-apply it. %setup -q -n %{name}-%{version} %build # Flutter's own bundled clang toolchain doesn't understand GCC's # `-specs=...` mechanism that Fedora's hardened build flags rely on. export CFLAGS="$(sed -E 's/-specs=[^ ]+//g' <<<"$CFLAGS")" export CXXFLAGS="$(sed -E 's/-specs=[^ ]+//g' <<<"$CXXFLAGS")" export LDFLAGS="$(sed -E 's/-specs=[^ ]+//g' <<<"$LDFLAGS")" # cargokit (the Rust<->Flutter glue used by packages/localsend_isolates) # hard-requires a `rustup` binary on PATH to check/install toolchains and # targets, and always compiles through `rustup run cargo ...` # rather than calling `cargo` on PATH directly. Since rust-toolchain.toml # pins exactly %{rust_toolchain} -- matching the rust/cargo BuildRequires # above -- a real rustup would just download a second, redundant copy of # the same compiler. This shim reports the pinned toolchain/target as # already installed and delegates `rustup run CMD...` straight # to Fedora's system CMD, so the actual compilation still goes through the # real system cargo/rustc. install -Dpm0755 %{SOURCE2} %{_builddir}/fake-rustup-bin/rustup export PATH="%{_builddir}/fake-rustup-bin:$PATH" FLUTTER_ROOT=%{_builddir}/flutter-sdk rm -rf "$FLUTTER_ROOT" git clone -q --depth 1 --branch %{flutter_version} \ https://github.com/flutter/flutter.git "$FLUTTER_ROOT" export PATH="$FLUTTER_ROOT/bin:$PATH" export CI=true export FLUTTER_SUPPRESS_ANALYTICS=true flutter config --no-analytics --no-cli-animations flutter precache --linux cd app flutter pub get --enforce-lockfile # See Patch0 above for why this can't be an %%autopatch. Globs the # installed version rather than hardcoding tray_manager-0.5.3 so a pubspec # bump fails loudly here (patch context mismatch) instead of silently # building against unpatched, possibly still-broken pub-cache source. tray_manager_dir=$(ls -d "$HOME"/.pub-cache/hosted/pub.dev/tray_manager-*) patch -p1 -d "$tray_manager_dir" < %{PATCH0} flutter build linux --release -v --no-pub %install install -d %{buildroot}%{_libexecdir}/%{name} cp -a app/build/linux/arm64/release/bundle/. %{buildroot}%{_libexecdir}/%{name}/ chmod 0755 %{buildroot}%{_libexecdir}/%{name}/localsend_app # Bundled plugin/rust .so files carry build-tree rpaths; repoint them at # their own directory so they still resolve once installed elsewhere. find %{buildroot}%{_libexecdir}/%{name}/lib -name '*.so*' -print0 | \ xargs -0 -r patchelf --set-rpath '$ORIGIN' install -d %{buildroot}%{_bindir} ln -s %{_libexecdir}/%{name}/localsend_app %{buildroot}%{_bindir}/%{name} install -Dpm0644 %{SOURCE1} %{buildroot}%{_userunitdir}/localsend.service install -Dpm0644 %{SOURCE3} %{buildroot}%{_datadir}/applications/localsend.desktop install -Dpm0644 app/assets/img/logo-512.png \ %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/localsend.png %post %systemd_user_post localsend.service %preun %systemd_user_preun localsend.service %postun %systemd_user_postun_with_restart localsend.service %files %license LICENSE %doc README.md %{_bindir}/%{name} %{_libexecdir}/%{name}/ %{_userunitdir}/localsend.service %{_datadir}/applications/localsend.desktop %{_datadir}/icons/hicolor/512x512/apps/localsend.png %changelog * Fri Aug 14 2026 Lachlan Marie - 1.18.1-1 - Initial RPM packaging of LocalSend (Flutter + Rust/cargokit) for Fedora 44 aarch64, with a systemd --user service that autostarts it minimized to the tray.