Unexpected effect of default build config in xcode

xcode has the ability to set a default build configuration for use in xcodebuild. For example. Vacation or debug

https://developer.apple.com/library/ios/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-MY_APP_HAS_MULTIPLE_BUILD_CONFIGUR __HOW_DOXODC_I_SAET_A_DIGURATION_HOW_DO_I_SAET_A_DIGURATION

But when I try to do this in my project, it looks like it is not being used as it said it should

$ echo $DEVELOPER_DIR
/Applications/Xcode6.0.1.app/Contents/Developer 
$ xcodebuild  -list
Information about project "CocoaPodsExample":
    Targets:
        CocoaPodsExample
        CocoaPodsExampleTests

    Build Configurations:
        Debug
        Release

    If no build configuration is specified and -scheme is not passed then "Release" is used.

    Schemes:
        CocoaPodsExample

      

Given the default Debug configuration:

$ git grep defaultConfigurationName
CocoaPodsExample.xcodeproj/project.pbxproj:                     defaultConfigurationName = Debug;
CocoaPodsExample.xcodeproj/project.pbxproj:                     defaultConfigurationName = Debug;
CocoaPodsExample.xcodeproj/project.pbxproj:                     defaultConfigurationName = Debug;
Pods/Pods.xcodeproj/project.pbxproj:                    defaultConfigurationName = Debug;
Pods/Pods.xcodeproj/project.pbxproj:                    defaultConfigurationName = Debug;
Pods/Pods.xcodeproj/project.pbxproj:                    defaultConfigurationName = Debug;

      

specify DEFAULT configuration using Debug ( WAITING )

$ xcodebuild -scheme CocoaPodsExample -workspace CocoaPodsExample.xcworkspace -configuration DEFAULT build | grep "CONFIGURATION"
=== BUILD TARGET Pods-AFNetworking OF PROJECT Pods WITH THE DEFAULT CONFIGURATION (Debug) ===
=== BUILD TARGET Pods OF PROJECT Pods WITH THE DEFAULT CONFIGURATION (Debug) ===
=== BUILD TARGET CocoaPodsExample OF PROJECT CocoaPodsExample WITH THE DEFAULT CONFIGURATION (Debug) ===
=== BUILD TARGET CocoaPodsExampleTests OF PROJECT CocoaPodsExample WITH THE DEFAULT CONFIGURATION (Debug) ===

      

and without specifying config, uses Debug ( EXPECTED )

$ DEVELOPER_DIR=/Applications/Xcode6.0.1.app/Contents/Developer xcodebuild -scheme CocoaPodsExample -workspace CocoaPodsExample.xcworkspace build | grep "CONFIGURATION"
=== BUILD TARGET Pods-AFNetworking OF PROJECT Pods WITH CONFIGURATION Debug ===
=== BUILD TARGET Pods OF PROJECT Pods WITH CONFIGURATION Debug ===
=== BUILD TARGET CocoaPodsExample OF PROJECT CocoaPodsExample WITH CONFIGURATION Debug ===
=== BUILD TARGET CocoaPodsExampleTests OF PROJECT CocoaPodsExample WITH CONFIGURATION Debug ===

      

This release as default configuration

$ git grep defaultConfigurationName
CocoaPodsExample.xcodeproj/project.pbxproj:                     defaultConfigurationName = Release;
CocoaPodsExample.xcodeproj/project.pbxproj:                     defaultConfigurationName = Release;
CocoaPodsExample.xcodeproj/project.pbxproj:                     defaultConfigurationName = Release;
Pods/Pods.xcodeproj/project.pbxproj:                    defaultConfigurationName = Release;
Pods/Pods.xcodeproj/project.pbxproj:                    defaultConfigurationName = Release;
Pods/Pods.xcodeproj/project.pbxproj:                    defaultConfigurationName = Release;

      

specify DEFAULT configuration uses Release ( WAITING )

$ xcodebuild -scheme CocoaPodsExample -workspace CocoaPodsExample.xcworkspace -configuration DEFAULT build | grep "CONFIGURATION"
=== BUILD TARGET Pods-AFNetworking OF PROJECT Pods WITH THE DEFAULT CONFIGURATION (Release) ===
=== BUILD TARGET Pods OF PROJECT Pods WITH THE DEFAULT CONFIGURATION (Release) ===
=== BUILD TARGET CocoaPodsExample OF PROJECT CocoaPodsExample WITH THE DEFAULT CONFIGURATION (Release) ===
=== BUILD TARGET CocoaPodsExampleTests OF PROJECT CocoaPodsExample WITH THE DEFAULT CONFIGURATION (Release) ===

      

and without indicating that the config is using Debug ( UNEXPECTED )

$ xcodebuild -scheme CocoaPodsExample -workspace CocoaPodsExample.xcworkspace build | grep "CONFIGURATION"
=== BUILD TARGET Pods-AFNetworking OF PROJECT Pods WITH CONFIGURATION Debug ===
=== BUILD TARGET Pods OF PROJECT Pods WITH CONFIGURATION Debug ===
=== BUILD TARGET CocoaPodsExample OF PROJECT CocoaPodsExample WITH CONFIGURATION Debug ===
=== BUILD TARGET CocoaPodsExampleTests OF PROJECT CocoaPodsExample WITH CONFIGURATION Debug ===

      

It's as if:

  • defaultConfigurationName is only used when using -configuration DEFAULT
  • defaultConfigurationName is ignored if no configuration is set and only Debug

