Building static frameworks under Carthage

Mark Jarecki
Jul 16 · 4 min read

Make your favourite Carthage frameworks static


After expounding the benefits of static frameworks for inclusion in your next iOS et al. app, I’ve had a few of you ask me:

How do you build third-party static frameworks under a dependency manager, like Carthage?

Carthage supports building static frameworks, as described in its documentation. However, the script detailed in that example is dated, because since Xcode 9 beta 4, Xcode natively supports static libraries with Swift sources. Making the xcconfig LD hack no longer necessary.

I’ve written a BASH script to simplify the process of building static frameworks with Carthage. I’ll detail what it does and how to use it.

The Problem

The frameworks built by Carthage are dynamic by default.

It is necessary to override some xcconfig properties with a temporary file to make static frameworks build successfully.

Mach-O type


The MACH_O_TYPE determines what is being built — executable, dynamic library, static library, bundle, or relocatable object file. As we are building static frameworks the setting must be staticlib.

Debug information format


Make sure that xcodebuild is not attempting to produce dSYM (debug symbol) files, as this will cause a build failure. Static libraries already contain debug symbols. When the static framework is used by an executable, that executable can produce dSYM files containing its own symbols and that of the framework. Setting DEBUG_INFORMATION_FORMAT to dwarf (debugging with attributed record formats) the debugging information adheres to the standard dwarf debug format.

Framework search paths


Carthage builds static frameworks to the/Static sub-directory along its normal build path. i.e. ./Carthage/Build/iOS/Static.

The main problem exists when a Carthage framework is dependent on another Carthage framework and the path to the dependency is explicit because it is merely linked, and it does not have FRAMEWORK_SEARCH_PATHS set to a recursive look up. As is the case, for example, with RxSwiftExt and its dependency on RxSwift.

In this case, looking at the linked frameworks in the Frameworks group, you will notice that the path is, for example in the case of the RxRelay.framework — is explicitly Carthage/Build/iOS/RxRelay.framework. When the compiler looks up this path, it will not find RxRelay.framework and will result in a build failure.

We need to help out the compiler to find the location of the linked static frameworks by overriding the xcconfig FRAMEWORK_SEARCH_PATHS, in this case with ./Carthage/Build/iOS/**. This tells the compiler to recursively scan through sub-directories of ./Carthage/Build/iOS to find the linked framework relative to the group.

Sample Project

Download the sample project to follow this example.

I’ll also assume you have Carthage installed.

If you open the BuildStaticCarthage.xcworkspace now, you should get multiple build errors, as all the dependent frameworks have not been check-out or built yet.

Update Carthage

The project has a number of commonly used Carthage frameworks in its Cartfile. Two of the frameworks — RxGesture and RxSwiftExt — are dependent on RxSwift.

Open the Terminal and navigate to the directory that contains the Cartfile. Now update the checked-out source code without building, by running:

It will take a while to download the sources.

Once completed, we are ready to use the script.

The Script

The script has the following options:

-p |--platform

Required. The target build platform. Only one platform at a time. Valid options are ios, macos, watchos, tvos.

-d | --dependencies

Required. List of frameworks to be built. As they appear in the Cartfile.

-f | --framework-search-paths

Optional. List of additional framework search paths in addition to the default $(inherited) ./Carthage/Build/{PlatformName}/**

To use the script, to build our static frameworks for iOS, in the Terminal run:

After working out your CPU for a good few minutes, you should now find yourself with four successfully built static frameworks, and be ready to build and run the example app.

Project Settings

In the BuildStaticCarthage.xcodeproj, there are a few settings that make the static frameworks available to the app build target:


In the Xcode project navigator, within the Config group, you will see a Base.xcconfig file. This contains two xcconfig properties:

FRAMEWORK_SEARCH_PATHS points to the directory containing the static frameworks relative to the project directory.

OTHER_LINKER_FLAGS tells the compiler to merge the full static framework into the executable. The -ObjC flag is required for frameworks that contain Objective-C extensions.

This could also be set in the target’s Build Settings Other Linker Flags setting.


Realm is dependent on the SDK libraries: libz.tbd and libc++.tbd. These dependencies must be linked to separately to those framework from the Carthage build process. You can find these libraries from your target’s Linked Frameworks and Libraries menu by pressing the + button and selecting them appropriately.


So, there you have it. A simple method to build static frameworks under Carthage.

Now try and add your favourite Carthage-managed frameworks to your Cartfile and see if you can make them static.

The example project that utilises the script can be found here:

This code is provided as-is.


Exploring interactive product development, visualisation and user experience design

Mark Jarecki

Written by

Interactive product developer and information visualisation aficionado



Exploring interactive product development, visualisation and user experience design

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade