“Complicated and Fragile”

I’d like to explain the "complicated and fragile" comment I made in my last post.

What was complicated and fragile about it? Let me count the ways:

-SenTest All-the-Time
In order to make the tests take place when the application is launched, I had to put the -SenTest All argument on the project’s MyDocApp executable. I didn’t find a way to conditionalize that to a target: When I instead added $(MY_BUILD_SETTING) as the argument, and then set MY_BUILD_SETTING to -SenTest All for my Tests aggregrate target, no argument was passed in to the application.

This constraint means that I can’t, for instance, put any tests in MainMenu.nib, because if I did they would always be invoked, even if my Tests framework was not present. Not so cool.

Anybody know a way conditionalize such executable arguments?

Why not just add a second custom executable to the project? It could have a different set of arguments. Use one executable for Tests, and one for No-Tests.

Unfortunately, such a custom executable reference in the target has to be specified by full path, which is a deal-breaker. When I tried to set the path for such a custom executable relative to the shared build directory, I got circular dependency errors, probably because the executable in question was already a product of one of the project’s targets.

Subscript
Both the copying of the Tests framework to the application and deleting them from the application only work if you specify the application name in build phase locations directly by string. This means duplication, and breakage if you only change the name in one place and not the others.

The to location is the Subpath section of the Copy Files build phase of the Tests target. I can’t use $(PRODUCT_NAME).$(WRAPPER_EXTENSION) there because those build setting values aren’t set for the Tests target, where the copying has to take place. They’re set for the MyDocApp target, which can be used by either Tests or No-Tests.

The from location is in the script text in the Shell Script Files build phase of the No-Tests target. If you look at that text, you’ll see that I actually delete two things: the framework in $(TARGET_BUILD_DIRECTORY), which is where it was originally built, and the framework inside the MyDocApp application bundle inside $(TARGET_BUILD_DIRECTORY), which is where the framework was copied to.

The Simple Life
The first two points describe the fragility of the setup: the changes I can make are more constricted or error-prone than I would like.

But the general complexity of the setup also needs to be noted. My setup has two entirely new embedded frameworks that the OCUnit template does not have. It has five targets instead of two. There are 22 steps in the README to change a generic Cocoa project into this.

Is it worth it? I’ll let you know.

2 comments

  1. Uli Kusterer

    Are you sure $(BUILD_SETTING) is right? In shell script build phases, I usually use ${BUILD_SETTING} instead. This may be a bash/csh difference, though.