Generating Xcode Build Configuration Files with BuildSettingExtractor (xcodeproj → xcconfig)
January 31, 2015
Using build configuration files—or xcconfig files as they are known—has some definite benefits. However, as seen in the screencast, the initial process of copying the current build settings out of an Xcode project into xcconfig files is tedious and potentially error-prone.
To aid in that initial extraction process, I wrote a utility app called BuildSettingExtractor. It is available on github at https://github.com/dempseyatgithub/BuildSettingExtractor.
The app is a simple droplet utility: drop an xcodeproj file on it, choose a destination folder, BuildSettingExtractor will extract the build settings from the project and generate xcconfig files.
A set of files is generated for each target in the project and for the project itself. Each set of files includes one xcconfig file per build configuration and one xcconfig file of shared settings. For example, a typical Xcode project will generate nine xcconfig files: three sets of files for the app target, test target, and project with three files for Debug, Release and Shared in each set.
I hope you find BuildSettingExtractor useful. Even if you are just curious about project build settings, this is an easy way to inspect a project’s build settings without fear of accidentally changing them.
A little more about xcconfig files
By default, Xcode stores all build configuration settings in the project file itself. However, you can tell Xcode to base a build configuration’s settings on a build configuration file instead.
A build configuration file is a text file of key-value pairs. An xcconfig file can also contain comments and include other xcconfig files.
// // Project-Debug.xcconfig // #include "Project-Shared.xcconfig” // Include other xcconfig files // An xcconfig file is a text file of key-value pairs. // Use comments to record why you are using certain build values. // The /*comment*/ and #comment styles are not valid in an xcconfig file. COPY_PHASE_STRIP = NO GCC_DYNAMIC_NO_PIC = NO GCC_OPTIMIZATION_LEVEL = 0 GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited) GCC_SYMBOLS_PRIVATE_EXTERN = NO MTL_ENABLE_DEBUG_INFO = YES ONLY_ACTIVE_ARCH = YES
There are some benefits to using xcconfig files:
- Build settings are not in project file—this removes one source of project file merge conflicts
- Build settings can be documented using comments
- An xcconfig file of shared settings can be included in each build configuration
There are also potential drawbacks to using xcconfig files. One potential pitfall is that the build settings for a configuration are based on the xcconfig file—but settings set in Xcode override the xcconfig file settings. This can leave you with unexpected build behavior because an errant build setting set in Xcode is overriding the xcconfig file setting.
This issue is compounded by the fact that when new Xcode versions update project settings, the settings are added to the project, not to an xcconfig file. So when using xcconfig files, some vigilance is required to keep an eye out for build settings being added to the project. These stray build settings should be moved from the project to the appropriate xcconfig file.
BuildSettingExtractor generates xcconfig files from a project—it does not set your project up to use them. Here are few resources that walk through that process:
I was inspired to release BuildSettingExtractor by Episode #154 of NSScreencast. The episode is a step by step demo walking through the process.
By the way, if you aren’t familiar with NSScreencast, I recommend taking a look. Ben Scheirman (@subdigital) presents weekly bite-sized screencasts covering a wide range of development topics. Some screencasts are free and some, like Episode #154, require a subscription. __(Ben also plays guitar with James Dempsey and the Breakpoints, but that has yet to be the subject of a screencast.)
In each of these walkthroughs, instead making a bunch of xcconfig files by hand and then copying and pasting from the project into the correct file, you would use BuildSettingExtractor instead. •