Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does bitcode_strip (xcrun) do?

Having added TwilioVideo as a Pods dependency in my iOS project, I realized that its size significantly increased (+100 Mo).

After some researches, I found this thread and especially this message that advises stripping bitcode using this command via Podfile.

I didn't know much about bitcode, until I found this great article about it: https://lowlevelbits.org/bitcode-demystified/

Now I understand what is bitcode and why Apple requests it as well as how they use it to recompile apps if they want to. However, I still don't understand what is this "strip bitcode" operation, so I'm looking for information about this (it actually worked well since after adding these lines to my Podfile, my app is now "only" 30 Mo bigger).

Thanks for your help.

like image 885
Rob Avatar asked Sep 28 '18 23:09

Rob


People also ask

What is Bitcode used for?

Bitcode is an Apple technology that enables you to recompile your app to reduce its size. The recompilation happens when you upload your app to App Store Connect or export it for Ad Hoc, Development, or Enterprise distribution.

Why is Bitcode deprecated?

Starting with Xcode 14, bitcode is no longer required for watchOS and tvOS applications, and the App Store no longer accepts bitcode submissions from Xcode 14. Xcode no longer builds bitcode by default and generates a warning message if a project explicitly enables bitcode: “Building with bitcode is deprecated.

What are BCSymbolmaps?

A BCSymbolMap is a lot like a dSYM for bitcode. Xcode builds it both as part of creating the app binary and for every dynamic framework. It's required for resymbolicating function/method names to understand crashes. Symbol maps are per architecture, so there are currently two (ARMv7 and 64-bit ARM) in PSPDFKit.


1 Answers

Here is the manpage for bitcode_strip

remove or leave the bitcode segment in a Mach-O file

bitcode_strip input [ -r | -m | -l ] -o output

What is a Mach-O file?

Mach-O is a file format for executables, object code, shared libraries, dynamically-loaded code, and core dumps

Mach-O also happens to be where iOS and OS X executables are stored, as well as bitcode.

Here is the manpage for xcrun

run or locate development tools

xcrun [-sdk SDK] -find <tool_name>

From my understanding after reading the links you have attached, bitcode is an intermediary step in the compilation process. If you submit your source code to apple by itself, apple will end up having different versions of object code in each app, corresponding to the number of different CPU types that OS X and iOS can run on (over 4 different types). Now, apple can compile your source code most of the way into a minimal form called bitcode, which has no baggage related to which CPU it will be run on.

Most of the way: it does the lexer, parser, semantic analysis and code generation parts of the compiler, which is specific to your source code.

The rest of the way: machine-specific things like optimization, assembling, and linking, which is different on an iPhone compared to a macbook, for example

If you submit the bitcode to the app store, it is much easier to finish compiling it into different final forms for different CPU types. It looks like your problem was that the bitcode in your project ended up being quite a large file (this came from Twilio adding support for bitcode). "Stripping" the bitcode basically removed the bitcode from your project (removes the bitcode segment from your Mach-O file), allowing it to fit within your size constraints. The downside is that apple won't have the bitcode, they'll only have the binary (and will not be able to recompile).

Lets break down the code you linked on github:

source 'https://github.com/twilio/cocoapod-specs'

target 'ObjCVideoQuickstart' do
  pod 'TwilioVideo', '1.0.0-beta14'
end

post_install do |installer|
  # Find bitcode_strip
  bitcode_strip_path = `xcrun -sdk iphoneos --find bitcode_strip`.chop!

  # Find path to TwilioVideo dependency
  path = Dir.pwd
  framework_path = "#{path}/Pods/TwilioVideo/TwilioVideo.framework/TwilioVideo"

  # Strip Bitcode sections from the framework
  strip_command = "#{bitcode_strip_path} #{framework_path} -m -o #{framework_path}" 
  puts "About to strip: #{strip_command}"
  system(strip_command)
end

1.

bitcode_strip_path = `xcrun -sdk iphoneos --find bitcode_strip`.chop!

Locates the bitcode_strip tool in your Xcode installation (read the manpage linked above for xcrun)

2.

framework_path = "#{path}/Pods/TwilioVideo/TwilioVideo.framework/TwilioVideo"

Finds the framework you want to remove the bitcode from

3.

strip_command = "#{bitcode_strip_path} #{framework_path} -m -o #{framework_path}" 
puts "About to strip: #{strip_command}"
system(strip_command)

Creates and executes the command to actually remove the bitcode section from the Mach-O executable. -m is specified for removal (see the linked manpage for bitcode_strip)

please note: using the solution provided by this twilio employee (or other solutions like this) may not be future-proof, as bitcode may become mandatory in the app store

For more information, look into "app thinning"

like image 116
Noam Hacker Avatar answered Oct 29 '22 18:10

Noam Hacker