Add --flavor support for Windows desktop builds#187034
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements flavor support for Windows builds. The changes include updating the build directory structure to accommodate flavors, suffixing the executable name with the flavor string, and modifying the C++ runner template to display the flavor in the window title. Corresponding tests were added to verify the new functionality. A review comment identifies a potential crash in the C++ runner template due to missing error handling in the string conversion logic, which could lead to an underflow and exception.
|
Hello! I'm really looking forward to this feature. I have a question: how should resource files be handled? For example: |
You can do it by setting custom variables in CMakeLists.txt, for example: if(FLUTTER_APP_FLAVOR STREQUAL "apple")
set(RUNNER_APP_ICON "apple.ico")
set(WINDOW_TITLE "Apple")
elseif(FLUTTER_APP_FLAVOR STREQUAL "banana")
set(RUNNER_APP_ICON "banana.ico")
set(WINDOW_TITLE "Banana")
else()
set(RUNNER_APP_ICON "app_icon.ico")
set(WINDOW_TITLE "windows_flavors")
endif()
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/Runner.rc.in"
"${CMAKE_CURRENT_SOURCE_DIR}/Runner.rc"
@ONLY
)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in"
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
@ONLY
)and then postprocess them using Runner.rc.in: Same applies for custom titles in main.cpp.in: #include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>
#include "flutter_window.h"
#include "utils.h"
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
_In_ wchar_t *command_line, _In_ int show_command) {
// Attach to console when present (e.g., 'flutter run') or create a
// new console when running with a debugger.
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
CreateAndAttachConsole();
}
// Initialize COM, so that it is available for use in the library and/or
// plugins.
::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
flutter::DartProject project(L"data");
std::vector<std::string> command_line_arguments =
GetCommandLineArguments();
project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
if (!window.Create(L"@WINDOW_TITLE@", origin, size)) {
return EXIT_FAILURE;
}
window.SetQuitOnClose(true);
::MSG msg;
while (::GetMessage(&msg, nullptr, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::CoUninitialize();
return EXIT_SUCCESS;
}
|
Should I rename |
mattkae
left a comment
There was a problem hiding this comment.
Nice tests! I have a comment about the generated C++ if we can improve it
d8ac7c3 to
32b01b2
Compare
mattkae
left a comment
There was a problem hiding this comment.
This is working well for me, thanks for the work on this! @loic-sharma do you have anything that you want to add?
|
@AngeloAvv It looks like this PR missed flavors in a few places:
|
|
@loic-sharma let me know if the fixes make sense to you. In the meanwhile I aligned the Linux PR as well |
Is the new change allowing users to set the application id, binary name, app icon, and title in a single line using the built-in FLUTTER_APP_FLAVOR? |
|
autosubmit label was removed for flutter/flutter/187034, because This PR has not met approval requirements for merging. The PR author is not a member of flutter-hackers and needs 1 more review(s) in order to merge this PR.
|
|
Please add the document. |
…#12081) Manual roll Flutter from 0c80830e465b to ca9f874f5284 (119 revisions) Manual roll requested by [email protected] flutter/flutter@0c80830...ca9f874 2026-06-30 [email protected] [tool] Don't require a Flutter compile task when staging jniLibs (flutter/flutter#188805) 2026-06-30 [email protected] [Impeller] Fix potential overflow when allocating buffers at the next power of two size (flutter/flutter#188742) 2026-06-30 [email protected] [Framework/Tool] Decouple preview theme imports (flutter/flutter#188176) 2026-06-30 [email protected] Add import of `dart:_js_interop_wasm` in sdk rewriter tool (flutter/flutter#188620) 2026-06-30 [email protected] Detach LLDB and print stack trace on process stop (flutter/flutter#188576) 2026-06-30 [email protected] [Linux] Fix FlCompositorOpenGL.pixels comment (flutter/flutter#188754) 2026-06-30 [email protected] [flutter_tools] Fix crash in flutter create when pubspec.yaml is empty (flutter/flutter#188385) 2026-06-30 [email protected] Roll Packages from 656ccaa to 274ed3e (23 revisions) (flutter/flutter#188792) 2026-06-30 [email protected] In AndroidImageGenerator, check that the destination pixel buffer has sufficient capacity for the decoded data (flutter/flutter#188752) 2026-06-30 [email protected] Roll pub packages (flutter/flutter#188773) 2026-06-30 [email protected] [Impeller] Add a flat VertexAttributeFormat for vertex inputs (flutter/flutter#188684) 2026-06-30 [email protected] Roll pub packages (flutter/flutter#188764) 2026-06-30 [email protected] Roll Dart SDK from 0cb483880b6b to e1bdb9ce3327 (2 revisions) (flutter/flutter#188763) 2026-06-29 [email protected] Handle 'no permissions' adb device state (flutter/flutter#187248) 2026-06-29 [email protected] [windows]: adjusts uniform buffers to hit hlsl optimization (flutter/flutter#188538) 2026-06-29 [email protected] Roll Skia from bfb7860cb9c7 to 71947c4110b0 (9 revisions) (flutter/flutter#188747) 2026-06-29 [email protected] ci: extract wait-for-engine-build logic into a reusable composite action (flutter/flutter#188748) 2026-06-29 [email protected] Provide guided migration logs when iOS app crashes on simulator (flutter/flutter#188736) 2026-06-29 [email protected] Revert "[flutter_tools] Track asset transformer dependencies for hot reload" (flutter/flutter#188751) 2026-06-29 [email protected] Migrate ABI splits to new AGP dsl (flutter/flutter#188369) 2026-06-29 [email protected] Add Impeller+OpenGLES startup benchmark for mokey (flutter/flutter#188495) 2026-06-29 [email protected] Increase macOS minimum supported version from 10.15 to 12 to support Xcode 27 (flutter/flutter#188520) 2026-06-29 [email protected] Moves test ownership validation to flutter/flutter (flutter/flutter#188655) 2026-06-29 [email protected] Add --flavor support for Windows desktop builds (flutter/flutter#187034) 2026-06-29 [email protected] Android_hardware_smoke_test: Enable pixel exact local file comparator to read goldens from flutter asset URI (flutter/flutter#188587) 2026-06-29 [email protected] [flutter_tools] Use DeviceHub.app for iOS simulator path on Xcode 27+ (flutter/flutter#187910) 2026-06-29 [email protected] Roll Skia from 111e7582d081 to bfb7860cb9c7 (2 revisions) (flutter/flutter#188731) 2026-06-29 [email protected] Use `revert` label instead of `revert_wf` (flutter/flutter#188639) 2026-06-29 [email protected] Properly await Dart Development Service shutdown with timeout (flutter/flutter#188387) 2026-06-29 [email protected] [flutter_tools] Track asset transformer dependencies for hot reload (flutter/flutter#187947) 2026-06-29 [email protected] [Tool] Tolerate malformed UTF-8 in process streaming decoders (flutter/flutter#188453) 2026-06-29 [email protected] [flutter_tools] Use new ddc modules in test (flutter/flutter#188240) 2026-06-29 [email protected] Roll Packages from c1f7d92 to 656ccaa (12 revisions) (flutter/flutter#188728) 2026-06-29 [email protected] Remove unused fields (flutter/flutter#188705) 2026-06-29 [email protected] Clear text input handler widget on view dispose (flutter/flutter#188701) 2026-06-29 [email protected] Free compositor in view renderer finalize to avoid use-after-free (flutter/flutter#188702) 2026-06-29 [email protected] [linux] Use GWeakRef in mock signal handler test helper (flutter/flutter#188700) 2026-06-29 [email protected] Fixing few related editing issues with LTR/RTL text (flutter/flutter#188503) 2026-06-29 [email protected] [Flutter GPU] Add Texture.fromImage to wrap a ui.Image texture (flutter/flutter#188605) 2026-06-29 [email protected] [Flutter GPU] Honor the enable argument in RenderPass.setDepthWriteEnable (flutter/flutter#188715) 2026-06-29 [email protected] Roll Skia from ba1942d8c3e1 to 111e7582d081 (1 revision) (flutter/flutter#188721) 2026-06-29 [email protected] Roll Skia from 587d8befe1ee to ba1942d8c3e1 (6 revisions) (flutter/flutter#188717) 2026-06-29 [email protected] Remove some refs to package:intl (flutter/flutter#188504) 2026-06-29 [email protected] [VPAT] Update a11y assessment app FAB example to announce value change when it's updated. (flutter/flutter#188466) ...
…flutter#12081) Manual roll Flutter from 0c80830e465b to ca9f874f5284 (119 revisions) Manual roll requested by [email protected] flutter/flutter@0c80830...ca9f874 2026-06-30 [email protected] [tool] Don't require a Flutter compile task when staging jniLibs (flutter/flutter#188805) 2026-06-30 [email protected] [Impeller] Fix potential overflow when allocating buffers at the next power of two size (flutter/flutter#188742) 2026-06-30 [email protected] [Framework/Tool] Decouple preview theme imports (flutter/flutter#188176) 2026-06-30 [email protected] Add import of `dart:_js_interop_wasm` in sdk rewriter tool (flutter/flutter#188620) 2026-06-30 [email protected] Detach LLDB and print stack trace on process stop (flutter/flutter#188576) 2026-06-30 [email protected] [Linux] Fix FlCompositorOpenGL.pixels comment (flutter/flutter#188754) 2026-06-30 [email protected] [flutter_tools] Fix crash in flutter create when pubspec.yaml is empty (flutter/flutter#188385) 2026-06-30 [email protected] Roll Packages from 656ccaa to 274ed3e (23 revisions) (flutter/flutter#188792) 2026-06-30 [email protected] In AndroidImageGenerator, check that the destination pixel buffer has sufficient capacity for the decoded data (flutter/flutter#188752) 2026-06-30 [email protected] Roll pub packages (flutter/flutter#188773) 2026-06-30 [email protected] [Impeller] Add a flat VertexAttributeFormat for vertex inputs (flutter/flutter#188684) 2026-06-30 [email protected] Roll pub packages (flutter/flutter#188764) 2026-06-30 [email protected] Roll Dart SDK from 0cb483880b6b to e1bdb9ce3327 (2 revisions) (flutter/flutter#188763) 2026-06-29 [email protected] Handle 'no permissions' adb device state (flutter/flutter#187248) 2026-06-29 [email protected] [windows]: adjusts uniform buffers to hit hlsl optimization (flutter/flutter#188538) 2026-06-29 [email protected] Roll Skia from bfb7860cb9c7 to 71947c4110b0 (9 revisions) (flutter/flutter#188747) 2026-06-29 [email protected] ci: extract wait-for-engine-build logic into a reusable composite action (flutter/flutter#188748) 2026-06-29 [email protected] Provide guided migration logs when iOS app crashes on simulator (flutter/flutter#188736) 2026-06-29 [email protected] Revert "[flutter_tools] Track asset transformer dependencies for hot reload" (flutter/flutter#188751) 2026-06-29 [email protected] Migrate ABI splits to new AGP dsl (flutter/flutter#188369) 2026-06-29 [email protected] Add Impeller+OpenGLES startup benchmark for mokey (flutter/flutter#188495) 2026-06-29 [email protected] Increase macOS minimum supported version from 10.15 to 12 to support Xcode 27 (flutter/flutter#188520) 2026-06-29 [email protected] Moves test ownership validation to flutter/flutter (flutter/flutter#188655) 2026-06-29 [email protected] Add --flavor support for Windows desktop builds (flutter/flutter#187034) 2026-06-29 [email protected] Android_hardware_smoke_test: Enable pixel exact local file comparator to read goldens from flutter asset URI (flutter/flutter#188587) 2026-06-29 [email protected] [flutter_tools] Use DeviceHub.app for iOS simulator path on Xcode 27+ (flutter/flutter#187910) 2026-06-29 [email protected] Roll Skia from 111e7582d081 to bfb7860cb9c7 (2 revisions) (flutter/flutter#188731) 2026-06-29 [email protected] Use `revert` label instead of `revert_wf` (flutter/flutter#188639) 2026-06-29 [email protected] Properly await Dart Development Service shutdown with timeout (flutter/flutter#188387) 2026-06-29 [email protected] [flutter_tools] Track asset transformer dependencies for hot reload (flutter/flutter#187947) 2026-06-29 [email protected] [Tool] Tolerate malformed UTF-8 in process streaming decoders (flutter/flutter#188453) 2026-06-29 [email protected] [flutter_tools] Use new ddc modules in test (flutter/flutter#188240) 2026-06-29 [email protected] Roll Packages from c1f7d92 to 656ccaa (12 revisions) (flutter/flutter#188728) 2026-06-29 [email protected] Remove unused fields (flutter/flutter#188705) 2026-06-29 [email protected] Clear text input handler widget on view dispose (flutter/flutter#188701) 2026-06-29 [email protected] Free compositor in view renderer finalize to avoid use-after-free (flutter/flutter#188702) 2026-06-29 [email protected] [linux] Use GWeakRef in mock signal handler test helper (flutter/flutter#188700) 2026-06-29 [email protected] Fixing few related editing issues with LTR/RTL text (flutter/flutter#188503) 2026-06-29 [email protected] [Flutter GPU] Add Texture.fromImage to wrap a ui.Image texture (flutter/flutter#188605) 2026-06-29 [email protected] [Flutter GPU] Honor the enable argument in RenderPass.setDepthWriteEnable (flutter/flutter#188715) 2026-06-29 [email protected] Roll Skia from ba1942d8c3e1 to 111e7582d081 (1 revision) (flutter/flutter#188721) 2026-06-29 [email protected] Roll Skia from 587d8befe1ee to ba1942d8c3e1 (6 revisions) (flutter/flutter#188717) 2026-06-29 [email protected] Remove some refs to package:intl (flutter/flutter#188504) 2026-06-29 [email protected] [VPAT] Update a11y assessment app FAB example to announce value change when it's updated. (flutter/flutter#188466) ...
Flutter desktop on Windows currently has no equivalent of the
--flavorplumbing that already exists for Android, iOS, and macOS:flutter build windows --flavor Xis rejected at the command-parser level,flutter run -d windows --flavor Xemits a "flavor only supported on Android, iOS, macOS" warning, and there is no convention for producing per-flavor binaries or build directories. This PR wires the existing flavor infrastructure end-to-end on Windows so that multiple flavors can coexist in the same project without colliding on disk or in the runner.What changes
flutter build windowsaccepts--flavorvia the sharedusesFlavorOption()helper.WindowsDevice.supportsFlavorsreturnstrue, soflutter run -d windows --flavor Xno longer warns and now drives the flavored build pipeline.build/windows/<arch>/<flavor>/runner/<Config>/(parity with Android/iOS/macOS). Projects that don't pass--flavorkeep the legacybuild/windows/<arch>/runner/<Config>/layout — no migration required.-DFLUTTER_APP_FLAVOR=<flavor>so the generated project can react to the flavor at configure time.windows.tmpl/CMakeLists.txt.tmpl) suffixesBINARY_NAMEwith-<flavor>whenFLUTTER_APP_FLAVORis defined. The branch is guarded byif(DEFINED FLUTTER_APP_FLAVOR AND NOT FLUTTER_APP_FLAVOR STREQUAL ""), so existing projects regenerated from this template behave identically when no flavor is passed.windows.tmpl/runner/CMakeLists.txt+main.cpp.tmpl) exposesFLUTTER_APP_FLAVORas a compile-time preprocessor define viatarget_compile_definitionsand uses it to suffix the Win32 window title, giving projects a one-line entry point for flavor-aware native behavior without any additional Flutter tool surface area.windows.tmpl/runner/Runner.rc.tmpl) introduces aFLUTTER_BINARY_NAMEpreprocessor define — injected via the sametarget_compile_definitionsmechanism already used forFLUTTER_VERSION_*— and uses it for theInternalNameandOriginalFilenamePE metadata fields, so the version resource stays in sync with the actual on-disk binary name regardless of flavor.appFlavorgetter frompackage:flutter/services.dart, which readsFLUTTER_APP_FLAVORfrom the dart-defines thattoEnvironmentConfig()already produces. No framework changes required.Design choices
runner/<Config>: therunner/<Config>leaf reflects the Visual Studio multi-config generator (Debug/Profile/Release are subdirectories chosen at build time, not at CMake configure time). Inserting the flavor above this segment keeps the VS solution reusable across modes for a given flavor.FLUTTER_BINARY_NAMEinRunner.rc: PE metadata correctness matters because tools (installers, code-signing pipelines, Windows Error Reporting) readOriginalFilenameandInternalNamefrom the version resource. Passing the CMake variable as a preprocessor define costs nothing and avoids anyconfigure_fileindirection in the template.Package.appxmanifest, and installer scripts remain the project's responsibility — this PR intentionally keeps the tool agnostic and only standardizes the plumbing.Tests
test/general.shard/windows/build_windows_flavor_test.dartcovers:flutter build windows --flavor appleinvokes CMake with-DFLUTTER_APP_FLAVOR=appleand a flavor-namespaced working directory, and the success log referencesbuild\windows\x64\apple\runner\Release\.getCmakeExecutableNamereturns the base binary name without a flavor, andname-flavorwhen a flavor is provided (empty string treated as no flavor).getWindowsBuildDirectoryreturns the legacy path without a flavor and inserts the flavor segment when one is provided.test/commands.shard/hermetic/build_windows_test.dartcontinues to pass with no changes, confirming the legacy no-flavor path is unaffected.Manual verification
Generated an example project, then ran the full matrix:
All three builds coexist in
build\windows\x64\without overwriting each other, the Win32 window title reflects the flavor, and the Dart UI readsappFlavorcorrectly at runtime in each binary. PE metadata (InternalName,OriginalFilename) matches the actual filename in all three cases.Backward compatibility
--flavorsee no change: same build directory, same binary name, same generated CMake.windows/CMakeLists.txtto keep working; they only need to regenerate (or hand-patch theif(DEFINED FLUTTER_APP_FLAVOR)branch) to opt into flavor support.Fixes #98994
Pre-launch Checklist
///).