et
, or engine tool, is a command-line tool that intends to provide a unified interface for building and working in the flutter engine.
Table of Contents:
et
assumes that you have a working knowledge of the Flutter framework and engine (see: architectural layers), and have a valid checkout of the engine source on a supported platform (see: setting up the engine development environment); in fact, the tool will not run at all outside of a valid repository setup.
It is recommended to add et
to your PATH
by adding the bin
folder:
PATH=$PATH:/path/to/engine/flutter/bin
To verify you have a working installation, try et help
:
$ et help A command line tool for working on the Flutter Engine. This is a community supported project, file a bug or feature request: https://flutter.dev/to/engine-tool-bug. Usage: et <command> [arguments] Global options: -h, --help Print this usage information. -v, --verbose Prints verbose output Available commands: build Builds the engine fetch Download the Flutter engine's dependencies format Formats files using standard formatters and styles. lint Lint the engine repository. query Provides information about build configurations and tests. run Run a Flutter app with a local engine build. test Runs a test target Run "et help <command>" for more information about a command.
Many commands in et
use or reference a build configuration, often explicitly specified using --config
(or the short-hand -c
).
A build configuration has at least:
drone_dimensions
);gn
);name
, description
);Build configurations are typically defined in ci/builders
, where they either live in a task-specific configuration file (i.e. to build and run tests on CI), such as mac_unopt.json
, or one of many configurations that are used only for local development and iteration in local_engine.json
. The builds specified in these files are referenced by name as --config
:
# Implicitly references ci/builders/mac_unopt.json et build --config ci/host_debug_unopt_arm64 # Implicitly references ci/builders/local_engine.json et build --config host_debug_unopt_arm64
See building a host engine and building a target engine for more details.
[!CAUTION] Each build configuration (sometimes called a variant) produces a different set of output files in
$ENGINE/src/out
, e.g. ``$ENGINE/src/out/host_debug; these outputs can be multiple GBs, and add up quickly. Consider using [
et cleanup`](#reclaiming-older-output-directories) to delete older output directories automatically.
Tasks we expect the majority of contributors and users of the engine to need.
The default and most common operation is to build a host variant of the engine, or an engine that runs on the local (desktop) operating system currently being used. For example, when running on an ARM64 macOS laptop, an ARM64 macOS desktop engine build, or when running an x64 Linux desktop, a x64 Linux desktop engine build.
# Builds the current platform's (host) debug build. et build # Equivalent to the above. et build --config host_debug
[!TIP] To understand where the names come from, see understanding the concept of a build configuration.
A host engine is useful when:
The Flutter engine supports multiple target engines, or engines not native to the current desktop-class operating system, such as Android or iOS. For example, when running on a MacOS laptop or desktop, you can build an iOS simulator or application engine:
# Builds an iOS device (non-simulator) engine. et build --config ios_debug # Builds an iOS simulator engine. et build --config ios_debug_sim
By convention, target engines are not prefixed with host
.
A target engine is useful when:
By default, the entire engine is built.
For example these commands are equivalent:
et build --config host_debug et build --config host_debug //flutter/...
While caching often avoids rebuilding parts of the engine that have not changed, sometimes you as the developer will have more information than the dependency tree on what exactly needs to be rebuilt between changes. To build specific targets, provide the fully qualified path to the GN
target:
# Builds only the "flutter.jar" artifact. et build --config android_debug_unopt_arm64 //flutter/shell/platform/android:android_jar
To build all targets in particular directory, recursively, use /dirname/...
:
# Builds all targets, recursively, in //flutter/shell/platform. et build --config android_debug_unopt_arm64 //flutter/shell/platform/...
To build all targets in particular directory, non-recursively, use :all
:
# Builds all targets, non-recursively, in //flutter/shell/platform. et build --config android_debug_unopt_arm64 //flutter/shell/platform:all
C++ unit tests can be simulatenously rebuilt and run using et test
:
et test //flutter/impeller:impeller_unittests
Both /...
and :all
are supported as well.
[!NOTE] Support for non-C++ tests is limited. See running Dart tests.
To run all formatters on changed files, use et format
:
et format
Sometimes a dependency change (or change in a tool) might invalidate the format checks of a file you did not change (dirty):
# Checks *all* files, which is *much* slower! et format --all
Similar to formatters, global linters can be run with et lint
:
et lint
At the time of this writing, the linters always operate on the entire repository.
Normally to run a Flutter application with a prebuilt engine, you'd run:
cd to/project/dir flutter run
While iterating on the engine source, you may want to use the engine outputs (both host and target) built above. et run
can help:
cd to/project/dir et run
[!NOTE] >
et run
will rebuild (if necessary) host and target builds, which can take a significant amount of time.
Tasks that might be restricted to a subset of the engine team, or for upstream users (such as developers that work on the Dart VM or SDK teams). Features may be in a somewhat incomplete state compared to common tasks, or might be a bit less intuitive or easy to use.
Google employees have the option of using remote-build execution, or RBE, to greatly speed up many builds by reusing previously built (and cached) artifacts as well as delegating the compiler to a high-powered (remote) virtual machine.
To enable RBE, follow flutter.dev/to/engine-rbe.
Once enabled, by default, et
builds will use RBE where possible, which also (implicitly) requires an active internet connection. It is possible to temporarily (for one command) change whether to prefer remote builds or exclusively use local builds by using --build-strategy
:
# Exclusively builds locally, which can be faster for some incremental builds. # Does not require an internet connection. et build --build-strategy=local # Exclusively builds remotely, which is less taxing on your local machine. # Requires a fast internet connection. et build --build-strategy=remote
To disable RBE once it is enabled, a build can use --no-rbe
:
et build --no-rbe
[!CAUTION] Disabling RBE invalidates the build context, which means that previously built artifacts (when the flag was enabled) are not re-used. It is recommended to use
--build-strategy=local
instead unless you are debugging the tool or the RBE configuration itself.
There is limited support for running Dart unittests using et
:
et test //flutter/tools/engine_tool/...
[!NOTE] Unlike C++, it is not currently required to have
BUILD.gn
targets declared for Dart tests, and the vast majority of packages do not have them. As we add and adopt GN more broadly this command will become more generally useful.
Most of the time developers will use a pre-configured engine configuration (see understanding the concept of a build configuration) as these configurations are already generally supported, and often tested on CI. If you need to build a configuration not-specified, consider the following:
Does my configuration represent a combination of flags that should be tested on CI or re-used by others?
If so, the best option may be adding the build to ci/builders, either as a CI build or merely as a local engine build. By adding your build here it will be reproducible for other developers, documented, and automatically usable within the et
command-line tool.
Is my configuration for 1-off testing or validation only?
If so, any combination of additional GN arguments (i.e. arguments that otherwise would be parsed by tools/gn) can be provided by passing --gn-args
, often in conjunction with an existing configuration template.
For example, using link-time optimization (LTO):
et build --config host_release --lto
Or, using a from-source Dart SDK (often used by Dart SDK and VM developers):
et build --config host_debug --gn-args="--no-prebuilt-dart-sdk"
[!TIP] For more information on build configurations, see the README.
The et cleanup
command removes older output directories that have not been accessed, by default in the last 30 days, but customizable with the command-line argument --untouched-since
.
Consider using dry-run
to preview what would be deleted:
# Deletes all output directories older than 30 days. et cleanup # Shows what output directories would be deleted by the above command. et cleanup --dry-run # Deletes all output directories accessed last in 2023. et cleanup --untouched-since=2024-01-01
We welcome contributions to improve et
for our all developers.
dart format
in the future.dart:io
except from main.dart
. Instead access the system only through the Enviroment
object.Run tests using et
:
et test //flutter/tools/engine_tool/...
If you're not sure what to work on, consider our existing label of e: engine-tool
: