mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[engine_build_configs] Use dart:ffi Abi to determine the host cpu (flutter/engine#50604)
Follow-up on https://github.com/flutter/engine/pull/50543#discussion_r1486546946
This commit is contained in:
parent
5b220df694
commit
9f2ff32022
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ffi' as ffi;
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:engine_build_configs/engine_build_configs.dart';
|
||||
@ -119,6 +120,7 @@ The build names are the "name" fields of the maps in the list of "builds".
|
||||
final GlobalBuildRunner buildRunner = GlobalBuildRunner(
|
||||
platform: const LocalPlatform(),
|
||||
processRunner: ProcessRunner(),
|
||||
abi: ffi.Abi.current(),
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: extraGnArgs,
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io' as io show Directory, Process, ProcessResult;
|
||||
import 'dart:ffi' as ffi;
|
||||
import 'dart:io' as io show Directory, Process;
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
@ -111,7 +112,13 @@ typedef RunnerEventHandler = void Function(RunnerEvent);
|
||||
/// An abstract base clase for running the various tasks that a build config
|
||||
/// specifies. Derived classes implement the `run()` method.
|
||||
sealed class Runner {
|
||||
Runner(this.platform, this.processRunner, this.engineSrcDir, this.dryRun);
|
||||
Runner(
|
||||
this.platform,
|
||||
this.processRunner,
|
||||
this.abi,
|
||||
this.engineSrcDir,
|
||||
this.dryRun,
|
||||
);
|
||||
|
||||
/// Information about the platform that hosts the runner.
|
||||
final Platform platform;
|
||||
@ -119,6 +126,9 @@ sealed class Runner {
|
||||
/// Runs the subprocesses required to run the element of the build config.
|
||||
final ProcessRunner processRunner;
|
||||
|
||||
/// The [Abi] of the host platform.
|
||||
final ffi.Abi abi;
|
||||
|
||||
/// The src/ directory of the engine checkout.
|
||||
final io.Directory engineSrcDir;
|
||||
|
||||
@ -162,6 +172,7 @@ final class GlobalBuildRunner extends Runner {
|
||||
GlobalBuildRunner({
|
||||
Platform? platform,
|
||||
ProcessRunner? processRunner,
|
||||
ffi.Abi? abi,
|
||||
required io.Directory engineSrcDir,
|
||||
required this.build,
|
||||
this.extraGnArgs = const <String>[],
|
||||
@ -175,6 +186,7 @@ final class GlobalBuildRunner extends Runner {
|
||||
}) : super(
|
||||
platform ?? const LocalPlatform(),
|
||||
processRunner ?? ProcessRunner(),
|
||||
abi ?? ffi.Abi.current(),
|
||||
engineSrcDir,
|
||||
dryRun,
|
||||
);
|
||||
@ -289,22 +301,20 @@ final class GlobalBuildRunner extends Runner {
|
||||
}
|
||||
|
||||
late final String _hostCpu = (){
|
||||
if (platform.isWindows) {
|
||||
return platform.environment['PROCESSOR_ARCHITECTURE'] ?? 'x64';
|
||||
}
|
||||
final List<String> unameCommand = <String>['uname', '-m'];
|
||||
final io.ProcessResult unameResult = processRunner.processManager.runSync(
|
||||
unameCommand,
|
||||
);
|
||||
return unameResult.exitCode == 0 ? (unameResult.stdout as String).trim() : 'x64';
|
||||
return switch (abi) {
|
||||
ffi.Abi.linuxArm64 || ffi.Abi.macosArm64 || ffi.Abi.windowsArm64 => 'arm64',
|
||||
ffi.Abi.linuxX64 || ffi.Abi.macosX64 || ffi.Abi.windowsX64 => 'x64',
|
||||
_ => throw StateError('This host platform "$abi" is not supported.'),
|
||||
};
|
||||
}();
|
||||
|
||||
late final String _buildtoolsPath = (){
|
||||
final String platformDir = switch (platform.operatingSystem) {
|
||||
final String os = platform.operatingSystem;
|
||||
final String platformDir = switch (os) {
|
||||
Platform.linux => 'linux-$_hostCpu',
|
||||
Platform.macOS => 'mac-$_hostCpu',
|
||||
Platform.windows => 'windows-$_hostCpu',
|
||||
_ => '<unknown>',
|
||||
_ => throw StateError('This host OS "$os" is not supported.'),
|
||||
};
|
||||
return p.join(engineSrcDir.path, 'buildtools', platformDir);
|
||||
}();
|
||||
@ -317,11 +327,12 @@ final class GlobalBuildRunner extends Runner {
|
||||
final String exe = platform.isWindows ? '.exe' : '';
|
||||
final String bootstrapPath = p.join(reclientPath, 'bootstrap$exe');
|
||||
final String reproxyPath = p.join(reclientPath, 'reproxy$exe');
|
||||
final String reclientConfigFile = switch (platform.operatingSystem) {
|
||||
final String os = platform.operatingSystem;
|
||||
final String reclientConfigFile = switch (os) {
|
||||
Platform.linux => 'reclient-linux.cfg',
|
||||
Platform.macOS => 'reclient-mac.cfg',
|
||||
Platform.windows => 'reclient-win.cfg',
|
||||
_ => '<unknown>',
|
||||
_ => throw StateError('This host OS "$os" is not supported.'),
|
||||
};
|
||||
final String reclientConfigPath = p.join(
|
||||
engineSrcDir.path, 'flutter', 'build', 'rbe', reclientConfigFile,
|
||||
@ -487,6 +498,7 @@ final class GlobalBuildRunner extends Runner {
|
||||
final BuildTaskRunner runner = BuildTaskRunner(
|
||||
processRunner: processRunner,
|
||||
platform: platform,
|
||||
abi: abi,
|
||||
engineSrcDir: engineSrcDir,
|
||||
task: task,
|
||||
dryRun: dryRun,
|
||||
@ -503,6 +515,7 @@ final class GlobalBuildRunner extends Runner {
|
||||
final BuildTestRunner runner = BuildTestRunner(
|
||||
processRunner: processRunner,
|
||||
platform: platform,
|
||||
abi: abi,
|
||||
engineSrcDir: engineSrcDir,
|
||||
test: test,
|
||||
extraTestArgs: extraTestArgs,
|
||||
@ -521,12 +534,14 @@ final class BuildTaskRunner extends Runner {
|
||||
BuildTaskRunner({
|
||||
Platform? platform,
|
||||
ProcessRunner? processRunner,
|
||||
ffi.Abi? abi,
|
||||
required io.Directory engineSrcDir,
|
||||
required this.task,
|
||||
bool dryRun = false,
|
||||
}) : super(
|
||||
platform ?? const LocalPlatform(),
|
||||
processRunner ?? ProcessRunner(),
|
||||
abi ?? ffi.Abi.current(),
|
||||
engineSrcDir,
|
||||
dryRun,
|
||||
);
|
||||
@ -571,6 +586,7 @@ final class BuildTestRunner extends Runner {
|
||||
BuildTestRunner({
|
||||
Platform? platform,
|
||||
ProcessRunner? processRunner,
|
||||
ffi.Abi? abi,
|
||||
required io.Directory engineSrcDir,
|
||||
required this.test,
|
||||
this.extraTestArgs = const <String>[],
|
||||
@ -578,6 +594,7 @@ final class BuildTestRunner extends Runner {
|
||||
}) : super(
|
||||
platform ?? const LocalPlatform(),
|
||||
processRunner ?? ProcessRunner(),
|
||||
abi ?? ffi.Abi.current(),
|
||||
engineSrcDir,
|
||||
dryRun,
|
||||
);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:convert' as convert;
|
||||
import 'dart:ffi' as ffi;
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:engine_build_configs/src/build_config.dart';
|
||||
@ -39,6 +40,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
task: generator,
|
||||
dryRun: true,
|
||||
@ -65,6 +67,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
test: test,
|
||||
dryRun: true,
|
||||
@ -93,6 +96,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
dryRun: true,
|
||||
@ -154,6 +158,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--extra-gn-arg'],
|
||||
@ -193,6 +198,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--goma'],
|
||||
@ -218,10 +224,9 @@ void main() {
|
||||
final GlobalBuildRunner buildRunner = GlobalBuildRunner(
|
||||
platform: FakePlatform(operatingSystem: Platform.linux),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: _fakeProcessManager(
|
||||
unameResult: io.ProcessResult(1, 0, 'arm64', ''),
|
||||
),
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--rbe'],
|
||||
@ -263,6 +268,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
runGn: false,
|
||||
@ -297,6 +303,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
runNinja: false,
|
||||
@ -338,6 +345,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
runGenerators: false,
|
||||
@ -381,6 +389,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
runTests: false,
|
||||
@ -409,10 +418,9 @@ void main() {
|
||||
final GlobalBuildRunner buildRunner = GlobalBuildRunner(
|
||||
platform: FakePlatform(operatingSystem: Platform.linux),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: _fakeProcessManager(
|
||||
unameResult: io.ProcessResult(1, 0, 'arm64', ''),
|
||||
),
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--no-lto', '--no-goma', '--rbe'],
|
||||
@ -448,6 +456,7 @@ void main() {
|
||||
// dryRun should not try to spawn any processes.
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
dryRun: true,
|
||||
@ -469,6 +478,7 @@ void main() {
|
||||
gnResult: io.ProcessResult(1, 1, '', ''),
|
||||
),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
);
|
||||
@ -495,6 +505,7 @@ void main() {
|
||||
ninjaResult: io.ProcessResult(1, 1, '', ''),
|
||||
),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
);
|
||||
@ -518,10 +529,10 @@ void main() {
|
||||
platform: FakePlatform(operatingSystem: Platform.linux),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: _fakeProcessManager(
|
||||
unameResult: io.ProcessResult(1, 0, 'arm64', ''),
|
||||
bootstrapResult: io.ProcessResult(1, 1, '', ''),
|
||||
),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--rbe'],
|
||||
@ -547,7 +558,6 @@ void main() {
|
||||
platform: FakePlatform(operatingSystem: Platform.linux),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: _fakeProcessManager(
|
||||
unameResult: io.ProcessResult(1, 0, 'arm64', ''),
|
||||
canRun: (Object? exe, {String? workingDirectory}) {
|
||||
if (exe is String? && exe != null && exe.endsWith('bootstrap')) {
|
||||
return false;
|
||||
@ -556,6 +566,7 @@ void main() {
|
||||
},
|
||||
),
|
||||
),
|
||||
abi: ffi.Abi.linuxX64,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--rbe'],
|
||||
@ -568,10 +579,31 @@ void main() {
|
||||
|
||||
expect(events[2] is RunnerError, isTrue);
|
||||
});
|
||||
|
||||
test('GlobalBuildRunner throws a StateError on an unsupported host cpu', () async {
|
||||
final GlobalBuild targetBuild = buildConfig.builds[0];
|
||||
final GlobalBuildRunner buildRunner = GlobalBuildRunner(
|
||||
platform: FakePlatform(operatingSystem: Platform.linux),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: _fakeProcessManager(),
|
||||
),
|
||||
abi: ffi.Abi.linuxRiscv32,
|
||||
engineSrcDir: engine.srcDir,
|
||||
build: targetBuild,
|
||||
extraGnArgs: <String>['--rbe'],
|
||||
);
|
||||
|
||||
bool caughtError = false;
|
||||
try {
|
||||
await buildRunner.run((RunnerEvent event) {});
|
||||
} on StateError catch (_) {
|
||||
caughtError = true;
|
||||
}
|
||||
expect(caughtError, isTrue);
|
||||
});
|
||||
}
|
||||
|
||||
FakeProcessManager _fakeProcessManager({
|
||||
io.ProcessResult? unameResult,
|
||||
io.ProcessResult? bootstrapResult,
|
||||
io.ProcessResult? gnResult,
|
||||
io.ProcessResult? ninjaResult,
|
||||
@ -587,7 +619,6 @@ FakeProcessManager _fakeProcessManager({
|
||||
return FakeProcessManager(
|
||||
canRun: canRun ?? (Object? exe, {String? workingDirectory}) => true,
|
||||
onRun: (List<String> cmd) => switch (cmd) {
|
||||
['uname', ...] => unameResult ?? success,
|
||||
_ => failUnknown ? io.ProcessResult(1, 1, '', '') : success,
|
||||
},
|
||||
onStart: (List<String> cmd) => switch (cmd) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user