Why build from source?
Most people should just grab a prebuilt package from the releases page — there are installers for Windows, macOS, Linux (x64 and ARM64), and Android, plus a hosted web version. But if you want to hack on the app, test a fix, run on a platform we don't ship binaries for, or just see how it all fits together, building from source is straightforward once the toolchain is in place.
HTCommander is a single Flutter codebase that targets Windows, macOS, Linux, iOS, Android, and the web. The Dart/Flutter side is identical everywhere; the only per-platform work is installing Flutter itself and the native SDKs and system libraries each target needs. This post walks through all of it.
Step 1 — Install Flutter (all platforms)
HTCommander tracks a recent Flutter stable channel (it needs the Dart
3.12+ SDK, per pubspec.yaml). The cleanest way to
install and stay current is Flutter's own tooling.
The universal path — follow the official installer for your OS: https://docs.flutter.dev/get-started/install
After installing, confirm the toolchain is healthy from a terminal:
flutter --version
flutter doctor
flutter doctor is your friend on every platform — it checks for the platform
SDKs, licenses, and tools described below and prints exactly what's missing. Work
through its checklist until the targets you care about show a green check.
Tip: on Linux and macOS, installing Flutter via a version manager or the git clone method keeps
flutter upgradeworking. On Windows, the.zipinstall orwinget install --id=Google.Flutterboth work well.
Once Flutter is installed, enable the desktop/web targets you plan to build (these are no-ops if already on):
flutter config --enable-windows-desktop
flutter config --enable-macos-desktop
flutter config --enable-linux-desktop
flutter config --enable-web
Step 2 — Get the source
git clone https://github.com/Ylianst/HTCommander.git
cd HTCommander/src
flutter pub get
Important: the Flutter project lives in the src/ subdirectory of the
repository, not the repo root. All flutter commands below are run from
HTCommander/src. flutter pub get downloads the Dart package dependencies; the
first native build will fetch the platform-specific pieces.
Step 3 — Build for your platform
Pick your target. Each section lists the one-time platform setup, then the build
command. All builds are run from the src/ directory.
Windows
Setup:
- Visual Studio 2022 (not VS Code) with the "Desktop development with C++" workload. This provides MSVC, the Windows SDK, and CMake — everything the Flutter Windows toolchain links against.
Build:
flutter build windows --release
The result lands in build/windows/x64/runner/Release/. To iterate live, use
flutter run -d windows.
macOS
Setup:
- Xcode (from the App Store) plus its command-line tools:
sudo xcodebuild -runFirstLaunch - CocoaPods for plugin dependencies:
sudo gem install cocoapods
Build:
flutter build macos --release
The app bundle appears in build/macos/Build/Products/Release/. Use
flutter run -d macos for live development.
Linux
Linux needs the most system packages because HTCommander's desktop build links
against several native libraries directly. In addition to the standard Flutter
Linux toolchain, HTCommander's own Linux runner plugins use BlueZ (native
Bluetooth Classic / RFCOMM to the radio), GLib/GIO, and the PulseAudio
simple API (native PCM playback), and the bundled audioplayers plugin uses
GStreamer. Missing any of these is what produces errors like:
CMake Error at .../FindPkgConfig.cmake:619 (message):
The following required packages were not found:
- gstreamer-app-1.0
That error just means the GStreamer development files aren't installed — it's a missing dependency, not a bug.
Setup (Debian / Ubuntu — including the Framework laptop):
sudo apt update
sudo apt install -y \
clang cmake ninja-build pkg-config \
libgtk-3-dev liblzma-dev \
libglib2.0-dev \
libbluetooth-dev \
libpulse-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good
What each group is for:
| Package(s) | Needed by |
|---|---|
clang, cmake, ninja-build, pkg-config |
The Flutter Linux build toolchain |
libgtk-3-dev, liblzma-dev |
Flutter's GTK shell |
libglib2.0-dev |
GLib/GIO (gio-2.0) used by the native plugins |
libbluetooth-dev |
BlueZ — native Bluetooth Classic/RFCOMM link to the radio |
libpulse-dev |
PulseAudio simple API — native PCM audio playback |
libgstreamer1.0-dev, libgstreamer-plugins-base1.0-dev |
The audioplayers plugin (gstreamer-app-1.0) |
gstreamer1.0-plugins-base, gstreamer1.0-plugins-good |
GStreamer runtime codecs for audio playback |
Setup (Fedora / RHEL):
sudo dnf install -y \
clang cmake ninja-build pkgconf-pkg-config \
gtk3-devel xz-devel \
glib2-devel \
bluez-libs-devel \
pulseaudio-libs-devel \
gstreamer1-devel gstreamer1-plugins-base-devel
Setup (Arch):
sudo pacman -S --needed \
clang cmake ninja pkgconf \
gtk3 xz \
glib2 \
bluez-libs \
libpulse \
gstreamer gst-plugins-base
Verify the tricky one is now visible to pkg-config before building:
pkg-config --modversion gstreamer-app-1.0
If that prints a version number, you're good.
Build:
flutter build linux --release
The bundle lands in build/linux/x64/release/bundle/ (or arm64 on ARM
machines). On an ARM64 host — like a Raspberry Pi or an ARM laptop — the exact
same command and package list apply; Flutter selects the ARM64 toolchain
automatically. Use flutter run -d linux for live development.
Android
Setup:
- Android Studio (easiest — it bundles the SDK, platform tools, and an emulator), or the standalone Android command-line tools.
- Accept the SDK licenses:
flutter doctor --android-licenses - A device with USB debugging enabled, or a running emulator.
Build:
# APK for sideloading / direct install:
flutter build apk --release
# Or an App Bundle for the Play Store:
flutter build appbundle --release
The APK is written to build/app/outputs/flutter-apk/. Install straight to a
connected device with flutter install, or iterate with flutter run -d <device>.
iOS
Setup (macOS only):
- Xcode and command-line tools (see the macOS section).
- CocoaPods:
sudo gem install cocoapods. - For running on a physical device, an Apple Developer account and a configured
signing team in Xcode (open
ios/Runner.xcworkspace).
Build:
# Simulator / development run:
flutter run -d <ios-device-or-simulator>
# Release build (add --no-codesign to skip signing for CI/inspection):
flutter build ios --release
Web
Setup: nothing beyond Flutter itself. Note that HTCommander's web build relies on Web Bluetooth, which today means Chrome or Edge — Safari and Firefox don't expose the Bluetooth APIs the app needs.
Build:
flutter build web --release
The static site is emitted to build/web/. Serve it with any static host, or run
flutter run -d chrome during development.
Troubleshooting
Package gstreamer-app-1.0 was not found(orbluez,libpulse-simple,gio-2.0) on Linux. A-devpackage is missing — install the full Linux set from the table above. The name after "not found" maps directly to one of those packages.flutter doctorshows a red X. Fix the item it names before building; it's almost always a missing SDK, an unaccepted license, or a tool not on yourPATH.- Old artifacts causing weird build errors. Run
flutter cleaninsrc/, thenflutter pub get, then rebuild. This regenerates the ephemeral CMake/Gradle files. - Wrong directory. Every command here runs from
HTCommander/src, not the repository root. If Flutter says it can't findpubspec.yaml, you're one level too high. - Plugin/pod mismatches on macOS/iOS. From
src/iosorsrc/macos, runpod repo updatethenpod install, or justflutter cleanand rebuild.
Summary
| Platform | Host OS to build on | Extra setup beyond Flutter | Build command |
|---|---|---|---|
| Windows | Windows | Visual Studio 2022 + C++ workload | flutter build windows --release |
| macOS | macOS | Xcode + CocoaPods | flutter build macos --release |
| Linux (x64/ARM64) | Linux | GTK, BlueZ, PulseAudio, GStreamer dev libs | flutter build linux --release |
| Android | any | Android Studio / SDK + licenses | flutter build apk --release |
| iOS | macOS | Xcode + CocoaPods + signing | flutter build ios --release |
| Web | any | Chrome/Edge for testing | flutter build web --release |
Once Flutter is installed and flutter doctor is happy for your target, building
HTCommander is a single command. The Dart code is the same everywhere — the only
platform-specific effort is the native toolchain and, on Linux, the handful of
system libraries the radio link, audio playback, and Bluetooth stack depend on.
Happy hacking — and if you get it running on a platform we don't ship binaries for, we'd love a report.