Add docs on 'Create app flavors for Windows and Linux' - #13736
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new documentation guide for setting up Flutter flavors on Windows and Linux desktop apps, along with updating existing docs and navigation links to reference it. Feedback on the new guide highlights a critical MDX syntax error with an unclosed <Tabs> tag, and suggests providing more concrete, actionable CMake and configuration examples for customizing application icons on both Windows and Linux.
|
Staged preview of the updated docs.flutter.dev site (updated for commit 8491f5e): https://flutter-docs-prod--docs-pr13736-flavors-windows-linux-5airv7fi.web.app |
This comment was marked as resolved.
This comment was marked as resolved.
|
Staged preview of the updated flutter.dev site (updated for commit 8491f5e): https://flutter-dev-230821--www-pr13736-flavors-windows-linux-ljw8my0n.web.app |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
| 1. Open `linux/runner/CMakeLists.txt` and pass `FLUTTER_APP_FLAVOR` | ||
| as a preprocessor definition: | ||
|
|
||
| ```cmake title="linux/runner/CMakeLists.txt" | ||
| if(DEFINED FLUTTER_APP_FLAVOR AND NOT FLUTTER_APP_FLAVOR STREQUAL "") | ||
| target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_APP_FLAVOR=\"${FLUTTER_APP_FLAVOR}\"") | ||
| endif() | ||
| ``` | ||
|
|
||
| 1. Open `linux/runner/my_application.cc` and update the window title | ||
| in the `my_application_activate` function: | ||
|
|
||
| ```c title="linux/runner/my_application.cc" | ||
| #if defined(FLUTTER_APP_FLAVOR) | ||
| const char* title = "flavors_example (" FLUTTER_APP_FLAVOR ")"; | ||
| #else | ||
| const char* title = "flavors_example"; | ||
| #endif | ||
|
|
||
| if (use_header_bar) { | ||
| GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); | ||
| gtk_widget_show(GTK_WIDGET(header_bar)); | ||
| gtk_header_bar_set_title(header_bar, title); | ||
| gtk_header_bar_set_show_close_button(header_bar, TRUE); | ||
| gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); | ||
| } else { | ||
| gtk_window_set_title(window, title); | ||
| } | ||
| ``` |
There was a problem hiding this comment.
The Linux mechanism here is correct — unlike the Windows tab. GTK takes narrow const char* strings, so the preprocessor define works directly with no conversion. flutter_flavorizr does exactly this, and its example project builds and runs with it.
Two adjustments to match what actually works:
1. Placement. target_compile_definitions(${BINARY_NAME} …) needs the target to exist, so it must come after add_executable(${BINARY_NAME} …). flutter_flavorizr anchors on the existing APPLICATION_ID define, which is already correctly positioned:
# Add preprocessor definitions for the application ID.
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
if(DEFINED FLUTTER_APP_FLAVOR AND NOT FLUTTER_APP_FLAVOR STREQUAL "")
add_definitions(-DFLUTTER_APP_FLAVOR="${FLUTTER_APP_FLAVOR}")
endif()Placing the new block right after the APPLICATION_ID line is an easy instruction to follow and is guaranteed to be in scope.
2. my_application.cc snippet doesn't match the file it's editing. The generated my_application_activate passes the title as a string literal in two places. The snippet introduces a title variable but shows the if (use_header_bar) block dedented to column 0, whereas in the real file it's indented two spaces inside the function — so this can't be pasted as-is.
The working shape, which keeps the diff to the existing code minimal:
const gchar* window_title = "flavors_example";
#ifdef FLUTTER_APP_FLAVOR
if (g_strcmp0(FLUTTER_APP_FLAVOR, "staging") == 0) {
window_title = "Staging App";
} else if (g_strcmp0(FLUTTER_APP_FLAVOR, "production") == 0) {
window_title = "Production App";
}
#endifthen replace the two hardcoded literals with window_title:
gtk_header_bar_set_title(header_bar, window_title);
...
gtk_window_set_title(window, window_title);Using g_strcmp0 rather than string concatenation also lets each flavor have a fully custom title instead of AppName (flavor), which is closer to what people actually want from flavors.
There was a problem hiding this comment.
I believe this is fixed.
| 1. Prepare your icon files in `.ico` format | ||
| (for example, `app_icon_staging.ico` and `app_icon_production.ico`) | ||
| and place them in `windows/runner/resources/`. | ||
|
|
||
| 1. In `windows/CMakeLists.txt`, select the appropriate icon file | ||
| based on `FLUTTER_APP_FLAVOR`: | ||
|
|
||
| ```cmake title="windows/CMakeLists.txt" | ||
| if(FLUTTER_APP_FLAVOR STREQUAL "staging") | ||
| set(APP_ICON_NAME "app_icon_staging.ico") | ||
| elseif(FLUTTER_APP_FLAVOR STREQUAL "production") | ||
| set(APP_ICON_NAME "app_icon_production.ico") | ||
| else() | ||
| set(APP_ICON_NAME "app_icon.ico") | ||
| endif() | ||
| ``` | ||
|
|
||
| 1. Configure `windows/runner/Runner.rc` or your CMake target | ||
| to use `APP_ICON_NAME` for the application icon resource. |
There was a problem hiding this comment.
Blocking — this section isn't implementable as written.
Two problems:
-
The snippet targets
windows/CMakeLists.txt, whereFLUTTER_APP_FLAVORis still undefined (same scope issue as the earlier section).if(FLUTTER_APP_FLAVOR STREQUAL "staging")on an undefined variable is always false, soAPP_ICON_NAMEsilently falls through toelse(). -
Step 3 — "Configure
windows/runner/Runner.rcor your CMake target to useAPP_ICON_NAME" — is the entire difficulty, and it's left as an exercise.Runner.rcis a resource script; it cannot read CMake variables. There is no way to complete this step from what the page provides.
flutter_flavorizr handles this with the same configure_file pass proposed in my comment on the window-title section — one mechanism covering icon, title, and PE metadata. Extend that block in windows/runner/CMakeLists.txt, before add_executable:
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/Runner.rc.in"
"${CMAKE_CURRENT_SOURCE_DIR}/Runner.rc"
@ONLY
)Rename Runner.rc to Runner.rc.in and parameterize it — these are the exact substitutions its example project ships:
IDI_APP_ICON ICON "resources\\@RUNNER_APP_ICON@"
VALUE "FileDescription", "@WINDOW_TITLE@" "\0"
VALUE "ProductName", "@WINDOW_TITLE@" "\0"
with the per-flavor .ico files sitting in windows/runner/resources/ alongside the default app_icon.ico.
Same caveat as before: Runner.rc becomes a generated file, so it should be gitignored while Runner.rc.in is committed.
There was a problem hiding this comment.
I believe this is fixed.
| 1. Prepare PNG icons for each flavor | ||
| (for example, `app_icon_staging.png` and `app_icon_production.png`). | ||
|
|
||
| 1. Create corresponding `.desktop` files for each flavor | ||
| (for example, `flavors_example_staging.desktop` and | ||
| `flavors_example_production.desktop`) | ||
| that reference the respective icon and executable binary name. | ||
|
|
||
| 1. Update `linux/CMakeLists.txt` to install the correct `.desktop` file | ||
| and icon based on `FLUTTER_APP_FLAVOR`. |
There was a problem hiding this comment.
This section is prose-only, and step 3 — "Update linux/CMakeLists.txt to install the correct .desktop file and icon" — is where all the actual work lives. A reader can't act on it.
It's also genuinely harder than the Windows case: on Linux the icon isn't embedded in the binary, so it depends on .desktop entries, the icon theme layout, and the packaging format (snap/deb/flatpak).
I'd suggest cutting these three steps and linking to Build and release a Linux app instead, noting that per-flavor icons are a packaging concern rather than a flavor concern. Shipping three non-actionable bullets sets readers up to fail — and I'd rather not propose a concrete recipe here, since I don't have a verified working example to base one on.
There was a problem hiding this comment.
I believe this is fixed.
|
@AngeloAvv, I want to thank you for your ENORMOUSLY detailed and helpful review!!! (In fact, if you could email me at shaza@google, I'd like to thank you tangibly....) I can tell that you are an educator! I believe I have incorporated all of your feedback. Could you do a quick check and confirm? Staged here: |
Closes #13642
Adds documentation for setting up app flavors on Windows and Linux desktop platforms.