windows_flavourizer 0.0.1
windows_flavourizer: ^0.0.1 copied to clipboard
Automates multi-flavor Windows runner setup for Flutter projects on IntelliJ IDEA and VS Code
Windows Flavourizer #
Windows Flavourizer is a command-line tool that automates multi-flavor Windows runner setup and IDE run/debug configurations for Flutter desktop projects on VS Code and IntelliJ IDEA / Android Studio.
π‘ The Problem #
Flutter natively supports flavor-based development for mobile (Android product flavors and iOS schemes), but Windows desktop flavor support poses several hurdles:
- Build Artifact Collisions: By default, Flutter compiles the Windows runner into a single shared output directory (
build/windows/x64/runner/<CONFIG>). Switching between flavors overwrites previously compiled binaries and leads to stale or mismatched builds. - Identical Executable Names: The binary name in
windows/CMakeLists.txtis hardcoded (e.g.,set(BINARY_NAME "my_app")). Flutter does not dynamically rename the output executable per flavor. - CMake Install Prefix Errors: Default CMake configs can attempt to install to system directories like
Program Files, resulting in permission errors. - IDE Debugging Friction: Launching and debugging specific flavors directly from IDE run configurations often fails to attach properly or rebuilds the wrong flavor target.
β¨ What Windows Flavourizer Does #
windows_flavourizer provides a one-command solution that transforms your Flutter Windows project:
- Isolated Binary Output: Patches
windows/runner/CMakeLists.txtso each flavor outputs to its own directory:build/windows/x64/<flavor>/runner/<flavor>/<CONFIG>/ - Dynamic Binary Naming: Patches
windows/CMakeLists.txtto suffix binary names with the active flavor (e.g.,my_app_dev.exe,my_app_prod.exe). - CMake Permission Fix: Resolves
CMAKE_INSTALL_PREFIXpermission conflicts automatically. - Pre-Launch Build Automation: Generates
scripts/ensure_binary.ps1, a PowerShell script that checks if the flavor binary exists, and compiles it viaflutter build windows --debug --flavor <flavor>if needed. - VS Code Configurations: Generates
.vscode/tasks.jsonand.vscode/launch.jsonwith pre-launch tasks, entrypoint mapping,--use-application-binarylaunch args, and a compound launcher to run all flavors concurrently. - IntelliJ / Android Studio Configurations: Generates
.idea/runConfigurations/XML files for each flavor and a compound configuration to launch all flavors at once.
π¦ Installation #
You can activate windows_flavourizer globally:
dart pub global activate windows_flavourizer
Or add it as a dev_dependency in your Flutter project's pubspec.yaml:
dev_dependencies:
windows_flavourizer: ^0.0.1
π Usage #
Run the tool from the root directory of your Flutter project:
If activated globally: #
windows_flavourizer [options]
If added as a dev dependency: #
dart run windows_flavourizer [options]
βοΈ CLI Options #
| Option | Abbreviation | Default | Description |
|---|---|---|---|
--flavors |
-f |
Auto-detected | Comma-separated list of flavors. Auto-detects from lib/main_*.dart, android/app/build.gradle, or pubspec.yaml if omitted. |
--ide |
-i |
all |
Target IDE configurations to generate: intellij, vscode, or all. |
--base-name |
-n |
name in pubspec.yaml |
Base binary name for the executable. |
--scaffold-entry-points |
-s |
false |
Automatically create lib/main_<flavor>.dart entrypoints for missing flavors. |
--help |
-h |
- | Show usage information and exit. |
--version |
-v |
- | Show version information and exit. |
π Examples #
1. Default Setup (dev, staging, prod for both IDEs) #
windows_flavourizer
2. Custom Flavors #
windows_flavourizer --flavors dev,qa,prod
3. Target Specific IDE #
Generate configurations only for VS Code:
windows_flavourizer --ide vscode
Generate configurations only for IntelliJ IDEA / Android Studio:
windows_flavourizer --ide intellij
4. Custom Base Binary Name #
windows_flavourizer --base-name my_custom_app
π Recommended Project Structure #
windows_flavourizer automatically checks for dedicated flavor entrypoints. If a flavor-specific entrypoint is found (lib/main_<flavor>.dart), it is used; otherwise, it falls back to lib/main.dart:
my_flutter_app/
βββ lib/
β βββ main.dart # Fallback entrypoint
β βββ main_dev.dart # Entrypoint for 'dev' flavor
β βββ main_staging.dart # Entrypoint for 'staging' flavor
β βββ main_prod.dart # Entrypoint for 'prod' flavor
βββ scripts/
β βββ ensure_binary.ps1 # [Generated] Pre-launch build script
βββ windows/
β βββ CMakeLists.txt # [Patched] Dynamic binary naming & install prefix fix
β βββ runner/
β βββ CMakeLists.txt # [Patched] Flavor-specific output directories
βββ .vscode/ # [Generated if ide is vscode or all]
β βββ launch.json
β βββ tasks.json
βββ .idea/runConfigurations/ # [Generated if ide is intellij or all]
βββ Ensure_dev_Binary.xml
βββ Windows_dev.xml
βββ Windows_All_Flavors.xml
βββ ...
π₯οΈ Running in Your IDE #
Visual Studio Code #
- Open the Run and Debug panel (
Ctrl + Shift + D). - Select your target configuration from the dropdown:
- Windows (dev)
- Windows (staging)
- Windows (prod)
- Windows (All Flavors) (launches all flavors simultaneously)
- Press F5 to start debugging.

