Question

I have a project with one main Cocoa application, a bunch of plugins, and a couple of helper apps. The helper apps have their own targets, and as I want the app build-able without the plugins, the main app has it's own target (call it AppTarget), but I usually build it all in an Aggregate Target (call it TargetA). I also have another Aggregate Target with TargetA, another plugin, and an additional Copy Files Build Phase (TargetB). This all works as expected. I'm trying to create a new Aggregate Target, TargetC, which contains TargetA, and which will have (but doesn't yet) have a Run Shell Script Build Phase.

The problem I'm running into is that I'm trying to use GCC_PREPROCESSOR_DEFINITIONS to #define a symbol, TARGETC, for conditional compilation (#ifdef TARGETC ... #endif), but it's not being included in the build parameters when I look in the build log, and the behavior of the app matches the build log -- the GCC_PREPROCESSOR_DEFINITIONS failed (I tried both TARGETC and TARGETC=1. I tried adding an OTHER_CFLAGS User-Defined Setting (setting it to -DTARGETC=1), but that didn't work either.

The documentation says that User-Defined Settings on Aggregate Targets trickle down to their subtargets, but it seems that this only goes down one level - TargetA may be getting it, but the AppTarget sure isn't. Is this a bug, expected behavior, or am I doing something wrong?

Was it helpful?

Solution

I found the answer: this is expected behavior, and furthermore, aggregate targets don't pass their user settings down to subtargets at all; either the documentation is wrong or I misread it. Which kinda seems to defeat the purpose of having GCC_PREPROCESSOR_DEFINITIONS as a default user setting available for aggregate targets, but c'est la vie.

To get the behavior I wanted, instead I'm building a separate plugin that will be added to the new aggregate target. I'm using a singleton to load the plugin, which will hold a reference to the principal class in the plugin (typed as id <MyPluginProtocol>), which can be returned to anyone who asks. If the load attempt fails (because the plugin doesn't exist), it will return nil, so if (nil != [[PluginLoader sharedLoader] plugin]) takes the place of #ifdef TARGETC. It means I don't get to cut down on shipping code size, but at least it works, and it's not a waste as I have other code that was going to go into a plugin (just for this target) anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top