Cross-compile from x64 to arm64 (#20)

This commit is contained in:
Hidenori Matsubayashi
2021-07-27 14:17:50 +09:00
committed by GitHub
parent d6d8ba9d90
commit 0a3ef762f5
6 changed files with 65 additions and 7 deletions
+29 -5
View File
@@ -44,6 +44,21 @@ class BuildPackageCommand extends BuildSubCommand with ELinuxExtension {
allowed: <String>['wayland', 'gbm', 'eglstream', 'x11'],
help: 'Target backend type that the app will run on devices.',
);
argParser.addOption(
'target-sysroot',
defaultsTo: '/',
help: 'The root filesystem path of target platform for which '
'the app is compiled. This option is valid only '
'if the current host and target architectures are different.',
);
argParser.addOption(
'system-include-directories',
defaultsTo: null,
help:
'The additional system include paths to cross-compile for target platform. '
'This option is valid only '
'if the current host and target architectures are different.',
);
}
@override
@@ -70,12 +85,21 @@ class BuildPackageCommand extends BuildSubCommand with ELinuxExtension {
/// See: [BuildApkCommand.runCommand] in `build_apk.dart`
@override
Future<FlutterCommandResult> runCommand() async {
// Not supported cross-building for x64 on arm64.
final String targetArch = stringArg('target-arch');
final String hostArch = _getCurrentHostPlatformArchName();
if (hostArch != targetArch && hostArch == 'arm64') {
globals.logger
.printError('Not supported cross-building for x64 on arm64.');
return FlutterCommandResult.fail();
}
final BuildInfo buildInfo = await getBuildInfo();
final ELinuxBuildInfo eLinuxBuildInfo = ELinuxBuildInfo(
buildInfo,
targetArch: stringArg('target-arch'),
targetBackendType: stringArg('target-backend-type'),
);
final ELinuxBuildInfo eLinuxBuildInfo = ELinuxBuildInfo(buildInfo,
targetArch: targetArch,
targetBackendType: stringArg('target-backend-type'),
targetSysroot: stringArg('target-sysroot'),
systemIncludeDirectories: stringArg('system-include-directories'));
validateBuild(eLinuxBuildInfo);
displayNullSafetyMode(buildInfo);
+20 -1
View File
@@ -12,6 +12,7 @@ import 'package:file/file.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
@@ -68,7 +69,7 @@ abstract class ELinuxAssetBundle extends Target {
getBuildModeForName(environment.defines[kBuildMode]);
final Directory outputDirectory = environment.outputDir
.childDirectory('flutter_assets')
..createSync(recursive: true);
..createSync(recursive: true);
// Only copy the prebuilt runtimes and kernel blob in debug mode.
if (buildMode == BuildMode.debug) {
@@ -348,11 +349,24 @@ class NativeBundle {
// Run the native build.
final String cmakeBuildType = buildMode.isPrecompiled ? 'Release' : 'Debug';
final String targetArch = buildInfo.targetArch;
final String hostArch = _getCurrentHostPlatformArchName();
final String targetSysroot = buildInfo.targetSysroot;
final String systemIncludeDirectories = buildInfo.systemIncludeDirectories;
final bool needCrossBuild = targetArch != hostArch;
final bool needCrossBuildOptionsForArm64 = targetArch == 'arm64';
RunResult result = await _processUtils.run(
<String>[
'cmake',
'-DCMAKE_BUILD_TYPE=$cmakeBuildType',
'-DFLUTTER_TARGET_BACKEND_TYPE=${buildInfo.targetBackendType}',
if (needCrossBuild) '-DFLUTTER_TARGET_PLATFORM_SYSROOT=$targetSysroot',
if (needCrossBuild && systemIncludeDirectories != null)
'-DFLUTTER_SYSTEM_INCLUDE_DIRECTORIES=$systemIncludeDirectories',
if (needCrossBuildOptionsForArm64)
'-DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu',
if (needCrossBuildOptionsForArm64)
'-DCMAKE_CXX_COMPILER_TARGET=aarch64-linux-gnu',
eLinuxDir.path,
],
workingDirectory: outputDir.path,
@@ -389,6 +403,11 @@ class NativeBundle {
}
}
String _getCurrentHostPlatformArchName() {
final HostPlatform hostPlatform = getCurrentHostPlatform();
return getNameForHostPlatformArch(hostPlatform);
}
/// Converts [targetArch] to an arch name that corresponds to the `BUILD_ARCH`
/// value used by the eLinux native builder.
String getELinuxBuildArch(String targetArch) {
+4
View File
@@ -34,12 +34,16 @@ class ELinuxBuildInfo {
this.buildInfo, {
@required this.targetArch,
@required this.targetBackendType,
@required this.targetSysroot,
@required this.systemIncludeDirectories,
}) : assert(targetArch != null),
assert(targetBackendType != null);
final BuildInfo buildInfo;
final String targetArch;
final String targetBackendType;
final String targetSysroot;
final String systemIncludeDirectories;
}
/// See:
+4
View File
@@ -224,10 +224,14 @@ class ELinuxDevice extends Device {
BuildInfo buildInfo,
}) async {
final FlutterProject project = FlutterProject.current();
// TODO(hidenori): change the fixed values (|targetSysroot| and |systemIncludeDirectories|)
// to the values from user-specified custom-devices feilds.
final ELinuxBuildInfo eLinuxBuildInfo = ELinuxBuildInfo(
buildInfo,
targetArch: _targetArch,
targetBackendType: _backendType,
targetSysroot: '/',
systemIncludeDirectories: null,
);
await ELinuxBuilder.buildBundle(
project: project,
+2 -1
View File
@@ -219,7 +219,8 @@ class ELinuxWorkflow extends Workflow {
@override
bool get appliesToHostPlatform =>
_operatingSystemUtils.hostPlatform != HostPlatform.linux_arm64;
(_operatingSystemUtils.hostPlatform == HostPlatform.linux_x64) ||
(_operatingSystemUtils.hostPlatform == HostPlatform.linux_arm64);
@override
bool get canLaunchDevices => true;
+6
View File
@@ -15,6 +15,12 @@ if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Basically we use this include when we got the following error:
# fatal error: 'bits/c++config.h' file not found
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
include_directories(SYSTEM ${FLUTTER_SYSTEM_INCLUDE_DIRECTORIES})
endif()
endif()
# Configure build options.