Reland "Relax arguments around local engine, build hello_world with bitcode" (#39434)
This commit is contained in:
parent
f26f8e8348
commit
cb965495d7
@ -317,7 +317,6 @@
|
|||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ENABLE_BITCODE = NO;
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
@ -444,7 +443,6 @@
|
|||||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ENABLE_BITCODE = NO;
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
@ -465,7 +463,6 @@
|
|||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ENABLE_BITCODE = NO;
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
|
@ -114,7 +114,6 @@ BuildApp() {
|
|||||||
flutter_engine_flag="--local-engine-src-path=${FLUTTER_ENGINE}"
|
flutter_engine_flag="--local-engine-src-path=${FLUTTER_ENGINE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local bitcode_flag=""
|
|
||||||
if [[ -n "$LOCAL_ENGINE" ]]; then
|
if [[ -n "$LOCAL_ENGINE" ]]; then
|
||||||
if [[ $(echo "$LOCAL_ENGINE" | tr "[:upper:]" "[:lower:]") != *"$build_mode"* ]]; then
|
if [[ $(echo "$LOCAL_ENGINE" | tr "[:upper:]" "[:lower:]") != *"$build_mode"* ]]; then
|
||||||
EchoError "========================================================================"
|
EchoError "========================================================================"
|
||||||
@ -131,10 +130,12 @@ BuildApp() {
|
|||||||
local_engine_flag="--local-engine=${LOCAL_ENGINE}"
|
local_engine_flag="--local-engine=${LOCAL_ENGINE}"
|
||||||
flutter_framework="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.framework"
|
flutter_framework="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.framework"
|
||||||
flutter_podspec="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.podspec"
|
flutter_podspec="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.podspec"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local bitcode_flag=""
|
||||||
if [[ $ENABLE_BITCODE == "YES" ]]; then
|
if [[ $ENABLE_BITCODE == "YES" ]]; then
|
||||||
bitcode_flag="--bitcode"
|
bitcode_flag="--bitcode"
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -e "${project_path}/.ios" ]]; then
|
if [[ -e "${project_path}/.ios" ]]; then
|
||||||
RunCommand rm -rf -- "${derived_dir}/engine"
|
RunCommand rm -rf -- "${derived_dir}/engine"
|
||||||
@ -237,6 +238,7 @@ BuildApp() {
|
|||||||
|
|
||||||
RunCommand eval "$(echo "static const int Moo = 88;" | xcrun clang -x c \
|
RunCommand eval "$(echo "static const int Moo = 88;" | xcrun clang -x c \
|
||||||
${arch_flags} \
|
${arch_flags} \
|
||||||
|
-fembed-bitcode-marker \
|
||||||
-dynamiclib \
|
-dynamiclib \
|
||||||
-Xlinker -rpath -Xlinker '@executable_path/Frameworks' \
|
-Xlinker -rpath -Xlinker '@executable_path/Frameworks' \
|
||||||
-Xlinker -rpath -Xlinker '@loader_path/Frameworks' \
|
-Xlinker -rpath -Xlinker '@loader_path/Frameworks' \
|
||||||
|
@ -179,13 +179,14 @@ class AOTSnapshotter {
|
|||||||
// The DWARF section confuses Xcode tooling, so this strips it. Ideally,
|
// The DWARF section confuses Xcode tooling, so this strips it. Ideally,
|
||||||
// gen_snapshot would provide an argument to do this automatically.
|
// gen_snapshot would provide an argument to do this automatically.
|
||||||
if (platform == TargetPlatform.ios && bitcode) {
|
if (platform == TargetPlatform.ios && bitcode) {
|
||||||
final IOSink sink = fs.file('$assembly.bitcode').openWrite();
|
final IOSink sink = fs.file('$assembly.stripped.S').openWrite();
|
||||||
for (String line in fs.file(assembly).readAsLinesSync()) {
|
for (String line in fs.file(assembly).readAsLinesSync()) {
|
||||||
if (line.startsWith('.section __DWARF')) {
|
if (line.startsWith('.section __DWARF')) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sink.writeln(line);
|
sink.writeln(line);
|
||||||
}
|
}
|
||||||
|
await sink.flush();
|
||||||
await sink.close();
|
await sink.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +200,8 @@ class AOTSnapshotter {
|
|||||||
if (platform == TargetPlatform.ios || platform == TargetPlatform.darwin_x64) {
|
if (platform == TargetPlatform.ios || platform == TargetPlatform.darwin_x64) {
|
||||||
final RunResult result = await _buildFramework(
|
final RunResult result = await _buildFramework(
|
||||||
appleArch: darwinArch,
|
appleArch: darwinArch,
|
||||||
assemblyPath: bitcode ? '$assembly.bitcode' : assembly,
|
isIOS: platform == TargetPlatform.ios,
|
||||||
|
assemblyPath: bitcode ? '$assembly.stripped.S' : assembly,
|
||||||
outputPath: outputDir.path,
|
outputPath: outputDir.path,
|
||||||
bitcode: bitcode,
|
bitcode: bitcode,
|
||||||
);
|
);
|
||||||
@ -213,26 +215,29 @@ class AOTSnapshotter {
|
|||||||
/// source at [assemblyPath].
|
/// source at [assemblyPath].
|
||||||
Future<RunResult> _buildFramework({
|
Future<RunResult> _buildFramework({
|
||||||
@required DarwinArch appleArch,
|
@required DarwinArch appleArch,
|
||||||
|
@required bool isIOS,
|
||||||
@required String assemblyPath,
|
@required String assemblyPath,
|
||||||
@required String outputPath,
|
@required String outputPath,
|
||||||
@required bool bitcode,
|
@required bool bitcode,
|
||||||
}) async {
|
}) async {
|
||||||
final String targetArch = getNameForDarwinArch(appleArch);
|
final String targetArch = getNameForDarwinArch(appleArch);
|
||||||
printStatus('Building App.framework for $targetArch...');
|
printStatus('Building App.framework for $targetArch...');
|
||||||
|
|
||||||
final List<String> commonBuildOptions = <String>[
|
final List<String> commonBuildOptions = <String>[
|
||||||
'-arch', targetArch,
|
'-arch', targetArch,
|
||||||
if (appleArch == DarwinArch.arm64 || appleArch == DarwinArch.armv7)
|
if (isIOS)
|
||||||
'-miphoneos-version-min=8.0',
|
'-miphoneos-version-min=8.0',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const String embedBitcodeArg = '-fembed-bitcode';
|
||||||
final String assemblyO = fs.path.join(outputPath, 'snapshot_assembly.o');
|
final String assemblyO = fs.path.join(outputPath, 'snapshot_assembly.o');
|
||||||
final RunResult compileResult = await xcode.cc(<String>[
|
final RunResult compileResult = await xcode.cc(<String>[
|
||||||
...commonBuildOptions,
|
'-arch', targetArch,
|
||||||
|
if (bitcode) embedBitcodeArg,
|
||||||
'-c',
|
'-c',
|
||||||
assemblyPath,
|
assemblyPath,
|
||||||
'-o',
|
'-o',
|
||||||
assemblyO,
|
assemblyO,
|
||||||
if (bitcode) '-fembed-bitcode',
|
|
||||||
]);
|
]);
|
||||||
if (compileResult.exitCode != 0) {
|
if (compileResult.exitCode != 0) {
|
||||||
printError('Failed to compile AOT snapshot. Compiler terminated with exit code ${compileResult.exitCode}');
|
printError('Failed to compile AOT snapshot. Compiler terminated with exit code ${compileResult.exitCode}');
|
||||||
@ -248,27 +253,17 @@ class AOTSnapshotter {
|
|||||||
'-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks',
|
'-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks',
|
||||||
'-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks',
|
'-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks',
|
||||||
'-install_name', '@rpath/App.framework/App',
|
'-install_name', '@rpath/App.framework/App',
|
||||||
if (bitcode) '-fembed-bitcode',
|
if (bitcode) embedBitcodeArg,
|
||||||
|
if (bitcode && isIOS) ...<String>[embedBitcodeArg, '-isysroot', await xcode.iPhoneSdkLocation()],
|
||||||
'-o', appLib,
|
'-o', appLib,
|
||||||
assemblyO,
|
assemblyO,
|
||||||
];
|
];
|
||||||
final RunResult linkResult = await xcode.clang(linkArgs);
|
final RunResult linkResult = await xcode.clang(linkArgs);
|
||||||
if (linkResult.exitCode != 0) {
|
if (linkResult.exitCode != 0) {
|
||||||
printError('Failed to link AOT snapshot. Linker terminated with exit code ${compileResult.exitCode}');
|
printError('Failed to link AOT snapshot. Linker terminated with exit code ${compileResult.exitCode}');
|
||||||
|
}
|
||||||
return linkResult;
|
return linkResult;
|
||||||
}
|
}
|
||||||
// See https://github.com/flutter/flutter/issues/22560
|
|
||||||
// These have to be placed in a .noindex folder to prevent Xcode from
|
|
||||||
// using Spotlight to find them and potentially attach the wrong ones.
|
|
||||||
final RunResult dsymResult = await xcode.dsymutil(<String>[
|
|
||||||
appLib,
|
|
||||||
'-o', fs.path.join(outputPath, 'App.framework.dSYM.noindex'),
|
|
||||||
]);
|
|
||||||
if (dsymResult.exitCode != 0) {
|
|
||||||
printError('Failed to extract dSYM out of dynamic lib');
|
|
||||||
}
|
|
||||||
return dsymResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compiles a Dart file to kernel.
|
/// Compiles a Dart file to kernel.
|
||||||
///
|
///
|
||||||
|
@ -83,7 +83,7 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
|
|||||||
if (platform != TargetPlatform.ios) {
|
if (platform != TargetPlatform.ios) {
|
||||||
throwToolExit('Bitcode is only supported on iOS (TargetPlatform is $targetPlatform).');
|
throwToolExit('Bitcode is only supported on iOS (TargetPlatform is $targetPlatform).');
|
||||||
}
|
}
|
||||||
await validateBitcode();
|
await validateBitcode(buildMode, platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status status;
|
Status status;
|
||||||
@ -150,14 +150,6 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
|
|||||||
'-create',
|
'-create',
|
||||||
'-output', fs.path.join(outputPath, 'App.framework', 'App'),
|
'-output', fs.path.join(outputPath, 'App.framework', 'App'),
|
||||||
]);
|
]);
|
||||||
final Iterable<String> dSYMs = iosBuilds.values.map<String>((String outputDir) => fs.path.join(outputDir, 'App.framework.dSYM.noindex'));
|
|
||||||
fs.directory(fs.path.join(outputPath, 'App.framework.dSYM.noindex', 'Contents', 'Resources', 'DWARF'))..createSync(recursive: true);
|
|
||||||
await runCheckedAsync(<String>[
|
|
||||||
'lipo',
|
|
||||||
'-create',
|
|
||||||
'-output', fs.path.join(outputPath, 'App.framework.dSYM.noindex', 'Contents', 'Resources', 'DWARF', 'App'),
|
|
||||||
...dSYMs.map((String path) => fs.path.join(path, 'Contents', 'Resources', 'DWARF', 'App'))
|
|
||||||
]);
|
|
||||||
} else {
|
} else {
|
||||||
status?.cancel();
|
status?.cancel();
|
||||||
exitCodes.forEach((DarwinArch iosArch, Future<int> exitCodeFuture) async {
|
exitCodes.forEach((DarwinArch iosArch, Future<int> exitCodeFuture) async {
|
||||||
@ -202,24 +194,18 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> validateBitcode() async {
|
Future<void> validateBitcode(BuildMode buildMode, TargetPlatform targetPlatform) async {
|
||||||
final Artifacts artifacts = Artifacts.instance;
|
final Artifacts artifacts = Artifacts.instance;
|
||||||
if (artifacts is! LocalEngineArtifacts) {
|
final String flutterFrameworkPath = artifacts.getArtifactPath(
|
||||||
throwToolExit('Bitcode is only supported with a local engine built with --bitcode.');
|
Artifact.flutterFramework,
|
||||||
}
|
mode: buildMode,
|
||||||
final String flutterFrameworkPath = artifacts.getArtifactPath(Artifact.flutterFramework);
|
platform: targetPlatform,
|
||||||
|
);
|
||||||
if (!fs.isDirectorySync(flutterFrameworkPath)) {
|
if (!fs.isDirectorySync(flutterFrameworkPath)) {
|
||||||
throwToolExit('Flutter.framework not found at $flutterFrameworkPath');
|
throwToolExit('Flutter.framework not found at $flutterFrameworkPath');
|
||||||
}
|
}
|
||||||
final Xcode xcode = context.get<Xcode>();
|
final Xcode xcode = context.get<Xcode>();
|
||||||
|
|
||||||
// Check for bitcode in Flutter binary.
|
|
||||||
final RunResult otoolResult = await xcode.otool(<String>[
|
|
||||||
'-l', fs.path.join(flutterFrameworkPath, 'Flutter'),
|
|
||||||
]);
|
|
||||||
if (!otoolResult.stdout.contains('__LLVM')) {
|
|
||||||
throwToolExit('The Flutter.framework at $flutterFrameworkPath does not contain bitcode.');
|
|
||||||
}
|
|
||||||
final RunResult clangResult = await xcode.clang(<String>['--version']);
|
final RunResult clangResult = await xcode.clang(<String>['--version']);
|
||||||
final String clangVersion = clangResult.stdout.split('\n').first;
|
final String clangVersion = clangResult.stdout.split('\n').first;
|
||||||
final String engineClangVersion = PlistParser.instance.getValueFromFile(
|
final String engineClangVersion = PlistParser.instance.getValueFromFile(
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import '../base/common.dart';
|
||||||
import '../base/context.dart';
|
import '../base/context.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
import '../base/io.dart';
|
import '../base/io.dart';
|
||||||
@ -100,16 +101,14 @@ class Xcode {
|
|||||||
return runCheckedAsync(<String>['xcrun', 'clang', ...args]);
|
return runCheckedAsync(<String>['xcrun', 'clang', ...args]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<RunResult> dsymutil(List<String> args) {
|
Future<String> iPhoneSdkLocation() async {
|
||||||
return runCheckedAsync(<String>['xcrun', 'dsymutil', ...args]);
|
final RunResult runResult = await runCheckedAsync(
|
||||||
|
<String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path'],
|
||||||
|
);
|
||||||
|
if (runResult.exitCode != 0) {
|
||||||
|
throwToolExit('Could not find iPhone SDK location: ${runResult.stderr}');
|
||||||
}
|
}
|
||||||
|
return runResult.stdout.trim();
|
||||||
Future<RunResult> strip(List<String> args) {
|
|
||||||
return runCheckedAsync(<String>['xcrun', 'strip', ...args]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<RunResult> otool(List<String> args) {
|
|
||||||
return runCheckedAsync(<String>['xcrun', 'otool', ...args]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSimulatorPath() {
|
String getSimulatorPath() {
|
||||||
|
@ -116,13 +116,6 @@ void main() {
|
|||||||
when(mockArtifacts.getArtifactPath(Artifact.snapshotDart,
|
when(mockArtifacts.getArtifactPath(Artifact.snapshotDart,
|
||||||
platform: anyNamed('platform'), mode: mode)).thenReturn(kSnapshotDart);
|
platform: anyNamed('platform'), mode: mode)).thenReturn(kSnapshotDart);
|
||||||
}
|
}
|
||||||
|
|
||||||
when(mockXcode.dsymutil(any)).thenAnswer((_) => Future<RunResult>.value(
|
|
||||||
RunResult(
|
|
||||||
ProcessResult(1, 0, '', ''),
|
|
||||||
<String>['command name', 'arguments...']),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final Map<Type, Generator> contextOverrides = <Type, Generator>{
|
final Map<Type, Generator> contextOverrides = <Type, Generator>{
|
||||||
@ -210,14 +203,9 @@ void main() {
|
|||||||
|
|
||||||
verify(xcode.cc(argThat(contains('-fembed-bitcode')))).called(1);
|
verify(xcode.cc(argThat(contains('-fembed-bitcode')))).called(1);
|
||||||
verify(xcode.clang(argThat(contains('-fembed-bitcode')))).called(1);
|
verify(xcode.clang(argThat(contains('-fembed-bitcode')))).called(1);
|
||||||
verify(xcode.dsymutil(<String>[
|
|
||||||
'build/foo/App.framework/App',
|
|
||||||
'-o',
|
|
||||||
'build/foo/App.framework.dSYM.noindex',
|
|
||||||
])).called(1);
|
|
||||||
|
|
||||||
final File assemblyFile = fs.file(assembly);
|
final File assemblyFile = fs.file(assembly);
|
||||||
final File assemblyBitcodeFile = fs.file('$assembly.bitcode');
|
final File assemblyBitcodeFile = fs.file('$assembly.stripped.S');
|
||||||
expect(assemblyFile.existsSync(), true);
|
expect(assemblyFile.existsSync(), true);
|
||||||
expect(assemblyBitcodeFile.existsSync(), true);
|
expect(assemblyBitcodeFile.existsSync(), true);
|
||||||
expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
|
expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
|
||||||
@ -263,7 +251,6 @@ void main() {
|
|||||||
]);
|
]);
|
||||||
verifyNever(xcode.cc(argThat(contains('-fembed-bitcode'))));
|
verifyNever(xcode.cc(argThat(contains('-fembed-bitcode'))));
|
||||||
verifyNever(xcode.clang(argThat(contains('-fembed-bitcode'))));
|
verifyNever(xcode.clang(argThat(contains('-fembed-bitcode'))));
|
||||||
verify(xcode.dsymutil(any)).called(1);
|
|
||||||
|
|
||||||
final File assemblyFile = fs.file(assembly);
|
final File assemblyFile = fs.file(assembly);
|
||||||
final File assemblyBitcodeFile = fs.file('$assembly.bitcode');
|
final File assemblyBitcodeFile = fs.file('$assembly.bitcode');
|
||||||
|
@ -248,14 +248,12 @@ flutter_tools:lib/''');
|
|||||||
|
|
||||||
when(mockXcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
when(mockXcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
||||||
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
||||||
when(mockXcode.dsymutil(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
|
||||||
|
|
||||||
final BuildResult result = await buildSystem.build(const AotAssemblyProfile(), iosEnvironment);
|
final BuildResult result = await buildSystem.build(const AotAssemblyProfile(), iosEnvironment);
|
||||||
|
|
||||||
expect(result.success, true);
|
expect(result.success, true);
|
||||||
verify(mockXcode.cc(argThat(contains('-fembed-bitcode')))).called(1);
|
verify(mockXcode.cc(argThat(contains('-fembed-bitcode')))).called(1);
|
||||||
verify(mockXcode.clang(argThat(contains('-fembed-bitcode')))).called(1);
|
verify(mockXcode.clang(argThat(contains('-fembed-bitcode')))).called(1);
|
||||||
verify(mockXcode.dsymutil(any)).called(1);
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
ProcessManager: () => mockProcessManager,
|
ProcessManager: () => mockProcessManager,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => mockXcode,
|
||||||
@ -278,14 +276,12 @@ flutter_tools:lib/''');
|
|||||||
|
|
||||||
when(mockXcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
when(mockXcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
||||||
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
||||||
when(mockXcode.dsymutil(any)).thenAnswer((_) => Future<RunResult>.value(fakeRunResult));
|
|
||||||
|
|
||||||
final BuildResult result = await buildSystem.build(const AotAssemblyProfile(), iosEnvironment);
|
final BuildResult result = await buildSystem.build(const AotAssemblyProfile(), iosEnvironment);
|
||||||
|
|
||||||
expect(result.success, true);
|
expect(result.success, true);
|
||||||
verify(mockXcode.cc(argThat(contains('-fembed-bitcode')))).called(2);
|
verify(mockXcode.cc(argThat(contains('-fembed-bitcode')))).called(2);
|
||||||
verify(mockXcode.clang(argThat(contains('-fembed-bitcode')))).called(2);
|
verify(mockXcode.clang(argThat(contains('-fembed-bitcode')))).called(2);
|
||||||
verify(mockXcode.dsymutil(any)).called(2);
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
ProcessManager: () => mockProcessManager,
|
ProcessManager: () => mockProcessManager,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => mockXcode,
|
||||||
|
@ -179,9 +179,6 @@ void main() {
|
|||||||
when(xcode.clang(any)).thenAnswer((Invocation invocation) {
|
when(xcode.clang(any)).thenAnswer((Invocation invocation) {
|
||||||
return Future<RunResult>.value(RunResult(FakeProcessResult()..exitCode = 0, <String>['test']));
|
return Future<RunResult>.value(RunResult(FakeProcessResult()..exitCode = 0, <String>['test']));
|
||||||
});
|
});
|
||||||
when(xcode.dsymutil(any)).thenAnswer((Invocation invocation) {
|
|
||||||
return Future<RunResult>.value(RunResult(FakeProcessResult()..exitCode = 0, <String>['test']));
|
|
||||||
});
|
|
||||||
environment.buildDir.childFile('app.dill').createSync(recursive: true);
|
environment.buildDir.childFile('app.dill').createSync(recursive: true);
|
||||||
fs.file('.packages')
|
fs.file('.packages')
|
||||||
..createSync()
|
..createSync()
|
||||||
|
@ -6,6 +6,7 @@ import 'package:file/memory.dart';
|
|||||||
import 'package:flutter_tools/src/artifacts.dart';
|
import 'package:flutter_tools/src/artifacts.dart';
|
||||||
import 'package:flutter_tools/src/base/logger.dart';
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
import 'package:flutter_tools/src/base/process.dart';
|
import 'package:flutter_tools/src/base/process.dart';
|
||||||
|
import 'package:flutter_tools/src/build_info.dart';
|
||||||
import 'package:flutter_tools/src/commands/build_aot.dart';
|
import 'package:flutter_tools/src/commands/build_aot.dart';
|
||||||
import 'package:flutter_tools/src/base/file_system.dart';
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
||||||
@ -32,16 +33,9 @@ void main() {
|
|||||||
mockPlistUtils = MockPlistUtils();
|
mockPlistUtils = MockPlistUtils();
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('build aot validates building with bitcode requires a local engine', () async {
|
|
||||||
await expectToolExitLater(
|
|
||||||
validateBitcode(),
|
|
||||||
equals('Bitcode is only supported with a local engine built with --bitcode.'),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('build aot validates existence of Flutter.framework in engine', () async {
|
testUsingContext('build aot validates existence of Flutter.framework in engine', () async {
|
||||||
await expectToolExitLater(
|
await expectToolExitLater(
|
||||||
validateBitcode(),
|
validateBitcode(BuildMode.release, TargetPlatform.ios),
|
||||||
equals('Flutter.framework not found at ios_profile/Flutter.framework'),
|
equals('Flutter.framework not found at ios_profile/Flutter.framework'),
|
||||||
);
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
@ -49,48 +43,21 @@ void main() {
|
|||||||
FileSystem: () => memoryFileSystem,
|
FileSystem: () => memoryFileSystem,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('build aot validates Flutter.framework/Flutter contains bitcode', () async {
|
|
||||||
final Directory flutterFramework = memoryFileSystem.directory('ios_profile/Flutter.framework')
|
|
||||||
..createSync(recursive: true);
|
|
||||||
flutterFramework.childFile('Flutter').createSync();
|
|
||||||
flutterFramework.childFile('Info.plist').createSync();
|
|
||||||
|
|
||||||
final RunResult otoolResult = RunResult(
|
|
||||||
FakeProcessResult(stdout: '', stderr: ''),
|
|
||||||
const <String>['foo'],
|
|
||||||
);
|
|
||||||
when(mockXcode.otool(any)).thenAnswer((_) => Future<RunResult>.value(otoolResult));
|
|
||||||
await expectToolExitLater(
|
|
||||||
validateBitcode(),
|
|
||||||
equals('The Flutter.framework at ios_profile/Flutter.framework does not contain bitcode.'),
|
|
||||||
);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Artifacts: () => LocalEngineArtifacts('/engine', 'ios_profile', 'host_profile'),
|
|
||||||
FileSystem: () => memoryFileSystem,
|
|
||||||
ProcessManager: () => mockProcessManager,
|
|
||||||
Xcode: () => mockXcode,
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('build aot validates Flutter.framework/Flutter was built with same toolchain', () async {
|
testUsingContext('build aot validates Flutter.framework/Flutter was built with same toolchain', () async {
|
||||||
final Directory flutterFramework = memoryFileSystem.directory('ios_profile/Flutter.framework')
|
final Directory flutterFramework = memoryFileSystem.directory('ios_profile/Flutter.framework')
|
||||||
..createSync(recursive: true);
|
..createSync(recursive: true);
|
||||||
flutterFramework.childFile('Flutter').createSync();
|
flutterFramework.childFile('Flutter').createSync();
|
||||||
final File infoPlist = flutterFramework.childFile('Info.plist')..createSync();
|
final File infoPlist = flutterFramework.childFile('Info.plist')..createSync();
|
||||||
|
|
||||||
final RunResult otoolResult = RunResult(
|
|
||||||
FakeProcessResult(stdout: '__LLVM', stderr: ''),
|
|
||||||
const <String>['foo'],
|
|
||||||
);
|
|
||||||
final RunResult clangResult = RunResult(
|
final RunResult clangResult = RunResult(
|
||||||
FakeProcessResult(stdout: 'Apple LLVM version 10.0.0 (clang-4567.1.1.1)\nBlahBlah\n', stderr: ''),
|
FakeProcessResult(stdout: 'Apple LLVM version 10.0.0 (clang-4567.1.1.1)\nBlahBlah\n', stderr: ''),
|
||||||
const <String>['foo'],
|
const <String>['foo'],
|
||||||
);
|
);
|
||||||
when(mockXcode.otool(any)).thenAnswer((_) => Future<RunResult>.value(otoolResult));
|
|
||||||
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(clangResult));
|
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(clangResult));
|
||||||
when(mockPlistUtils.getValueFromFile(infoPlist.path, 'ClangVersion')).thenReturn('Apple LLVM version 10.0.1 (clang-1234.1.12.1)');
|
when(mockPlistUtils.getValueFromFile(infoPlist.path, 'ClangVersion')).thenReturn('Apple LLVM version 10.0.1 (clang-1234.1.12.1)');
|
||||||
|
|
||||||
await expectToolExitLater(
|
await expectToolExitLater(
|
||||||
validateBitcode(),
|
validateBitcode(BuildMode.release, TargetPlatform.ios),
|
||||||
equals('The Flutter.framework at ios_profile/Flutter.framework was built with "Apple LLVM version 10.0.1 '
|
equals('The Flutter.framework at ios_profile/Flutter.framework was built with "Apple LLVM version 10.0.1 '
|
||||||
'(clang-1234.1.12.1)", but the current version of clang is "Apple LLVM version 10.0.0 (clang-4567.1.1.1)". '
|
'(clang-1234.1.12.1)", but the current version of clang is "Apple LLVM version 10.0.0 (clang-4567.1.1.1)". '
|
||||||
'This will result in failures when trying toarchive an IPA. To resolve this issue, update your version '
|
'This will result in failures when trying toarchive an IPA. To resolve this issue, update your version '
|
||||||
@ -111,19 +78,14 @@ void main() {
|
|||||||
flutterFramework.childFile('Flutter').createSync();
|
flutterFramework.childFile('Flutter').createSync();
|
||||||
final File infoPlist = flutterFramework.childFile('Info.plist')..createSync();
|
final File infoPlist = flutterFramework.childFile('Info.plist')..createSync();
|
||||||
|
|
||||||
final RunResult otoolResult = RunResult(
|
|
||||||
FakeProcessResult(stdout: '__LLVM', stderr: ''),
|
|
||||||
const <String>['foo'],
|
|
||||||
);
|
|
||||||
final RunResult clangResult = RunResult(
|
final RunResult clangResult = RunResult(
|
||||||
FakeProcessResult(stdout: 'Apple LLVM version 10.0.1 (clang-1234.1.12.1)\nBlahBlah\n', stderr: ''),
|
FakeProcessResult(stdout: 'Apple LLVM version 10.0.1 (clang-1234.1.12.1)\nBlahBlah\n', stderr: ''),
|
||||||
const <String>['foo'],
|
const <String>['foo'],
|
||||||
);
|
);
|
||||||
when(mockXcode.otool(any)).thenAnswer((_) => Future<RunResult>.value(otoolResult));
|
|
||||||
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(clangResult));
|
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(clangResult));
|
||||||
when(mockPlistUtils.getValueFromFile(infoPlist.path, 'ClangVersion')).thenReturn('Apple LLVM version 10.0.1 (clang-1234.1.12.1)');
|
when(mockPlistUtils.getValueFromFile(infoPlist.path, 'ClangVersion')).thenReturn('Apple LLVM version 10.0.1 (clang-1234.1.12.1)');
|
||||||
|
|
||||||
await validateBitcode();
|
await validateBitcode(BuildMode.release, TargetPlatform.ios);
|
||||||
|
|
||||||
expect(bufferLogger.statusText, '');
|
expect(bufferLogger.statusText, '');
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
@ -141,19 +103,14 @@ void main() {
|
|||||||
flutterFramework.childFile('Flutter').createSync();
|
flutterFramework.childFile('Flutter').createSync();
|
||||||
final File infoPlist = flutterFramework.childFile('Info.plist')..createSync();
|
final File infoPlist = flutterFramework.childFile('Info.plist')..createSync();
|
||||||
|
|
||||||
final RunResult otoolResult = RunResult(
|
|
||||||
FakeProcessResult(stdout: '__LLVM', stderr: ''),
|
|
||||||
const <String>['foo'],
|
|
||||||
);
|
|
||||||
final RunResult clangResult = RunResult(
|
final RunResult clangResult = RunResult(
|
||||||
FakeProcessResult(stdout: 'Apple LLVM version 11.0.1 (clang-1234.1.12.1)\nBlahBlah\n', stderr: ''),
|
FakeProcessResult(stdout: 'Apple LLVM version 11.0.1 (clang-1234.1.12.1)\nBlahBlah\n', stderr: ''),
|
||||||
const <String>['foo'],
|
const <String>['foo'],
|
||||||
);
|
);
|
||||||
when(mockXcode.otool(any)).thenAnswer((_) => Future<RunResult>.value(otoolResult));
|
|
||||||
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(clangResult));
|
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(clangResult));
|
||||||
when(mockPlistUtils.getValueFromFile(infoPlist.path, 'ClangVersion')).thenReturn('Apple LLVM version 10.0.1 (clang-1234.1.12.1)');
|
when(mockPlistUtils.getValueFromFile(infoPlist.path, 'ClangVersion')).thenReturn('Apple LLVM version 10.0.1 (clang-1234.1.12.1)');
|
||||||
|
|
||||||
await validateBitcode();
|
await validateBitcode(BuildMode.release, TargetPlatform.ios);
|
||||||
|
|
||||||
expect(bufferLogger.statusText, '');
|
expect(bufferLogger.statusText, '');
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user