Unverified Commit 52a6de25 authored by Matan Lurey's avatar Matan Lurey Committed by GitHub

Add `--local-engine-host`, which if specified, is used instead of being inferred (#132180)

Closes https://github.com/flutter/flutter/issues/132162.

I did a tiny bit of minor cleanup but didn't want to go 🍔 beyond the
scope of this change. After it lands I'll update the Wiki.

## Before

```bash
$ fl run \
  --local-engine-src-path=$ENGINE \
  --local-engine=android_debug_unopt_arm64
```

... would try to use `host_debug_unopt` (i.e. Rosetta).

## After

```bash
$ fl run \
  --local-engine-src-path=$ENGINE \
  --local-engine=android_debug_unopt_arm64 \
  --local-engine-host=host_debug_unopt_arm64
```

... uses `host_debug_unopt_arm64`, as specified.

---

/cc @jonahwilliams @gaaclarke @zanderso
parent bd1bb675
......@@ -28,8 +28,8 @@ SPEC CHECKSUMS:
connectivity_macos: 5dae6ee11d320fac7c05f0d08bd08fc32b5514d9
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
PODFILE CHECKSUM: 2e6060c123c393d6beb3ee5b7beaf789de4d2e47
COCOAPODS: 1.12.0
COCOAPODS: 1.12.1
......@@ -308,6 +308,12 @@ class UserMessages {
"you have compiled the engine in that directory, which should produce an 'out' directory";
String get runnerLocalEngineOrWebSdkRequired =>
'You must specify --local-engine or --local-web-sdk if you are using a locally built engine or web sdk.';
// TODO(matanlurey): Make this an error, https://github.com/flutter/flutter/issues/132245.
String get runnerLocalEngineRequiresHostEngine =>
'Warning! You are using a locally built engine (--local-engine) but have not specified --local-host-engine.\n'
'You may be building with a different engine than the one you are running with. '
'See https://github.com/flutter/flutter/issues/132245 for details (in the future this will become '
'an error).';
String runnerNoEngineBuild(String engineBuildPath) =>
'No Flutter engine build found at $engineBuildPath.';
String runnerNoWebSdk(String webSdkPath) =>
......
......@@ -30,6 +30,7 @@ abstract final class FlutterGlobalOptions {
static const String kEnableTelemetryFlag = 'enable-telemetry';
static const String kLocalEngineOption = 'local-engine';
static const String kLocalEngineSrcPathOption = 'local-engine-src-path';
static const String kLocalEngineHostOption = 'local-engine-host';
static const String kLocalWebSDKOption = 'local-web-sdk';
static const String kMachineFlag = 'machine';
static const String kPackagesOption = 'packages';
......@@ -131,6 +132,13 @@ class FlutterCommandRunner extends CommandRunner<void> {
'Use this to select a specific version of the engine if you have built multiple engine targets.\n'
'This path is relative to "--local-engine-src-path" (see above).');
argParser.addOption(FlutterGlobalOptions.kLocalEngineHostOption,
hide: !verboseHelp,
help: 'The host operating system for which engine artifacts should be selected, if you are building Flutter locally.\n'
'This is only used when "--local-engine" is also specified.\n'
'By default, the host is determined automatically, but you may need to specify this if you are building on one '
'platform (e.g. MacOS ARM64) but intend to run Flutter on another (e.g. Android).');
argParser.addOption(FlutterGlobalOptions.kLocalWebSDKOption,
hide: !verboseHelp,
help: 'Name of a build output within the engine out directory, if you are building Flutter locally.\n'
......@@ -273,6 +281,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
final EngineBuildPaths? engineBuildPaths = await globals.localEngineLocator?.findEnginePath(
engineSourcePath: topLevelResults[FlutterGlobalOptions.kLocalEngineSrcPathOption] as String?,
localEngine: topLevelResults[FlutterGlobalOptions.kLocalEngineOption] as String?,
localHostEngine: topLevelResults[FlutterGlobalOptions.kLocalEngineHostOption] as String?,
localWebSdk: topLevelResults[FlutterGlobalOptions.kLocalWebSDKOption] as String?,
packagePath: topLevelResults[FlutterGlobalOptions.kPackagesOption] as String?,
);
......
......@@ -13,7 +13,7 @@ import '../base/user_messages.dart' hide userMessages;
import '../cache.dart';
import '../dart/package_map.dart';
/// A strategy for locating the out/ directory of a local engine build.
/// A strategy for locating the `out/` directory of a local engine build.
///
/// The flutter tool can be run with the output files of one or more engine builds
/// replacing the cached artifacts. Typically this is done by setting the
......@@ -25,7 +25,7 @@ import '../dart/package_map.dart';
/// For scenarios where the engine is not adjacent to flutter, the
/// `--local-engine-src-path` can be provided to give an exact path.
///
/// For more information on local engines, see CONTRIBUTING.md.
/// For more information on local engines, see README.md.
class LocalEngineLocator {
LocalEngineLocator({
required Platform platform,
......@@ -46,7 +46,13 @@ class LocalEngineLocator {
final UserMessages _userMessages;
/// Returns the engine build path of a local engine if one is located, otherwise `null`.
Future<EngineBuildPaths?> findEnginePath({String? engineSourcePath, String? localEngine, String? localWebSdk, String? packagePath}) async {
Future<EngineBuildPaths?> findEnginePath({
String? engineSourcePath,
String? localEngine,
String? localHostEngine,
String? localWebSdk,
String? packagePath,
}) async {
engineSourcePath ??= _platform.environment[kFlutterEngineEnvironmentVariableName];
if (engineSourcePath == null && localEngine == null && localWebSdk == null && packagePath == null) {
return null;
......@@ -81,7 +87,12 @@ class LocalEngineLocator {
if (engineSourcePath != null) {
_logger.printTrace('Local engine source at $engineSourcePath');
return _findEngineBuildPath(localEngine, localWebSdk, engineSourcePath);
return _findEngineBuildPath(
engineSourcePath: engineSourcePath,
localEngine: localEngine,
localWebSdk: localWebSdk,
localHostEngine: localHostEngine,
);
}
if (localEngine != null || localWebSdk != null) {
throwToolExit(
......@@ -176,7 +187,12 @@ class LocalEngineLocator {
return 'host_$tmpBasename';
}
EngineBuildPaths _findEngineBuildPath(String? localEngine, String? localWebSdk, String enginePath) {
EngineBuildPaths _findEngineBuildPath({
required String engineSourcePath,
String? localEngine,
String? localWebSdk,
String? localHostEngine,
}) {
if (localEngine == null && localWebSdk == null) {
throwToolExit(_userMessages.runnerLocalEngineOrWebSdkRequired, exitCode: 2);
}
......@@ -184,12 +200,16 @@ class LocalEngineLocator {
String? engineBuildPath;
String? engineHostBuildPath;
if (localEngine != null) {
engineBuildPath = _fileSystem.path.normalize(_fileSystem.path.join(enginePath, 'out', localEngine));
engineBuildPath = _fileSystem.path.normalize(_fileSystem.path.join(engineSourcePath, 'out', localEngine));
if (!_fileSystem.isDirectorySync(engineBuildPath)) {
throwToolExit(_userMessages.runnerNoEngineBuild(engineBuildPath), exitCode: 2);
}
final String basename = _fileSystem.path.basename(engineBuildPath);
if (localHostEngine == null) {
// TODO(matanlurey): https://github.com/flutter/flutter/issues/132245, change to throwToolExit.
_logger.printStatus(_userMessages.runnerLocalEngineRequiresHostEngine);
}
final String basename = localHostEngine ?? _fileSystem.path.basename(engineBuildPath);
final String hostBasename = _getHostEngineBasename(basename);
engineHostBuildPath = _fileSystem.path.normalize(
_fileSystem.path.join(_fileSystem.path.dirname(engineBuildPath), hostBasename),
......@@ -201,7 +221,7 @@ class LocalEngineLocator {
String? webSdkPath;
if (localWebSdk != null) {
webSdkPath = _fileSystem.path.normalize(_fileSystem.path.join(enginePath, 'out', localWebSdk));
webSdkPath = _fileSystem.path.normalize(_fileSystem.path.join(engineSourcePath, 'out', localWebSdk));
if (!_fileSystem.isDirectorySync(webSdkPath)) {
throwToolExit(_userMessages.runnerNoWebSdk(webSdkPath), exitCode: 2);
}
......
......@@ -93,6 +93,58 @@ void main() {
expect(logger.traceText, contains('Local engine source at /arbitrary/engine/src'));
});
testWithoutContext('works if --local-engine is specified and --local-engine-host is specified', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final Directory localEngine = fileSystem
.directory('$kArbitraryEngineRoot/src/out/android_debug_unopt_arm64/')
..createSync(recursive: true);
fileSystem.directory('$kArbitraryEngineRoot/src/out/host_debug_unopt_arm64/').createSync(recursive: true);
final BufferLogger logger = BufferLogger.test();
final LocalEngineLocator localEngineLocator = LocalEngineLocator(
fileSystem: fileSystem,
flutterRoot: 'flutter/flutter',
logger: logger,
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{}),
);
expect(
await localEngineLocator.findEnginePath(localEngine: localEngine.path, localHostEngine: 'host_debug_unopt_arm64'),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug_unopt_arm64',
targetEngine: '/arbitrary/engine/src/out/android_debug_unopt_arm64',
),
);
expect(logger.traceText, contains('Local engine source at /arbitrary/engine/src'));
});
testWithoutContext('works but produces a warning if --local-engine is specified but not --local-host-engine', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final Directory localEngine = fileSystem
.directory('$kArbitraryEngineRoot/src/out/android_debug_unopt_arm64/')
..createSync(recursive: true);
fileSystem.directory('$kArbitraryEngineRoot/src/out/host_debug_unopt/').createSync(recursive: true);
final BufferLogger logger = BufferLogger.test();
final LocalEngineLocator localEngineLocator = LocalEngineLocator(
fileSystem: fileSystem,
flutterRoot: 'flutter/flutter',
logger: logger,
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{}),
);
expect(
await localEngineLocator.findEnginePath(localEngine: localEngine.path),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug_unopt',
targetEngine: '/arbitrary/engine/src/out/android_debug_unopt_arm64',
),
);
expect(logger.statusText, contains('Warning! You are using a locally built engine (--local-engine) but have not specified --local-host-engine'));
});
testWithoutContext('works if --local-engine is specified and --local-engine-src-path '
'is determined by --local-engine', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment