How to set Xcode project dependencies with different build configurations? [closed]
Asked Answered
A

2

12

I have an Xcode 7.3 workspace with three projects, App, FrameworkA, and FrameworkB. Each project has a single target. This is iOS, so the framework targets are Cocoa Touch Frameworks, which means frameworks containing dynamically linked shared libraries.

App depends on Framework A which depends on Framework B. These dependencies are working, insofar as A properly links to the build product of B, and the App properly links to and embeds both frameworks A and B (because you cannot have one framework embedding another, it seems an application bundle needs to link and embed both direct and transitive dependencies.)

But here is my problem. Frameworks A and B have the usual build configurations, Debug and Release. App has an additional build configuration, LocalRelease, which is triggered by the Run build action, and used for building an optimized build (like Release) but code signed with a developer identity (like Debug).

When I try to build App with this LocalRelease build configuration, this breaks the build since it breaks the dependencies on frameworks A and B. I believe that is because these frameworks do not have LocalRelease build configurations, so Xcode never puts their build products into a LocalRelease-iphoneos folder, as it does with App.

So my narrow question is, how do I configure build settings so that a project with a nonstandard build configuration name (like LocalRelease) can depend on other projects that use only the standard build configuration names? I'm hoping there's a simple way to do this that does not require adding scripts or xcconfig files, but if those are necessary I'd love to understand why.

And my broader question is, is it in general a bad idea to introduce additional build configurations because they do not allow smooth interaction of dependencies between projects in a shared workspace? I was led to defining this third configuration because I wanted an optimized local build, I did not want to define a new scheme, and I wanted the choice of build type to be expressed by the various build actions (run, profile, release) of a single scheme.

But maybe this was the wrong way to do it. As long as it is the case that build configuration names drive build product directory paths, and dependent projects need to find each other's build products in a shared directory, it seems like introducing a non-standard build configuration name to a project will break interoperation with depended-upon other projects.

Agate answered 7/5, 2016 at 16:28 Comment(0)
A
7

I raised a Developer Technical Support ticket with Apple about this, and spoke to the Xcode engineers at WWDC.

Answers to my own questions

how do I configure build settings so that a project with a nonstandard build configuration name (like LocalRelease) can depend on other projects that use only the standard build configuration names?

Answer: cannot be done.

is it in general a bad idea to introduce additional build configurations because they do not allow smooth interaction of dependencies between projects in a shared workspace?

Answer: yes, this is a bad idea.

So creating a new named build configuration is not the smart way to do what I was trying to do. Unfortunately, seems like the "simplest" solution is to embrace xcconfig files and change config files manually for this sort of thing.

Agate answered 13/9, 2016 at 22:58 Comment(4)
Why can't you set the CONFIGURATION_BUILD_DIR setting for your LocalRelease configuration to match the Release configuration? That way the framework projects should be found in the same place as the localrelease configuration I think.Conserve
Add $(BUILD_ROOT)/Release to your FRAMEWORK_SEARCH_PATHS build setting for the non-standard configurations to pick up the embedded frameworks that get put into the Release folderHeinz
This is a sad outcome! Apple introduces features that is unsupported by their own tooling! This can be fixed and work fine by converting your framework into a Pod and on the consuming app's Podfile, add a hash with the configuration mappings (it tells CP which custom configs are :debug or :release types)Vadim
I created a sample repo with the proposed solution. First commit is a working regular project + framework. Once you introduce custom configurations it stops working. The HEAD commit converts it into a pod and is able to build fine with custom configurations on the consuming app. github.com/nobre84/DummyVadim
G
2

In Xcode 11, it appears that if no corresponding configuration is found in the project dependency, the build system falls back to the setting Use {configuration here} for command-line builds under project configurations.

Xcode settings UI

Cleaning, building, and then inspecting my built products directory shows that the dependency is only built for the selected configuration.

Ginnifer answered 3/8, 2020 at 17:34 Comment(2)
And then add $(BUILD_ROOT)/Release to your FRAMEWORK_SEARCH_PATHS build setting for the non-standard configurations of the top project, to pick up the embedded frameworks that get put into the Release folder (or the one selected in the Use {configuration here} as described in the answer)Heinz
The problem is that when you're building for Debug configuration, normally this configuration already exists in the external framework, and so there's nothing in (BUILD_ROOT)/Release and the build phase fails.Arborescent

© 2022 - 2024 — McMap. All rights reserved.