-
Notifications
You must be signed in to change notification settings - Fork 1
Creating an iOS Bitcode enabled app
Bitcode requires that all libraries being built have bitcode enabled, and that they're all built with compatible toolchains. If you're building the engine locally, you must specify the --bitcode
flag to the gn
command, and this will result in building with the local Xcode installation's clang for compatibility reasons. You must also ensure that all plugins are built with bitcode - the best way to do so is to simply try to build with bitcode (instructions below) and see if the build succeeds.
The binaries we ship with the framework now have bitcode, as of version 1.9.6 (some commits earlier than this may have bitcode available as well).
Bitcode takes longer to build, and results in much larger intermediate binaries - since they contain the bitcode representation of your code embedded to be recompiled later. Local testing has shown that binaries are smaller when thinned and rebuilt from bitcode - for example, building the Flutter Gallery with bitcode for an iPhone 8+ results in a 39mb IPA.
During the experimental phase of this rollout, bitcode will not be enabled by default in Flutter application templates. It is very unlikely that we will auto-migrate templates to enable bitcode either, as this could potentially break projects that are consuming other libraries that are not bitcode enabled.
In your Xcode project, ensure that ENABLE_BITCODE
is set to YES
for all targets. Open the xcworkspace in Xcode:
my_flutter_app$ open ios/Runner.xcworkspace
Click on Runner, and then build settings. Ensure that all build settings are visible. Search for bitcode
, and change it to Yes
. Ensure this is done for all targets, including any targets created by the Cocoapods for plugins.
Or with plugins (you can select multiple targets at once by holding shift or cmd while clicking):
You should also remove config.build_settings['ENABLE_BITCODE'] = 'NO'
from the Podfile if you have plugins. For example, you can see how this was done for flutter_gallery.
Now, builds of your project will use bitcode. You can validate this by creating an archive for the product in Xcode and creating distribution artifacts for local development that use bitcode recompilation:
to check on the app size. And of course, you can do this to actually distribute your app (in which case you would not want to pre-thin the app).
The following setps will give you a profile engine with bitcode. GOMA cannot be used because bitcode requires using the Xcode toolchain, which is not GOMA aware.
src$ ./flutter/tools/gn --ios --runtime-mode=profile --no-goma --bitcode
src$ ./flutter/tools/gn --runtime-mode=profile # The host does not have to be built with bitcode, and can use GOMA
src$ autoninja -C out/ios_profile
src$ autoninja -C out/host_profile
If you build your local engine without bitcode, make sure to disable bitcode in your consuming app, as it will otherwise fail to build.
Bitcode can be either marker
or "regular". Marker means that there is no actual bitcode in the binary - we use this for debug and profile builds. This makes the build go faster, and since these builds should not be shipped to the store anyway they do not need to have full bitcode. Release builds get actual bitcode, which embeds blobs of structured data into your binary that can later be recompiled.
Bitcode is meant to be platform independent. Flutter and Dart use assembly code on iOS which is platform specific. These sections of code get annotated with a __LLVM,__asm
section to tell the compiler that they should be left as-is.
- Home of the Wiki
- Roadmap
- API Reference (stable)
- API Reference (master)
- Glossary
- Contributor Guide
- Chat on Discord
- Code of Conduct
- Issue triage reports
- Our Values
- Tree hygiene
- Issue hygiene and Triage
- Style guide for Flutter repo
- Project teams
- Contributor access
- What should I work on?
- Running and writing tests
- Release process
- Rolling Dart
- Manual Engine Roll with Breaking Commits
- Updating Material Design Fonts & Icons
- Postmortems
- Setting up the Framework development environment
- The Framework architecture
- The flutter tool
- API Docs code block generation
- Running examples
- Using the Dart analyzer
- The flutter run variants
- Test coverage for package:flutter
- Writing a golden-file test for package:flutter
- Setting up the Engine development environment
- Compiling the engine
- Debugging the engine
- Using Sanitizers with the Flutter Engine
- Testing the engine
- The Engine architecture
- Flutter's modes
- Engine disk footprint
- Comparing AOT Snapshot Sizes
- Custom Flutter engine embedders
- Custom Flutter Engine Embedding in AOT Mode
- Flutter engine operation in AOT Mode
- Engine-specific Service Protocol extensions
- Crashes
- Supporting legacy platforms
- Metal on iOS FAQ
- Engine Clang Tidy Linter
- Why we have a separate engine repo
- Reduce Flutter engine size with MLGO
- Setting up the Plugins development environment
- Setting up the Packages development environment
- Plugins and Packages repository structure
- Plugin Tests
- Contributing to Plugins and Packages
- Releasing a Plugin or Package
- Unexpected Plugins and Packages failures