🗺️ How to generate and upload linkmaps to Emerge
Learn what linkmaps are, how to send them to Emerge, and common pitfalls.
Emerge is a service that provides lots of tools to improve your app in many different ways, like reducing the app size, improving launch and runtime performance, identifying dead code in your codebase during runtime, and more.
If you’re fortunate enough to be using Emerge in your pipeline, you’ll notice that some features are only possible if you submit your linkmaps to them. A linkmap file is defined as a map file which details all symbols and their addresses in the output image.
The official documentation from Emerge shows where you should put your linkmap, but here we’ll go over detailed instructions on how to achieve that.
Note: this article assumes you’re already uploading your .xcarchive
to Emerge using their fastlane plugin.
Enable linkmap generation
Linkmap generation is disabled by default on Xcode, so we have to enable it. Xcode has the LD_GENERATE_MAP_FILE
build setting, defined as:
Activating this setting will cause the linker to write a map file to disk, which details all symbols and their addresses in the output image. The path to the map file is defined by the Path to Link Map File (LD_MAP_FILE_PATH) setting. Defaults to NO.
If you set your build settings via Xcode, search for LD_GENERATE_MAP_FILE
(or Write Link Map File
) in Xcode’s Build Settings and set it to YES
. But if you configure your build settings using config files like me, open your base .xcconfig
file and set:
LD_GENERATE_MAP_FILE = YES
Next, there’s the LD_GENERATE_MAP_FILE
build setting:
This setting defines the path to the map file written by the linker when the Write Link Map File (LD_GENERATE_MAP_FILE) setting is activated. By default, a separate file will be written for each architecture and build variant, and these will be generated in the Intermediates directory for the target whose product is being linked.
Defaults to $(TARGET_TEMP_DIR)/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt
I recommend customizing the path where the linkmaps are generated, so you can easily find them later (we’ll need it):
LD_MAP_FILE_PATH = $(SRCROOT)/.build/Linkmaps/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt
You can also set that value via Xcode’s Build Settings panel if you prefer.
If you decide to customize your LD_MAP_FILE_PATH
, you will also need to make sure its directory exists prior to building your app, otherwise the linkmap files won’t be generated. You can do this as part of your build pipeline, e.g. by adding a new Run Script to your Build Phases, or adding a step in your CI scripts, like fastlane.
Note: some projects might generate multiple linkmaps, and others might generate just one, and that’s expected.
Attaching your linkmaps to .xcarchive
Emerge requires you to submit your linkmaps to the .xcarchive
file you upload to them, like this:
├── MyApp.xcarchive
│ ├── Info.plist
│ ├── dSYMs
│ │ └── MyApp.app.dSYM
│ ├── Products
│ │ └── Applications
│ │ └── MyApp.app
│ └── Linkmaps
│ └── MyApp-LinkMap.txt
Let’s see how that would look like, via fastlane:
# In your `fastlane/Fastfile`
SRCROOT = File.expand_path("..") # Adjust this accordingly to your project's structure
LINKMAPS_DIR = File.join(SRCROOT, ".build/Linkmaps")
lane :archive do
…
FileUtils.mkdir_p(LINKMAPS_DIR) # This directory must exist before building your app
build_app(…) # Code that will build your app
end
lane :distribute do
distribute_to_emerge
distribute_to_app_store
end
private_lane :distribute_to_emerge do
attach_linkmap_to_xcarchive
emerge(…) # Code that will upload your .xcarchive to emerge
end
private_lane :attach_linkmap_to_xcarchive do
xcarchive_path = Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::XCODEBUILD_ARCHIVE]
source_dir = LINKMAPS_DIR
destination_dir = "#{xcarchive_path}/Linkmaps"
FileUtils.cp_r(source_dir, destination_dir, remove_destination: true)
UI.success("Copied linkmaps to xcarchive: #{destination_dir}")
end
Conclusion
In this article you learned what linkmaps are, how to generate them, and how to send them to Emerge. These are needed to enable certain features from Emerge.
If you still don’t use Emerge in your projects, you can sign up here.
Subscribe to this publication to be notified when more articles come out :)
Disclaimer: this post wasn’t sponsored by Emerge in any way.