Stop embedding bitcode for iOS in tool (#112831)
diff --git a/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart b/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
index 706ae3f..1607113 100644
--- a/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+++ b/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
@@ -171,7 +171,6 @@
);
await _checkDylib(appFrameworkPath);
- await _checkBitcode(appFrameworkPath, mode);
final String aotSymbols = await _dylibSymbols(appFrameworkPath);
@@ -228,15 +227,14 @@
section("Check all modes' engine dylib");
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
- final String engineBinary = path.join(
+ checkFileExists(path.join(
outputPath,
mode,
'Flutter.xcframework',
'ios-arm64',
'Flutter.framework',
'Flutter',
- );
- await _checkBitcode(engineBinary, mode);
+ ));
checkFileExists(path.join(
outputPath,
@@ -836,15 +834,6 @@
}
}
-Future<void> _checkBitcode(String frameworkPath, String mode) async {
- checkFileExists(frameworkPath);
-
- // Bitcode only needed in Release mode for archiving.
- if (mode == 'Release' && !await containsBitcode(frameworkPath)) {
- throw TaskResult.failure('$frameworkPath does not contain bitcode');
- }
-}
-
Future<String> _dylibSymbols(String pathToDylib) {
return eval('nm', <String>[
'-g',
diff --git a/dev/devicelab/lib/framework/ios.dart b/dev/devicelab/lib/framework/ios.dart
index dca47df..90d1d1e 100644
--- a/dev/devicelab/lib/framework/ios.dart
+++ b/dev/devicelab/lib/framework/ios.dart
@@ -47,43 +47,6 @@
return minVersion;
}
-Future<bool> containsBitcode(String pathToBinary) async {
- // See: https://stackoverflow.com/questions/32755775/how-to-check-a-static-library-is-built-contain-bitcode
- final String loadCommands = await eval('otool', <String>[
- '-l',
- '-arch',
- 'arm64',
- pathToBinary,
- ]);
- if (!loadCommands.contains('__LLVM')) {
- return false;
- }
- // Presence of the section may mean a bitcode marker was embedded (size=1), but there is no content.
- if (!loadCommands.contains('size 0x0000000000000001')) {
- return true;
- }
- // Check the false positives: size=1 wasn't referencing the __LLVM section.
-
- bool emptyBitcodeMarkerFound = false;
- // Section
- // sectname __bundle
- // segname __LLVM
- // addr 0x003c4000
- // size 0x0042b633
- // offset 3932160
- // ...
- final List<String> lines = LineSplitter.split(loadCommands).toList();
- lines.asMap().forEach((int index, String line) {
- if (line.contains('segname __LLVM') && lines.length - index - 1 > 3) {
- emptyBitcodeMarkerFound |= lines
- .skip(index - 1)
- .take(4)
- .any((String line) => line.contains(' size 0x0000000000000001'));
- }
- });
- return !emptyBitcodeMarkerFound;
-}
-
/// Creates and boots a new simulator, passes the new simulator's identifier to
/// `testFunction`.
///
diff --git a/packages/flutter_tools/bin/podhelper.rb b/packages/flutter_tools/bin/podhelper.rb
index 1bd5112..35f7cfd 100644
--- a/packages/flutter_tools/bin/podhelper.rb
+++ b/packages/flutter_tools/bin/podhelper.rb
@@ -65,6 +65,9 @@
# Skip other updates if it's not a Flutter plugin (transitive dependency).
next unless target.dependencies.any? { |dependency| dependency.name == 'Flutter' }
+ # Bitcode is deprecated, Flutter.framework bitcode blob will have been stripped.
+ build_configuration.build_settings['ENABLE_BITCODE'] = 'NO'
+
# Profile can't be derived from the CocoaPods build configuration. Use release framework (for linking only).
configuration_engine_dir = build_configuration.type == :debug ? debug_framework_dir : release_framework_dir
Dir.new(configuration_engine_dir).each_child do |xcframework_file|
diff --git a/packages/flutter_tools/bin/xcode_backend.dart b/packages/flutter_tools/bin/xcode_backend.dart
index 0f9de8c..0d81840 100644
--- a/packages/flutter_tools/bin/xcode_backend.dart
+++ b/packages/flutter_tools/bin/xcode_backend.dart
@@ -333,11 +333,6 @@
);
}
- String bitcodeFlag = '';
- if (environment['ENABLE_BITCODE'] == 'YES' && environment['ACTION'] == 'install') {
- bitcodeFlag = 'true';
- }
-
final List<String> flutterArgs = <String>[];
if (verbose) {
@@ -365,7 +360,6 @@
'-dTreeShakeIcons=${environment['TREE_SHAKE_ICONS'] ?? ''}',
'-dTrackWidgetCreation=${environment['TRACK_WIDGET_CREATION'] ?? ''}',
'-dDartObfuscation=${environment['DART_OBFUSCATION'] ?? ''}',
- '-dEnableBitcode=$bitcodeFlag',
'-dAction=${environment['ACTION'] ?? ''}',
'--ExtraGenSnapshotOptions=${environment['EXTRA_GEN_SNAPSHOT_OPTIONS'] ?? ''}',
'--DartDefines=${environment['DART_DEFINES'] ?? ''}',
diff --git a/packages/flutter_tools/lib/src/base/build.dart b/packages/flutter_tools/lib/src/base/build.dart
index 037c8f1..105e435 100644
--- a/packages/flutter_tools/lib/src/base/build.dart
+++ b/packages/flutter_tools/lib/src/base/build.dart
@@ -116,16 +116,11 @@
DarwinArch? darwinArch,
String? sdkRoot,
List<String> extraGenSnapshotOptions = const <String>[],
- required bool bitcode,
String? splitDebugInfo,
required bool dartObfuscation,
bool quiet = false,
}) async {
assert(platform != TargetPlatform.ios || darwinArch != null);
- if (bitcode && platform != TargetPlatform.ios) {
- _logger.printError('Bitcode is only supported for iOS.');
- return 1;
- }
if (!_isValidAotPlatform(platform, buildMode)) {
_logger.printError('${getNameForTargetPlatform(platform)} does not support AOT compilation.');
@@ -244,7 +239,6 @@
sdkRoot: sdkRoot,
assemblyPath: assembly,
outputPath: outputDir.path,
- bitcode: bitcode,
quiet: quiet,
stripAfterBuild: stripAfterBuild,
extractAppleDebugSymbols: extractAppleDebugSymbols
@@ -262,7 +256,6 @@
String? sdkRoot,
required String assemblyPath,
required String outputPath,
- required bool bitcode,
required bool quiet,
required bool stripAfterBuild,
required bool extractAppleDebugSymbols
@@ -286,12 +279,10 @@
],
];
- const String embedBitcodeArg = '-fembed-bitcode';
final String assemblyO = _fileSystem.path.join(outputPath, 'snapshot_assembly.o');
final RunResult compileResult = await _xcode.cc(<String>[
...commonBuildOptions,
- if (bitcode) embedBitcodeArg,
'-c',
assemblyPath,
'-o',
@@ -311,7 +302,6 @@
'-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks',
'-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks',
'-install_name', '@rpath/App.framework/App',
- if (bitcode) embedBitcodeArg,
'-o', appLib,
assemblyO,
];
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index 7fcfe44..8af32e1 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -942,9 +942,6 @@
/// The define to control what target file is used.
const String kTargetFile = 'TargetFile';
-/// The define to control whether the AOT snapshot is built with bitcode.
-const String kBitcodeFlag = 'EnableBitcode';
-
/// Whether to enable or disable track widget creation.
const String kTrackWidgetCreation = 'TrackWidgetCreation';
diff --git a/packages/flutter_tools/lib/src/build_system/targets/android.dart b/packages/flutter_tools/lib/src/build_system/targets/android.dart
index aa60e47..6ff4cc0 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/android.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/android.dart
@@ -250,7 +250,6 @@
buildMode: buildMode,
mainPath: environment.buildDir.childFile('app.dill').path,
outputPath: output.path,
- bitcode: false,
extraGenSnapshotOptions: extraGenSnapshotOptions,
splitDebugInfo: splitDebugInfo,
dartObfuscation: dartObfuscation,
diff --git a/packages/flutter_tools/lib/src/build_system/targets/common.dart b/packages/flutter_tools/lib/src/build_system/targets/common.dart
index 753fe68..91a39e6 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/common.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/common.dart
@@ -296,7 +296,6 @@
buildMode: buildMode,
mainPath: environment.buildDir.childFile('app.dill').path,
outputPath: outputPath,
- bitcode: false,
extraGenSnapshotOptions: extraGenSnapshotOptions,
splitDebugInfo: splitDebugInfo,
dartObfuscation: dartObfuscation,
diff --git a/packages/flutter_tools/lib/src/build_system/targets/ios.dart b/packages/flutter_tools/lib/src/build_system/targets/ios.dart
index 2bcb766..644d48a 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/ios.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/ios.dart
@@ -56,7 +56,6 @@
}
final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
- final bool bitcode = environment.defines[kBitcodeFlag] == 'true';
final BuildMode buildMode = getBuildModeForName(environmentBuildMode);
final TargetPlatform targetPlatform = getTargetPlatformForName(environmentTargetPlatform);
final String? splitDebugInfo = environment.defines[kSplitDebugInfo];
@@ -101,7 +100,6 @@
outputPath: environment.fileSystem.path.join(buildOutputPath, getNameForDarwinArch(darwinArch)),
darwinArch: darwinArch,
sdkRoot: sdkRoot,
- bitcode: bitcode,
quiet: true,
splitDebugInfo: splitDebugInfo,
dartObfuscation: dartObfuscation,
@@ -287,9 +285,6 @@
if (archs == null) {
throw MissingDefineException(kIosArchs, name);
}
- if (environment.defines[kBitcodeFlag] == null) {
- throw MissingDefineException(kBitcodeFlag, name);
- }
_copyFramework(environment, sdkRoot);
final File frameworkBinary = environment.outputDir.childDirectory('Flutter.framework').childFile('Flutter');
@@ -298,7 +293,9 @@
throw Exception('Binary $frameworkBinaryPath does not exist, cannot thin');
}
_thinFramework(environment, frameworkBinaryPath, archs);
- _bitcodeStripFramework(environment, frameworkBinaryPath);
+ if (buildMode == BuildMode.release) {
+ _bitcodeStripFramework(environment, frameworkBinaryPath);
+ }
_signFramework(environment, frameworkBinaryPath, buildMode);
}
@@ -373,16 +370,14 @@
}
}
- /// Destructively strip bitcode from the framework, if needed.
+ /// Destructively strip bitcode from the framework. This can be removed
+ /// when the framework is no longer built with bitcode.
void _bitcodeStripFramework(Environment environment, String frameworkBinaryPath) {
- if (environment.defines[kBitcodeFlag] == 'true') {
- return;
- }
final ProcessResult stripResult = environment.processManager.runSync(<String>[
'xcrun',
'bitcode_strip',
frameworkBinaryPath,
- '-m', // leave the bitcode marker.
+ '-r', // Delete the bitcode segment.
'-o',
frameworkBinaryPath,
]);
@@ -669,7 +664,6 @@
for (String arch in iosArchNames ?? <String>{}) ...<String>['-arch', arch],
stubSource.path,
'-dynamiclib',
- '-fembed-bitcode-marker',
// Keep version in sync with AOTSnapshotter flag
if (environmentType == EnvironmentType.physical)
'-miphoneos-version-min=11.0'
diff --git a/packages/flutter_tools/lib/src/build_system/targets/macos.dart b/packages/flutter_tools/lib/src/build_system/targets/macos.dart
index e88f883..a107f2f 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/macos.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/macos.dart
@@ -285,7 +285,6 @@
}
pending.add(snapshotter.build(
- bitcode: false,
buildMode: buildMode,
mainPath: environment.buildDir.childFile('app.dill').path,
outputPath: environment.fileSystem.path.join(buildOutputPath, getNameForDarwinArch(darwinArch)),
diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart
index 9679907..250188d 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios.dart
@@ -238,25 +238,12 @@
<plist version="1.0">
<dict>
<key>method</key>
-''');
-
- plistContents.write('''
<string>${stringArgDeprecated('export-method')}</string>
- ''');
- if (xcodeBuildResult?.xcodeBuildExecution?.buildSettings['ENABLE_BITCODE'] != 'YES') {
- // Bitcode is off by default in Flutter iOS apps.
- plistContents.write('''
- <key>uploadBitcode</key>
+ <key>uploadBitcode</key>
<false/>
</dict>
</plist>
''');
- } else {
- plistContents.write('''
-</dict>
-</plist>
-''');
- }
final File tempPlist = globals.fs.systemTempDirectory
.createTempSync('flutter_build_ios.').childFile('ExportOptions.plist');
diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
index 75b11e8..60e81bb 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
@@ -152,7 +152,7 @@
...framework.parent
.listSync()
.where((FileSystemEntity entity) =>
- entity.basename.endsWith('bcsymbolmap') || entity.basename.endsWith('dSYM'))
+ entity.basename.endsWith('dSYM'))
.map((FileSystemEntity entity) => <String>['-debug-symbols', entity.path])
.expand<String>((List<String> parameter) => parameter),
],
@@ -421,7 +421,6 @@
defines: <String, String>{
kTargetFile: targetFile,
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios),
- kBitcodeFlag: 'true',
kIosArchs: defaultIOSArchsForEnvironment(sdkType, globals.artifacts!)
.map(getNameForDarwinArch)
.join(' '),
@@ -480,9 +479,6 @@
' ├─Building plugins...'
);
try {
- final String bitcodeGenerationMode = mode == BuildMode.release ?
- 'bitcode' : 'marker'; // In release, force bitcode embedding without archiving.
-
List<String> pluginsBuildCommand = <String>[
...globals.xcode!.xcrunCommand(),
'xcodebuild',
@@ -492,7 +488,6 @@
'-configuration',
xcodeBuildConfiguration,
'SYMROOT=${iPhoneBuildOutput.path}',
- 'BITCODE_GENERATION_MODE=$bitcodeGenerationMode',
'ONLY_ACTIVE_ARCH=NO', // No device targeted, so build all valid architectures.
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES',
if (boolArg('static') ?? false)
@@ -519,7 +514,6 @@
'-configuration',
simulatorConfiguration,
'SYMROOT=${simulatorBuildOutput.path}',
- 'ENABLE_BITCODE=YES', // Support host apps with bitcode enabled.
'ONLY_ACTIVE_ARCH=NO', // No device targeted, so build all valid architectures.
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES',
if (boolArg('static') ?? false)
diff --git a/packages/flutter_tools/lib/src/ios/bitcode.dart b/packages/flutter_tools/lib/src/ios/bitcode.dart
deleted file mode 100644
index 1914ee2..0000000
--- a/packages/flutter_tools/lib/src/ios/bitcode.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import '../artifacts.dart';
-import '../base/common.dart';
-import '../base/context.dart';
-import '../base/process.dart';
-import '../base/version.dart';
-import '../build_info.dart';
-import '../globals.dart' as globals;
-import '../macos/xcode.dart';
-
-const bool kBitcodeEnabledDefault = false;
-
-Future<void> validateBitcode(BuildMode buildMode, TargetPlatform targetPlatform, EnvironmentType environmentType) async {
- final Artifacts? localArtifacts = globals.artifacts;
- final String? flutterFrameworkPath = localArtifacts?.getArtifactPath(
- Artifact.flutterFramework,
- mode: buildMode,
- platform: targetPlatform,
- environmentType: environmentType,
- );
- final Xcode? xcode = context.get<Xcode>();
-
- final RunResult? clangResult = await xcode?.clang(<String>['--version']);
- final String? clangVersion = clangResult?.stdout.split('\n').first;
- final String? engineClangVersion = flutterFrameworkPath == null
- ? null
- : globals.plistParser.getStringValueFromFile(
- globals.fs.path.join(flutterFrameworkPath, 'Info.plist'),
- 'ClangVersion',
- );
- final Version engineClangSemVer = _parseVersionFromClang(engineClangVersion);
- final Version clangSemVer = _parseVersionFromClang(clangVersion);
- if (engineClangSemVer > clangSemVer) {
- throwToolExit(
- 'The Flutter.framework at $flutterFrameworkPath was built '
- 'with "${engineClangVersion ?? 'unknown'}", but the current version '
- 'of clang is "$clangVersion". This will result in failures when trying to '
- 'archive an IPA. To resolve this issue, update your version of Xcode to '
- 'at least $engineClangSemVer.',
- );
- }
-}
-
-Version _parseVersionFromClang(String? clangVersion) {
- final RegExp pattern = RegExp(r'Apple (LLVM|clang) version (\d+\.\d+\.\d+) ');
- Never invalid() {
- throwToolExit('Unable to parse Clang version from "$clangVersion". '
- 'Expected a string like "Apple (LLVM|clang) #.#.# (clang-####.#.##.#)".');
- }
-
- if (clangVersion == null || clangVersion.isEmpty) {
- invalid();
- }
- final RegExpMatch? match = pattern.firstMatch(clangVersion);
- if (match == null || match.groupCount != 2) {
- invalid();
- }
- final Version? version = Version.parse(match.group(2));
- if (version == null) {
- invalid();
- }
- return version;
-}
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_darwin_framework_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_darwin_framework_test.dart
index b830640..9710fb9 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_darwin_framework_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_darwin_framework_test.dart
@@ -539,12 +539,10 @@
testWithoutContext('created with symbols', () async {
final Directory parentA = fileSystem.directory('FrameworkA')..createSync();
- final File bcsymbolmapA = parentA.childFile('ABC123.bcsymbolmap')..createSync();
final File dSYMA = parentA.childFile('FrameworkA.framework.dSYM')..createSync();
final Directory frameworkA = parentA.childDirectory('FrameworkA.framework')..createSync();
final Directory parentB = fileSystem.directory('FrameworkB')..createSync();
- final File bcsymbolmapB = parentB.childFile('ZYX987.bcsymbolmap')..createSync();
final File dSYMB = parentB.childFile('FrameworkB.framework.dSYM')..createSync();
final Directory frameworkB = parentB.childDirectory('FrameworkB.framework')..createSync();
final Directory output = fileSystem.directory('output');
@@ -557,14 +555,10 @@
'-framework',
frameworkA.path,
'-debug-symbols',
- bcsymbolmapA.path,
- '-debug-symbols',
dSYMA.path,
'-framework',
frameworkB.path,
'-debug-symbols',
- bcsymbolmapB.path,
- '-debug-symbols',
dSYMB.path,
'-output',
output.childDirectory('Combine.xcframework').path,
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
index 4599e7f..e82a2b1 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
@@ -444,42 +444,6 @@
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
- testUsingContext('ipa build invokes xcodebuild and archives with bitcode on', () async {
- final File cachedExportOptionsPlist = fileSystem.file('/CachedExportOptions.plist');
- final BuildCommand command = BuildCommand();
- fakeProcessManager.addCommands(<FakeCommand>[
- xattrCommand,
- setUpFakeXcodeBuildHandler(),
- exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
- ]);
- createMinimalMockProjectFiles();
-
- await createTestCommandRunner(command).run(
- const <String>['build', 'ipa', '--no-pub',]
- );
-
- const String expectedIpaPlistContents = '''
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
- <dict>
- <key>method</key>
- <string>app-store</string>
- </dict>
-</plist>
-''';
-
- final String actualIpaPlistContents = fileSystem.file(cachedExportOptionsPlist).readAsStringSync();
- expect(actualIpaPlistContents, expectedIpaPlistContents);
- }, overrides: <Type, Generator>{
- FileSystem: () => fileSystem,
- ProcessManager: () => fakeProcessManager,
- Platform: () => macosPlatform,
- XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(
- overrides: <String, String>{'ENABLE_BITCODE': 'YES'},
- ),
- });
-
testUsingContext('ipa build invokes xcode build with verbosity', () async {
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
diff --git a/packages/flutter_tools/test/general.shard/base/build_test.dart b/packages/flutter_tools/test/general.shard/base/build_test.dart
index 2221dee..80ce4ff 100644
--- a/packages/flutter_tools/test/general.shard/base/build_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/build_test.dart
@@ -165,7 +165,6 @@
buildMode: BuildMode.debug,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: false,
), isNot(equals(0)));
});
@@ -178,7 +177,6 @@
buildMode: BuildMode.debug,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: false,
), isNot(0));
});
@@ -191,99 +189,10 @@
buildMode: BuildMode.debug,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: false,
), isNot(0));
});
- testWithoutContext('builds iOS with bitcode', () async {
- final String outputPath = fileSystem.path.join('build', 'foo');
- final String assembly = fileSystem.path.join(outputPath, 'snapshot_assembly.S');
- final String genSnapshotPath = artifacts.getArtifactPath(
- Artifact.genSnapshot,
- platform: TargetPlatform.ios,
- mode: BuildMode.profile,
- );
- processManager.addCommands(<FakeCommand>[
- FakeCommand(command: <String>[
- '${genSnapshotPath}_arm64',
- '--deterministic',
- '--snapshot_kind=app-aot-assembly',
- '--assembly=$assembly',
- 'main.dill',
- ]),
- kWhichSysctlCommand,
- kARMCheckCommand,
- const FakeCommand(command: <String>[
- 'xcrun',
- 'cc',
- '-arch',
- 'arm64',
- '-miphoneos-version-min=11.0',
- '-isysroot',
- 'path/to/sdk',
- '-fembed-bitcode',
- '-c',
- 'build/foo/snapshot_assembly.S',
- '-o',
- 'build/foo/snapshot_assembly.o',
- ]),
- const FakeCommand(command: <String>[
- 'xcrun',
- 'clang',
- '-arch',
- 'arm64',
- '-miphoneos-version-min=11.0',
- '-isysroot',
- 'path/to/sdk',
- '-dynamiclib',
- '-Xlinker',
- '-rpath',
- '-Xlinker',
- '@executable_path/Frameworks',
- '-Xlinker',
- '-rpath',
- '-Xlinker',
- '@loader_path/Frameworks',
- '-install_name',
- '@rpath/App.framework/App',
- '-fembed-bitcode',
- '-o',
- 'build/foo/App.framework/App',
- 'build/foo/snapshot_assembly.o',
- ]),
- const FakeCommand(command: <String>[
- 'xcrun',
- 'dsymutil',
- '-o',
- 'build/foo/App.framework.dSYM',
- 'build/foo/App.framework/App',
- ]),
- const FakeCommand(command: <String>[
- 'xcrun',
- 'strip',
- '-x',
- 'build/foo/App.framework/App',
- '-o',
- 'build/foo/App.framework/App',
- ]),
- ]);
-
- final int genSnapshotExitCode = await snapshotter.build(
- platform: TargetPlatform.ios,
- buildMode: BuildMode.profile,
- mainPath: 'main.dill',
- outputPath: outputPath,
- darwinArch: DarwinArch.arm64,
- sdkRoot: 'path/to/sdk',
- bitcode: true,
- dartObfuscation: false,
- );
-
- expect(genSnapshotExitCode, 0);
- expect(processManager, hasNoRemainingExpectations);
- });
-
testWithoutContext('builds iOS snapshot with dwarfStackTraces', () async {
final String outputPath = fileSystem.path.join('build', 'foo');
final String assembly = fileSystem.path.join(outputPath, 'snapshot_assembly.S');
@@ -349,7 +258,6 @@
outputPath: outputPath,
darwinArch: DarwinArch.arm64,
sdkRoot: 'path/to/sdk',
- bitcode: false,
splitDebugInfo: 'foo',
dartObfuscation: false,
);
@@ -421,7 +329,6 @@
outputPath: outputPath,
darwinArch: DarwinArch.arm64,
sdkRoot: 'path/to/sdk',
- bitcode: false,
dartObfuscation: true,
);
@@ -490,7 +397,6 @@
outputPath: outputPath,
darwinArch: DarwinArch.arm64,
sdkRoot: 'path/to/sdk',
- bitcode: false,
dartObfuscation: false,
);
@@ -518,7 +424,6 @@
buildMode: BuildMode.release,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: false,
);
@@ -549,7 +454,6 @@
buildMode: BuildMode.release,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
splitDebugInfo: 'foo',
dartObfuscation: false,
);
@@ -579,7 +483,6 @@
buildMode: BuildMode.release,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: true,
);
@@ -607,7 +510,6 @@
buildMode: BuildMode.release,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
splitDebugInfo: '',
dartObfuscation: false,
);
@@ -634,7 +536,6 @@
buildMode: BuildMode.release,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: false,
);
@@ -659,7 +560,6 @@
buildMode: BuildMode.release,
mainPath: 'main.dill',
outputPath: outputPath,
- bitcode: false,
dartObfuscation: false,
extraGenSnapshotOptions: const <String>['--no-strip'],
);
diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart
index 1ddb400..a6c0e74 100644
--- a/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart
@@ -465,98 +465,10 @@
ProcessManager: () => processManager,
});
- testUsingContext('AotAssemblyProfile with bitcode sends correct argument to snapshotter', () async {
- iosEnvironment.defines[kIosArchs] = 'arm64';
- iosEnvironment.defines[kBitcodeFlag] = 'true';
- iosEnvironment.defines[kSdkRoot] = 'path/to/iPhoneOS.sdk';
- final String build = iosEnvironment.buildDir.path;
- processManager.addCommands(<FakeCommand>[
- FakeCommand(command: <String>[
- // This path is not known by the cache due to the iOS gen_snapshot split.
- 'Artifact.genSnapshot.TargetPlatform.ios.profile_arm64',
- '--deterministic',
- kAssemblyAot,
- '--assembly=$build/arm64/snapshot_assembly.S',
- '$build/app.dill',
- ]),
- FakeCommand(command: <String>[
- 'xcrun',
- 'cc',
- '-arch',
- 'arm64',
- '-miphoneos-version-min=11.0',
- '-isysroot',
- 'path/to/iPhoneOS.sdk',
- // Contains bitcode flag.
- '-fembed-bitcode',
- '-c',
- '$build/arm64/snapshot_assembly.S',
- '-o',
- '$build/arm64/snapshot_assembly.o',
- ]),
- FakeCommand(command: <String>[
- 'xcrun',
- 'clang',
- '-arch',
- 'arm64',
- '-miphoneos-version-min=11.0',
- '-isysroot',
- 'path/to/iPhoneOS.sdk',
- '-dynamiclib',
- '-Xlinker',
- '-rpath',
- '-Xlinker',
- '@executable_path/Frameworks',
- '-Xlinker',
- '-rpath',
- '-Xlinker',
- '@loader_path/Frameworks',
- '-install_name',
- '@rpath/App.framework/App',
- // Contains bitcode flag.
- '-fembed-bitcode',
- '-o',
- '$build/arm64/App.framework/App',
- '$build/arm64/snapshot_assembly.o',
- ]),
- FakeCommand(command: <String>[
- 'xcrun',
- 'dsymutil',
- '-o',
- '$build/arm64/App.framework.dSYM',
- '$build/arm64/App.framework/App',
- ]),
- FakeCommand(command: <String>[
- 'xcrun',
- 'strip',
- '-x',
- '$build/arm64/App.framework/App',
- '-o',
- '$build/arm64/App.framework/App',
- ]),
- FakeCommand(command: <String>[
- 'lipo',
- '$build/arm64/App.framework/App',
- '-create',
- '-output',
- '$build/App.framework/App',
- ]),
- ]);
-
- await const AotAssemblyProfile().build(iosEnvironment);
-
- expect(processManager, hasNoRemainingExpectations);
- }, overrides: <Type, Generator>{
- Platform: () => macPlatform,
- FileSystem: () => fileSystem,
- ProcessManager: () => processManager,
- });
-
testUsingContext('AotAssemblyRelease configures gen_snapshot with code size directory', () async {
iosEnvironment.defines[kCodeSizeDirectory] = 'code_size_1';
iosEnvironment.defines[kIosArchs] = 'arm64';
iosEnvironment.defines[kSdkRoot] = 'path/to/iPhoneOS.sdk';
- iosEnvironment.defines[kBitcodeFlag] = 'true';
final String build = iosEnvironment.buildDir.path;
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
@@ -577,8 +489,6 @@
'-miphoneos-version-min=11.0',
'-isysroot',
'path/to/iPhoneOS.sdk',
- // Contains bitcode flag.
- '-fembed-bitcode',
'-c',
'$build/arm64/snapshot_assembly.S',
'-o',
@@ -603,8 +513,6 @@
'@loader_path/Frameworks',
'-install_name',
'@rpath/App.framework/App',
- // Contains bitcode flag.
- '-fembed-bitcode',
'-o',
'$build/arm64/App.framework/App',
'$build/arm64/snapshot_assembly.o',
diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart
index cd2d81a..d84b0d8 100644
--- a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart
@@ -22,7 +22,6 @@
const List<String> _kSharedConfig = <String>[
'-dynamiclib',
- '-fembed-bitcode-marker',
'-miphoneos-version-min=11.0',
'-Xlinker',
'-rpath',
@@ -87,7 +86,6 @@
fileSystem.path.absolute(fileSystem.path.join(
'.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
'-dynamiclib',
- '-fembed-bitcode-marker',
'-miphonesimulator-version-min=11.0',
'-Xlinker',
'-rpath',
@@ -393,7 +391,6 @@
late FakeCommand copyPhysicalFrameworkCommand;
late FakeCommand lipoCommandNonFatResult;
late FakeCommand lipoVerifyArm64Command;
- late FakeCommand bitcodeStripCommand;
late FakeCommand adHocCodesignCommand;
setUp(() {
@@ -423,15 +420,6 @@
'arm64',
]);
- bitcodeStripCommand = FakeCommand(command: <String>[
- 'xcrun',
- 'bitcode_strip',
- binary.path,
- '-m',
- '-o',
- binary.path,
- ]);
-
adHocCodesignCommand = FakeCommand(command: <String>[
'codesign',
'--force',
@@ -453,7 +441,6 @@
defines: <String, String>{
kIosArchs: 'x86_64',
kSdkRoot: 'path/to/iPhoneSimulator.sdk',
- kBitcodeFlag: 'true',
},
);
@@ -495,7 +482,6 @@
defines: <String, String>{
kIosArchs: 'arm64',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
},
);
processManager.addCommand(copyPhysicalFrameworkCommand);
@@ -521,7 +507,6 @@
defines: <String, String>{
kIosArchs: 'arm64 armv7',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
},
);
@@ -564,7 +549,6 @@
defines: <String, String>{
kIosArchs: 'arm64 armv7',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
},
);
@@ -618,7 +602,6 @@
defines: <String, String>{
kIosArchs: 'arm64',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: 'true',
},
);
@@ -648,7 +631,6 @@
defines: <String, String>{
kIosArchs: 'arm64 armv7',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: 'true',
},
);
@@ -696,26 +678,33 @@
defines: <String, String>{
kIosArchs: 'arm64',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
},
);
processManager.addCommands(<FakeCommand>[
- copyPhysicalFrameworkCommand,
+ FakeCommand(command: <String>[
+ 'rsync',
+ '-av',
+ '--delete',
+ '--filter',
+ '- .DS_Store/',
+ 'Artifact.flutterFramework.TargetPlatform.ios.release.EnvironmentType.physical',
+ outputDir.path,
+ ]),
lipoCommandNonFatResult,
lipoVerifyArm64Command,
FakeCommand(command: <String>[
'xcrun',
'bitcode_strip',
binary.path,
- '-m',
+ '-r',
'-o',
binary.path,
], exitCode: 1, stderr: 'bitcode_strip error'),
]);
await expectLater(
- const DebugUnpackIOS().build(environment),
+ const ReleaseUnpackIOS().build(environment),
throwsA(isException.having(
(Exception exception) => exception.toString(),
'description',
@@ -739,7 +728,6 @@
defines: <String, String>{
kIosArchs: 'arm64',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
},
);
@@ -747,7 +735,6 @@
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
- bitcodeStripCommand,
adHocCodesignCommand,
]);
await const DebugUnpackIOS().build(environment);
@@ -768,7 +755,6 @@
defines: <String, String>{
kIosArchs: 'arm64',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
kCodesignIdentity: 'ABC123',
},
);
@@ -777,7 +763,6 @@
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
- bitcodeStripCommand,
FakeCommand(command: <String>[
'codesign',
'--force',
@@ -813,7 +798,6 @@
defines: <String, String>{
kIosArchs: 'arm64',
kSdkRoot: 'path/to/iPhoneOS.sdk',
- kBitcodeFlag: '',
kCodesignIdentity: 'ABC123',
},
);
@@ -822,7 +806,6 @@
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
- bitcodeStripCommand,
FakeCommand(command: <String>[
'codesign',
'--force',
diff --git a/packages/flutter_tools/test/general.shard/xcode_backend_test.dart b/packages/flutter_tools/test/general.shard/xcode_backend_test.dart
index d746239..626db26 100644
--- a/packages/flutter_tools/test/general.shard/xcode_backend_test.dart
+++ b/packages/flutter_tools/test/general.shard/xcode_backend_test.dart
@@ -31,7 +31,6 @@
<String, String>{
'ACTION': 'build',
'BUILT_PRODUCTS_DIR': buildDir.path,
- 'ENABLE_BITCODE': 'YES',
'FLUTTER_ROOT': flutterRoot.path,
'INFOPLIST_PATH': 'Info.plist',
},
@@ -51,7 +50,6 @@
'-dTreeShakeIcons=',
'-dTrackWidgetCreation=',
'-dDartObfuscation=',
- '-dEnableBitcode=',
'-dAction=build',
'--ExtraGenSnapshotOptions=',
'--DartDefines=',
@@ -85,7 +83,6 @@
<String, String>{
'BUILT_PRODUCTS_DIR': buildDir.path,
'CONFIGURATION': buildMode,
- 'ENABLE_BITCODE': 'YES',
'FLUTTER_ROOT': flutterRoot.path,
'INFOPLIST_PATH': 'Info.plist',
},
@@ -105,7 +102,6 @@
'-dTreeShakeIcons=',
'-dTrackWidgetCreation=',
'-dDartObfuscation=',
- '-dEnableBitcode=',
'-dAction=',
'--ExtraGenSnapshotOptions=',
'--DartDefines=',
@@ -154,7 +150,6 @@
'CONFIGURATION': buildMode,
'DART_DEFINES': dartDefines,
'DART_OBFUSCATION': dartObfuscation,
- 'ENABLE_BITCODE': 'YES',
'EXPANDED_CODE_SIGN_IDENTITY': expandedCodeSignIdentity,
'EXTRA_FRONT_END_OPTIONS': extraFrontEndOptions,
'EXTRA_GEN_SNAPSHOT_OPTIONS': extraGenSnapshotOptions,
@@ -181,7 +176,6 @@
'-dTreeShakeIcons=$treeShake',
'-dTrackWidgetCreation=$trackWidgetCreation',
'-dDartObfuscation=$dartObfuscation',
- '-dEnableBitcode=true',
'-dAction=install',
'--ExtraGenSnapshotOptions=$extraGenSnapshotOptions',
'--DartDefines=$dartDefines',
diff --git a/packages/flutter_tools/test/host_cross_arch.shard/ios_content_validation_test.dart b/packages/flutter_tools/test/host_cross_arch.shard/ios_content_validation_test.dart
index 32fbc4b..6b0081f 100644
--- a/packages/flutter_tools/test/host_cross_arch.shard/ios_content_validation_test.dart
+++ b/packages/flutter_tools/test/host_cross_arch.shard/ios_content_validation_test.dart
@@ -7,10 +7,11 @@
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/build_info.dart';
+import 'package:flutter_tools/src/convert.dart';
import '../integration.shard/test_utils.dart';
import '../src/common.dart';
-import '../src/darwin_common.dart';
+import '../src/fake_process_manager.dart';
void main() {
group('iOS app validation', () {
@@ -152,10 +153,8 @@
expect(vmSnapshot.existsSync(), buildMode == BuildMode.debug);
- // Archiving should contain a bitcode blob, but not building.
- // This mimics Xcode behavior and prevents a developer from having to install a
- // 300+MB app.
- expect(containsBitcode(outputFlutterFrameworkBinary.path, processManager), isFalse);
+ // Builds should not contain deprecated bitcode.
+ expect(_containsBitcode(outputFlutterFrameworkBinary.path, processManager), isFalse);
});
testWithoutContext('Info.plist dart observatory Bonjour service', () {
@@ -358,3 +357,46 @@
timeout: const Timeout(Duration(minutes: 7))
);
}
+
+bool _containsBitcode(String pathToBinary, ProcessManager processManager) {
+ // See: https://stackoverflow.com/questions/32755775/how-to-check-a-static-library-is-built-contain-bitcode
+ final ProcessResult result = processManager.runSync(<String>[
+ 'otool',
+ '-l',
+ '-arch',
+ 'arm64',
+ pathToBinary,
+ ]);
+ final String loadCommands = result.stdout as String;
+ if (!loadCommands.contains('__LLVM')) {
+ return false;
+ }
+ // Presence of the section may mean a bitcode marker was embedded (size=1), but there is no content.
+ if (!loadCommands.contains('size 0x0000000000000001')) {
+ return true;
+ }
+ // Check the false positives: size=1 wasn't referencing the __LLVM section.
+
+ bool emptyBitcodeMarkerFound = false;
+ // Section
+ // sectname __bundle
+ // segname __LLVM
+ // addr 0x003c4000
+ // size 0x0042b633
+ // offset 3932160
+ // ...
+ final List<String> lines = LineSplitter.split(loadCommands).toList();
+ lines.asMap().forEach((int index, String line) {
+ if (line.contains('segname __LLVM') && lines.length - index - 1 > 3) {
+ final bool bitcodeMarkerFound = lines
+ .skip(index - 1)
+ .take(4)
+ .any((String line) => line.contains(' size 0x0000000000000001'));
+ if (bitcodeMarkerFound) {
+ emptyBitcodeMarkerFound = true;
+ return;
+ }
+ }
+ });
+ return !emptyBitcodeMarkerFound;
+}
diff --git a/packages/flutter_tools/test/host_cross_arch.shard/macos_content_validation_test.dart b/packages/flutter_tools/test/host_cross_arch.shard/macos_content_validation_test.dart
index db0d5c6..cfa61f7 100644
--- a/packages/flutter_tools/test/host_cross_arch.shard/macos_content_validation_test.dart
+++ b/packages/flutter_tools/test/host_cross_arch.shard/macos_content_validation_test.dart
@@ -8,7 +8,6 @@
import '../integration.shard/test_utils.dart';
import '../src/common.dart';
-import '../src/darwin_common.dart';
void main() {
final String flutterBin = fileSystem.path.join(
@@ -150,18 +149,6 @@
expect(outputFlutterFramework.childLink('Modules'), isNot(exists));
expect(outputFlutterFramework.childDirectory('Modules'), isNot(exists));
- // Archiving should contain a bitcode blob, but not building.
- // This mimics Xcode behavior and prevents a developer from having to install a
- // 300+MB app.
- final File outputFlutterFrameworkBinary = outputFlutterFramework
- .childDirectory('Versions')
- .childDirectory('A')
- .childFile('FlutterMacOS');
- expect(
- containsBitcode(outputFlutterFrameworkBinary.path, processManager),
- isFalse,
- );
-
// Build again without cleaning.
final ProcessResult secondBuild = processManager.runSync(buildCommand, workingDirectory: workingDirectory);
diff --git a/packages/flutter_tools/test/src/darwin_common.dart b/packages/flutter_tools/test/src/darwin_common.dart
deleted file mode 100644
index 790d586..0000000
--- a/packages/flutter_tools/test/src/darwin_common.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-
-import 'package:flutter_tools/src/base/io.dart';
-import 'package:process/process.dart';
-
-bool containsBitcode(String pathToBinary, ProcessManager processManager) {
- // See: https://stackoverflow.com/questions/32755775/how-to-check-a-static-library-is-built-contain-bitcode
- final ProcessResult result = processManager.runSync(<String>[
- 'otool',
- '-l',
- '-arch',
- 'arm64',
- pathToBinary,
- ]);
- final String loadCommands = result.stdout as String;
- if (!loadCommands.contains('__LLVM')) {
- return false;
- }
- // Presence of the section may mean a bitcode marker was embedded (size=1), but there is no content.
- if (!loadCommands.contains('size 0x0000000000000001')) {
- return true;
- }
- // Check the false positives: size=1 wasn't referencing the __LLVM section.
-
- bool emptyBitcodeMarkerFound = false;
- // Section
- // sectname __bundle
- // segname __LLVM
- // addr 0x003c4000
- // size 0x0042b633
- // offset 3932160
- // ...
- final List<String> lines = LineSplitter.split(loadCommands).toList();
- lines.asMap().forEach((int index, String line) {
- if (line.contains('segname __LLVM') && lines.length - index - 1 > 3) {
- final bool bitcodeMarkerFound = lines
- .skip(index - 1)
- .take(4)
- .any((String line) => line.contains(' size 0x0000000000000001'));
- if (bitcodeMarkerFound) {
- emptyBitcodeMarkerFound = true;
- return;
- }
- }
- });
- return !emptyBitcodeMarkerFound;
-}