IntelliJ IDEA / Android Studio #
- Reload or restart the IDE project if needed.
- Select your run configuration from the top toolbar dropdown:
- Windows (dev)
- Windows (staging)
- Windows (prod)
- Windows (All Flavors)
- Click the Run or Debug icon.

π§ How It Works Under the Hood #
-
Pre-Launch Validation (
scripts/ensure_binary.ps1): Checks whetherbuild\windows\x64\$Flavor\runner\$Flavor\Debug\<baseName>_$Flavor.exeexists. If not present, it sets$env:APP_FLAVORand executesflutter build windows --debug --flavor $Flavor --target $Target. -
Root CMake (
windows/CMakeLists.txt): Injects logic to inspect environment variablesAPP_FLAVORandFLUTTER_APP_FLAVOR, dynamically settingBINARY_NAMEto${baseName}_${FLAVOR}. -
Runner CMake (
windows/runner/CMakeLists.txt): Appliesset_target_propertieswith customRUNTIME_OUTPUT_DIRECTORYtargets:- Debug:
build/windows/x64/<flavor>/runner/<flavor>/Debug - Release:
build/windows/x64/<flavor>/runner/<flavor>/Release - Profile:
build/windows/x64/<flavor>/runner/<flavor>/Profile
- Debug:
-
Fast IDE Launch: Launch configs execute Flutter using
--use-application-binarypointing directly to the compiled flavor executable. This bypasses repetitive CMake re-generation during normal debug sessions while keeping hot reload and debugging fully functional.
β οΈ Assumptions and Prerequisites #
Standard Flutter CMake Templates #
- It assumes
windows/CMakeLists.txtuses the standard Flutter variable definition lineset(BINARY_NAME "...")and the default installation prefix block (if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)...). - It assumes
windows/runner/CMakeLists.txtdeclaresadd_executable(${BINARY_NAME} WIN32as the target anchor for injectingisolate_flavor_runner_target. - Projects with custom, non-standard CMake templates may require manual adjustments.
Windows Host Environment #
- It assumes execution on Windows where
powershell.exeis present inPATH. - It assumes the local security/execution policy allows
-ExecutionPolicy Bypasswhen executingensure_binary.ps1.
Standard Windows Executable Output Paths #
It assumes the compiled artifact resides at:
build\windows\x64\<flavor>\runner\<flavor>\Debug\<baseName>_<flavor>.exe
If a project renames the target binary inside CMake to something other than ${baseName}_${flavor}, the runner will not locate it.
IDE Workspace Layouts #
- IntelliJ / Android Studio: Assumes the standard
.idea/folder structure exists (or will be parsed on open) so it can register project-contained.idea/runConfigurations/*.xmlfiles. - VS Code: Assumes configurations should live inside
.vscode/tasks.jsonand.vscode/launch.json.
Platform Scope #
It remains strictly targeted at Windows desktop runners (windows/). It does not configure iOS/macOS Xcode schemes or Android Gradle build variants beyond reading Gradle flavors for discovery.
π οΈ Troubleshooting #
- First-Time Build Takes Time: The very first time you launch a flavor, the pre-launch task will compile the native Windows binary. Subsequent launches will detect the existing binary and start instantly.
- Cache Invalidation: If you modify native C++ code or plugins, clean the build cache to ensure a fresh compilation:
flutter clean flutter pub get - PowerShell Script Execution: Generated tasks run PowerShell with
-ExecutionPolicy Bypass. If runningscripts/ensure_binary.ps1manually in a terminal, ensure your PowerShell execution policy allows local scripts:Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
π License #
This project is open source and available under the terms defined in the repository.