%global debug_package %{nil} %global __requires_exclude_from ^%{_libexecdir}/%{name}/.*$ %global __provides_exclude_from ^%{_libexecdir}/%{name}/.*$ %global appid app.bluebubbles.BlueBubbles %global flutter_version 3.44.6 # BlueBubbles tags releases as vX.Y.Z+BUILD (e.g. v2.1.0+90), not a plain # semver tag, so it's tracked here as the 4-part dotted form X.Y.Z.BUILD and # split back apart below -- matching what autobuild's tag-tracking (fixed to # fold separators into '.' instead of deleting them -- see # normalize_tag_to_numeric() in helpers/autobuild) will compare against and # rewrite in place on a new release. %global tag 2.1.1.91 %global appver %(echo %{tag} | sed -E 's/\\.[0-9]+$//') %global build_num %(echo %{tag} | sed -E 's/^.*\\.//') %global dirtag %(echo %{tag} | sed -E 's/\\.([0-9]+)$/-\\1/') Name: bluebubbles Version: %{tag} Release: 1%{?dist} Summary: iMessage client for Linux, part of the BlueBubbles ecosystem License: Apache-2.0 URL: https://bluebubbles.app Source0: https://github.com/BlueBubblesApp/bluebubbles-app/archive/refs/tags/v%{appver}+%{build_num}.tar.gz # This app is only supported natively on Linux desktop for aarch64/x86_64; # this repo only builds for aarch64. ExclusiveArch: aarch64 # Toolchain needed to compile the Flutter engine's Linux embedder and its # native plugins (gtk/webkit/mpv/appindicator/notify/json-glib bindings). BuildRequires: git BuildRequires: curl BuildRequires: unzip BuildRequires: jq BuildRequires: clang BuildRequires: gcc-c++ BuildRequires: cmake BuildRequires: ninja-build BuildRequires: pkgconf-pkg-config BuildRequires: patchelf BuildRequires: gtk3-devel BuildRequires: webkit2gtk4.1-devel BuildRequires: mpv-devel BuildRequires: libayatana-appindicator-gtk3-devel BuildRequires: libnotify-devel BuildRequires: json-glib-devel # Automatic dependency generation is disabled for the bundled libexecdir # tree below (it's a mix of vendored blobs with no matching system package # and plugin .so's whose real system deps auto-detection can miss), so the # runtime libs actually dlopen'd/linked by those plugins are listed here by # hand instead. Requires: gtk3 Requires: webkit2gtk4.1 Requires: mpv-libs Requires: libayatana-appindicator-gtk3 Requires: libnotify Requires: json-glib # checkInstanceLock() in lib/helpers/backend/startup_tasks.dart shells out to # `wmctrl -pl`/`wmctrl -iR` to raise the existing window when a second copy # is launched; without it that path throws an uncaught ProcessException. Requires: wmctrl %description BlueBubbles is a cross-platform ecosystem that brings iMessage to Android, Windows, Linux, and the web by pairing with a BlueBubbles Server running on a Mac. This package builds the Flutter-based desktop client from source for Linux. Note: this build requires network access at build time. It shallow-clones the pinned Flutter SDK release from GitHub, lets the Flutter tool download its matching Dart SDK and engine artifacts for linux-arm64, and runs `flutter pub get` against the upstream lockfile (which includes a handful of pinned git dependencies) -- none of this is vendored or offline-capable. %prep %autosetup -n bluebubbles-app-%{dirtag} # The GIF picker needs a Klipy API key; we don't have one to embed, so ship # an empty one. The rest of the app is unaffected, only in-app GIF search is. echo 'KLIPY_API_KEY=' > .env %build # The Flutter tool hardcodes CC=clang/CXX=clang++ for the Linux desktop # CMake step, but it still inherits our CFLAGS/CXXFLAGS/LDFLAGS. Those # contain GCC-only `-specs=...` hardening flags that clang rejects as # unused arguments, which the plugins' -Werror then turns into hard # failures. Drop just the -specs= tokens; the rest of the hardening flags # (fstack-protector-strong, fstack-clash-protection, etc.) are understood # by clang natively and stay in effect. export CFLAGS="$(sed -E 's/-specs=[^ ]+//g' <<<"$CFLAGS")" export CXXFLAGS="$(sed -E 's/-specs=[^ ]+//g' <<<"$CXXFLAGS")" export LDFLAGS="$(sed -E 's/-specs=[^ ]+//g' <<<"$LDFLAGS")" FLUTTER_ROOT=%{_builddir}/flutter-sdk git clone -q --depth 1 --branch %{flutter_version} \ https://github.com/flutter/flutter.git "$FLUTTER_ROOT" export PATH="$FLUTTER_ROOT/bin:$PATH" # Non-interactive, no analytics/crash reporting pings. export CI=true export FLUTTER_SUPPRESS_ANALYTICS=true flutter config --no-analytics --no-cli-animations # Downloads the Dart SDK + engine artifacts matching the host arch # (linux-arm64) from Google's storage; there is no offline path for this. flutter precache --linux flutter pub get --enforce-lockfile flutter build linux --release -v --no-pub tmp=$(mktemp) # 'version' must stay a plain X.Y.Z semver: SettingsService.getAppUpdateDict # does int.parse() on each dot-separated component to compare against the # latest GitHub release, so a 4th component here throws a FormatException # (caught, but noisy) every time the app checks for updates. jq --arg v "%{appver}" '.version = $v' \ build/linux/arm64/release/bundle/data/flutter_assets/version.json > "$tmp" mv "$tmp" build/linux/arm64/release/bundle/data/flutter_assets/version.json %install install -d %{buildroot}%{_libexecdir}/%{name} cp -a build/linux/arm64/release/bundle/. %{buildroot}%{_libexecdir}/%{name}/ chmod 0755 %{buildroot}%{_libexecdir}/%{name}/bluebubbles # Several bundled plugin .so files keep an absolute build-tree RPATH # (pointing at linux/flutter/ephemeral, where the engine headers/libs lived # during linking) instead of a relative one, which trips rpmbuild's # check-rpaths QA gate. Every sibling library they need lives alongside them # in this same lib/ dir, so a plain $ORIGIN is correct and sufficient. find %{buildroot}%{_libexecdir}/%{name}/lib -name '*.so*' -print0 | \ xargs -0 -r patchelf --set-rpath '$ORIGIN' install -d %{buildroot}%{_bindir} ln -s %{_libexecdir}/%{name}/bluebubbles %{buildroot}%{_bindir}/%{name} install -Dpm0644 flatpak/icon/128x128.png \ %{buildroot}%{_datadir}/icons/hicolor/128x128/apps/%{appid}.png install -Dpm0644 flatpak/%{appid}.desktop \ %{buildroot}%{_datadir}/applications/%{appid}.desktop install -Dpm0644 flatpak/%{appid}.metainfo.xml \ %{buildroot}%{_metainfodir}/%{appid}.metainfo.xml %files %license LICENSE %doc README.md %{_bindir}/%{name} %{_libexecdir}/%{name}/ %{_datadir}/applications/%{appid}.desktop %{_datadir}/icons/hicolor/128x128/apps/%{appid}.png %{_metainfodir}/%{appid}.metainfo.xml %changelog * Fri Aug 14 2026 Lachlan Marie - 2.1.1.91-1 - Update to 2.1.1.91 * Mon Aug 10 2026 Lachlan Marie - 2.1.0.90-1 - Initial RPM packaging of bluebubbles (built from source, online build)