I don't even know if this is a bug or expected behavior.

+3


source to share


1 answer


It was something that drove my own continuous integration scenarios, and also led me to be specific in teams xcodebuild

when it came to determining which of my configurations to run. It wasn't until a few months later that I entered behavior to determine what was really going on.

TL; DR version: The behavior you observe is working correctly , given the commands you shoot at xcodebuild

.

... now for the why

As it turns out, the value defaultConfigurationName

is a parameter that was added to pre-Xcode 4 projects as a means to describe which of the potentially many build configurations should be involved on command line lines when no configuration was specified ... exactly the same. as its name suggests, and is entirely in line with the expectation you expressed in your question.

There is some nuance in this story - in particular, why is Xcode 4 important? Xcode 4 was the first version of the developer toolchain to introduce the concept of "Schemas" as a way to define different ways to build an application. Apple's definition of Apple (emphasis mine) :

An Xcode schema defines a collection of build targets, a configuration to use when building , and a set of tests to run.

Looking at the file .xcscheme

associated with the project, we see a bunch of configuration data corresponding to the settings we see in the Schema editor of Xcode's modern interface. In Root / Scheme, there is one section for each of the six elements that are displayed in the left pane of the Schematic Editor, accessible by choosing Edit Scheme from the Schema Selection next to the Stop button:

  • BuildAction

    displays "Build"
  • TestAction

    matches the test
  • LaunchAction

    displays "Run"
  • ProfileAction

    displayed in "Profile"
  • AnalyzeAction

    maps for "Analysis"
  • ArchiveAction

    displayed in "Archive"

Inside everything except the Build element in Xcode, we find the Build Configuration dropdown. The value of this element is reflected in the file .xcscheme

according to the corresponding action setting for buildConfiguration

. Notice the build configuration defined for the Run action (via the Xcode Schematic Editor interface) or LaunchAction in the file .xcscheme

. I would venture to suggest that the schema CocoaPodsExample

has Debug

set as build config for Run / LaunchAction.

In the original question, your teams xcodebuild

indicate that you are using the Workspace to organize your project. The documentation forxcodebuild

:

To create an Xcode workspace, you must pass the -workspace and -schema parameters to define the assembly. The schema options will control which targets are created and how they are built, although you can pass other options to xcodebuild to override some options, i.e. schemas.



... because you are using a Stage you are forced to provide a parameter -scheme

, and therefore are using the value buildConfiguration

found in the Launch item in the Xcode schema editor, equivalent to that found in the LaunchAction: buildConfiguration section in the Scheme file .xcscheme

. Whatever build configuration is defined in this schema takes precedence over not being set -configuration

in the command itself xcodebuild

.

So why does it exist defaultBuildConfiguration

?

There are still legacy projects and even some development teams that haven't adopted workspaces in their Xcode projects. If you created a completely new test project, didn't include it in the workspace and run it xcodebuild build | grep "CONFIGURATION"

from the containing folder .xcodeproj

, you will see what defaultBuildConfiguration

get picked up.

I created an iOS Single View app called "Demo" and did nothing for an empty project. The project creates by default a schema named "Demo" which has the Run Build Configuration set to Debug

, and defaultConfigurationName

the default is Release

(NOTE: Some of these commands have user-defined paths - if you are going to run them yourself, be sure to update the paths accordingly! ) :

$ xmllint --xpath //Scheme/LaunchAction/@buildConfiguration Demo.xcodeproj/xcuserdata/bmusial.xcuserdatad/xcschemes/Demo.xcscheme
        buildConfiguration="Debug"
$ grep defaultConfigurationName Demo.xcodeproj/project.pbxproj 
        defaultConfigurationName = Release;
        defaultConfigurationName = Release;
        defaultConfigurationName = Release;
$ xcodebuild build | grep "CONFIGURATION"
=== BUILD TARGET Demo OF PROJECT Demo WITH THE DEFAULT CONFIGURATION (Release) ===

      

The result BUILD TARGET

has changed slightly: it now reads: DEFAULT CONFIGURATION (Release)

instead of CONFIGURATION Release

. Inclusion DEFAULT

and parentheses around the actual configuration are the only signs that xcodebuild

reverted to a value from defaultConfigurationName

. By the way, these same indicators are present in the output from your Workspace command equivalents.

Since this is a schema-enabled project, we can use -scheme

to build a config with a schema config, or we can explicitly override the config you are using by setting -configuration

:

$ xcodebuild -scheme Demo build | grep "CONFIGURATION"
=== BUILD TARGET Demo OF PROJECT Demo WITH CONFIGURATION Debug ===
=== BUILD TARGET DemoTests OF PROJECT Demo WITH CONFIGURATION Debug ===
$ xcodebuild -configuration Debug build | grep "CONFIGURATION"
=== BUILD TARGET Demo OF PROJECT Demo WITH CONFIGURATION Debug ===

      

The output of these commands reverts to normal style WITH CONFIGURATION

and configuration not wrapped in brackets.

Hopefully this gives you a lens on what's going on with your own projects and you can tweak your command line scripts accordingly. Once I figured it out, I was able to be less specific in my CI scripts, so as the project progressed, there was less need to update the build scripts in parallel with the project configuration changes. Naturally, depending on the nature of your own project and the frequency with which the build configuration may or may not change, you may want to consider being very prescriptive in your xcodebuild commands ... that is, forcing a specific configuration via -configuration

, If you come across any follow up questions, I'm all ears!

+3


source







All Articles