Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dev/integration_tests/flutter_gallery/macos/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions packages/flutter_tools/lib/src/base/user_messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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?,
);
Expand Down
36 changes: 28 additions & 8 deletions packages/flutter_tools/lib/src/runner/local_engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -176,20 +187,29 @@ 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);
}

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),
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down