Unverified Commit 393106fb authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Revert "Relax requirements around local engine, build hello_world with bitcode (#39357)" (#39431)

This reverts commit 202c1b42.
parent c1cb6800
...@@ -317,6 +317,7 @@ ...@@ -317,6 +317,7 @@
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",
...@@ -443,6 +444,7 @@ ...@@ -443,6 +444,7 @@
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",
...@@ -463,6 +465,7 @@ ...@@ -463,6 +465,7 @@
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,6 +114,7 @@ BuildApp() { ...@@ -114,6 +114,7 @@ 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 "========================================================================"
...@@ -130,12 +131,9 @@ BuildApp() { ...@@ -130,12 +131,9 @@ 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"
echo "Set Bitcode!" fi
fi fi
if [[ -e "${project_path}/.ios" ]]; then if [[ -e "${project_path}/.ios" ]]; then
......
...@@ -179,14 +179,13 @@ class AOTSnapshotter { ...@@ -179,14 +179,13 @@ 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.stripped.S').openWrite(); final IOSink sink = fs.file('$assembly.bitcode').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();
} }
...@@ -200,8 +199,7 @@ class AOTSnapshotter { ...@@ -200,8 +199,7 @@ 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,
isIOS: platform == TargetPlatform.ios, assemblyPath: bitcode ? '$assembly.bitcode' : assembly,
assemblyPath: bitcode ? '$assembly.stripped.S' : assembly,
outputPath: outputDir.path, outputPath: outputDir.path,
bitcode: bitcode, bitcode: bitcode,
); );
...@@ -215,29 +213,26 @@ class AOTSnapshotter { ...@@ -215,29 +213,26 @@ 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 (isIOS) if (appleArch == DarwinArch.arm64 || appleArch == DarwinArch.armv7)
'-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>[
'-arch', targetArch, ...commonBuildOptions,
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}');
...@@ -253,17 +248,27 @@ class AOTSnapshotter { ...@@ -253,17 +248,27 @@ 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) embedBitcodeArg, if (bitcode) '-fembed-bitcode',
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 ...@@ -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(buildMode, platform); await validateBitcode();
} }
Status status; Status status;
...@@ -150,6 +150,14 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen ...@@ -150,6 +150,14 @@ 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 {
...@@ -194,18 +202,24 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen ...@@ -194,18 +202,24 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
} }
} }
Future<void> validateBitcode(BuildMode buildMode, TargetPlatform targetPlatform) async { Future<void> validateBitcode() async {
final Artifacts artifacts = Artifacts.instance; final Artifacts artifacts = Artifacts.instance;
final String flutterFrameworkPath = artifacts.getArtifactPath( if (artifacts is! LocalEngineArtifacts) {
Artifact.flutterFramework, throwToolExit('Bitcode is only supported with a local engine built with --bitcode.');
mode: buildMode, }
platform: targetPlatform, final String flutterFrameworkPath = artifacts.getArtifactPath(Artifact.flutterFramework);
);
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,7 +4,6 @@ ...@@ -4,7 +4,6 @@
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';
...@@ -101,14 +100,16 @@ class Xcode { ...@@ -101,14 +100,16 @@ class Xcode {
return runCheckedAsync(<String>['xcrun', 'clang', ...args]); return runCheckedAsync(<String>['xcrun', 'clang', ...args]);
} }
Future<String> iPhoneSdkLocation() async { Future<RunResult> dsymutil(List<String> args) {
final RunResult runResult = await runCheckedAsync( return runCheckedAsync(<String>['xcrun', 'dsymutil', ...args]);
<String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path'], }
);
if (runResult.exitCode != 0) { Future<RunResult> strip(List<String> args) {
throwToolExit('Could not find iPhone SDK location: ${runResult.stderr}'); return runCheckedAsync(<String>['xcrun', 'strip', ...args]);
} }
return runResult.stdout.trim();
Future<RunResult> otool(List<String> args) {
return runCheckedAsync(<String>['xcrun', 'otool', ...args]);
} }
String getSimulatorPath() { String getSimulatorPath() {
......
...@@ -116,6 +116,13 @@ void main() { ...@@ -116,6 +116,13 @@ 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>{
...@@ -203,9 +210,14 @@ void main() { ...@@ -203,9 +210,14 @@ 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.stripped.S'); final File assemblyBitcodeFile = fs.file('$assembly.bitcode');
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);
...@@ -251,6 +263,7 @@ void main() { ...@@ -251,6 +263,7 @@ 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,12 +248,14 @@ flutter_tools:lib/'''); ...@@ -248,12 +248,14 @@ 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,
...@@ -276,12 +278,14 @@ flutter_tools:lib/'''); ...@@ -276,12 +278,14 @@ 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,6 +179,9 @@ void main() { ...@@ -179,6 +179,9 @@ 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,7 +6,6 @@ import 'package:file/memory.dart'; ...@@ -6,7 +6,6 @@ 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';
...@@ -33,9 +32,16 @@ void main() { ...@@ -33,9 +32,16 @@ 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(BuildMode.release, TargetPlatform.ios), validateBitcode(),
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>{
...@@ -43,21 +49,48 @@ void main() { ...@@ -43,21 +49,48 @@ 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(BuildMode.release, TargetPlatform.ios), validateBitcode(),
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 '
...@@ -78,14 +111,19 @@ void main() { ...@@ -78,14 +111,19 @@ 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(BuildMode.release, TargetPlatform.ios); await validateBitcode();
expect(bufferLogger.statusText, ''); expect(bufferLogger.statusText, '');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -103,14 +141,19 @@ void main() { ...@@ -103,14 +141,19 @@ 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(BuildMode.release, TargetPlatform.ios); await validateBitcode();
expect(bufferLogger.statusText, ''); expect(bufferLogger.statusText, '');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
......
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