# How the FlClash Setup Script Automates the Build Process for Different Platforms

> Discover how the FlClash setup script automates builds for Android, Linux, macOS, and Windows. Streamline your Flutter development with this efficient, platform-agnostic solution.

- Repository: [chen08209/FlClash](https://github.com/chen08209/FlClash)
- Tags: how-to-guide
- Published: 2026-05-31

---

**The `setup.dart` script in FlClash serves as a single entry point that automates the entire build and packaging pipeline for Android, Linux, macOS, and Windows by detecting the host environment, resolving artifact targets, preparing dependencies, and orchestrating `flutter_distributor` with platform-specific configurations.**

FlClash is an open-source Flutter-based GUI for ClashMeta that requires compiling both Dart/Flutter frontend code and platform-specific native binaries. The repository's `setup.dart` script eliminates manual build steps by automating cross-platform compilation and packaging through a unified command-line interface, enabling developers to produce release artifacts with a single command regardless of the host operating system.

## Four-Stage Build Automation Pipeline

The `setup.dart` script implements a deterministic four-stage workflow that handles everything from environment detection to final package generation. Each stage is designed to be platform-agnostic while accommodating platform-specific requirements.

### Stage 1: Host and Architecture Detection

The script begins by identifying the build environment using Dart's `Platform` API. It reads the host operating system via `Platform.operatingSystem` and maps it to an internal identifier (`_hostPlatform`), then determines the CPU architecture through `_detectArch()` ([`setup.dart#L35`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L35)).

By default, the script targets the host platform, but it accepts an optional platform argument that defaults to **android** when unspecified. This detection logic enables cross-compilation scenarios, such as building Android APKs from Linux or macOS hosts ([`setup.dart#L37‑L44`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L37-L44)).

### Stage 2: Packaging Target Resolution

Once the platform is determined, the script resolves which packaging formats to generate. It maintains a default mapping of platforms to artifact types:

- **Android**: `apk`
- **Linux (amd64)**: `deb`, `appimage`, `rpm`
- **macOS**: `dmg`
- **Windows**: `exe`, `msix`

Users can override these defaults using the `--targets` flag with comma-separated values. The resolution logic evaluates the architecture to conditionally include formats—ensuring, for example, that `.rpm` and `.deb` packages are only built for Linux x64 systems ([`setup.dart#L7‑L12`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L7-L12), [`setup.dart#L14‑L18`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L14-L18)).

### Stage 3: Environment Preparation and Native Compilation

The script prepares the build environment through several automated steps:

**Dependency Activation**: It activates the **flutter_distributor** package from the local `plugins/flutter_distributor` source, ensuring the packaging tools are available without global installation ([`setup.dart#L46‑L66`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L46-L66)).

**Go Core Compilation (Windows)**: On Windows hosts, the script invokes `_buildGoCore` to compile the ClashMeta core using the bundled `build_tool` located at `plugins/setup/buildkit/build_tool`. It calculates the SHA-256 hash of the resulting binary and writes this value to [`env.json`](https://github.com/chen08209/FlClash/blob/main/env.json) under the `CORE_SHA256` key, ensuring the Flutter application can verify the core binary's integrity at runtime ([`setup.dart#L61‑L66`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L61-L66)).

**Environment File Generation**: The script generates [`env.json`](https://github.com/chen08209/FlClash/blob/main/env.json) containing the `APP_ENV` variable (set to `pre` or `stable`) and optionally the core hash. This file is consumed by Flutter during the build process via `dart-define-from-file` ([`setup.dart#L61‑L66`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L61-L66)).

**Tool Installation**: The script automatically installs platform-specific packaging tools:
- **macOS**: Installs `appdmg` via npm for DMG creation
- **Linux**: Installs `apt` packages and `appimagetool` for AppImage generation ([`setup.dart#L54‑L78`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L54-L78))

### Stage 4: Build Execution and Distribution

The final stage constructs Flutter build arguments and executes the distributor. The script builds a command that includes:
- The `verbose` flag when `-v` is passed
- `--dart-define-from-file=env.json` to inject environment variables
- Platform-specific flags such as `split-per-abi` for Android builds

For Android specifically, the script maps the requested architecture (`arm`, `arm64`, `amd64`) to Flutter's internal target platform identifiers using `_androidFlutterTarget` ([`setup.dart#L100‑L112`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L100-L112)).

It then executes `flutter_distributor package` with the resolved platform, targets, architecture description, and prepared Flutter arguments ([`setup.dart#L79‑L94`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L79-L94)).

## Usage Examples

The script supports a concise CLI interface for various build scenarios:

```bash

# Build the current host platform (e.g., macOS on a macOS machine)

dart setup.dart

# Cross-compile an Android APK for arm64

dart setup.dart android --arch arm64 --targets apk

# Build a Windows installer with verbose Flutter output

dart setup.dart windows -v

# Build only a Linux AppImage for amd64, skipping other formats

dart setup.dart linux --targets appimage

```

**Available Flags:**
- `--env`: Selects the application environment (`pre` or `stable`)
- `--targets`: Overrides the default artifact list (comma-separated)
- `--arch`: For Android only—chooses the ABI (`arm`, `arm64`, `amd64`)
- `-v` / `--verbose`: Shows full Flutter build logs

## Summary

- **Unified Entry Point**: The `setup.dart` script consolidates all build logic, eliminating the need for separate platform-specific build scripts.
- **Intelligent Defaults**: Automatically selects appropriate packaging formats based on the target platform and architecture, with full override capability via CLI flags.
- **Integrated Core Compilation**: Automatically compiles the Go-based ClashMeta core on Windows and embeds its checksum into the build environment.
- **Self-Healing Dependencies**: Automatically installs required packaging tools (appdmg, appimagetool, apt packages) without manual configuration.
- **Cross-Platform Support**: Supports building for any target platform from any host, including Android cross-compilation from desktop systems.

## Frequently Asked Questions

### How does the FlClash setup script handle the Go core dependency on Windows?

On Windows, the script calls `_buildGoCore` which invokes the bundled `build_tool` located at `plugins/setup/buildkit/build_tool/lib/src/build_tool.dart`. This tool compiles the ClashMeta core from source, calculates its SHA-256 hash, and writes the hash to [`env.json`](https://github.com/chen08209/FlClash/blob/main/env.json) so the Flutter application can verify the binary at runtime.

### Can I build for Linux or macOS from a Windows host using the setup script?

No, the script is designed to run on the target host platform or cross-compile specifically to Android. While the script detects the host platform via `Platform.operatingSystem` ([`setup.dart#L37‑L44`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L37-L44)), it does not support cross-compiling Linux or macOS binaries from Windows. You must run the script on the respective native host or use CI runners for those platforms.

### What determines which packaging formats are built by default?

The default formats are hard-coded in `setup.dart` at lines 7-12. For example, Linux amd64 targets default to `deb,appimage,rpm`, while Android defaults to `apk`. The script also applies architectural logic—only building `.deb` and `.rpm` packages for amd64 Linux systems. You can override these defaults using the `--targets` flag followed by comma-separated format names.

### How does the script ensure the Flutter build uses the correct environment variables?

The script generates an [`env.json`](https://github.com/chen08209/FlClash/blob/main/env.json) file containing `APP_ENV` and optionally `CORE_SHA256` ([`setup.dart#L61‑L66`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L61-L66)). When executing the Flutter build, the script passes `--dart-define-from-file=env.json` as an argument ([`setup.dart#L100‑L112`](https://github.com/chen08209/FlClash/blob/main/setup.dart#L100-L112)), which injects these values as compile-time constants accessible within the Dart code.