How can I change the name of a release target without affecting the build of unit test target? - xcode

I have a release target and a test target, I want to change the name of the release target, but if I do so I start getting a linking error in the test target. As they are unit tests I didn't think there would/should be a dependency within the test target to the release target, but apparently there is.
The linkage error is:
ld: file not found: /Users/Cequint/Library/Developer/Xcode/DerivedData/XYZ-apppviisyaexwpdcwgjtfldjotro/Build/Products/Debug-iphonesimulator/XYZ.app/XYZ
Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang failed with exit code 1
XYZ.app is the name of the release target before I renamed it.
Is there an automatic or quick way of updating the unit test target so that it keeps in step?

Depending on how the unit test target was added, you may or may not have a build dependency in the test target to the app target. I would check there first in targets->test target->build phases->target dependencies. I would think XCode would automatically update that but you never know...
One more place to look for targets is in the unit test targets build scheme, where you should see the test target (plus optionally the project target itself, as I have a dependency on it in my personal test project).
Another place to test the reset method mentioned by others above is to go to the organizer, select projects, then 'delete...' all the derived data for the project in question.

Probably a bit late with this answer, but I experienced this same issue (Xcode 6.3) and figured out a fix:
Go into the Project Inspector and select the unit test target Locate
the Test Host value (it will be something like
$(BUILT_PRODUCTS_DIR)/MyOldAppTargetName.app/MyOldAppTargetName)
Edit the Test Host value to reflect the new app target name
(something like
$(BUILT_PRODUCTS_DIR)/MyNewAppTargetName.app/MyNewAppTargetName
I have filed this as http://www.openradar.me/21139630 and rdar://21139630 with Apple. Feel free to dupe if you also experience this issue.

Related

How to create Target that always runs at the end of a build

I've got a vxcproj with configuration type Driver and am trying to edit the project file to add a custom target that will always run at the end of building the project. I want it to run even if the standard build system detects it doesn't need to build anything.
I'm having a hard time trying to work out where to attach my target. If I attach to AfterBuild or PostBuildEvent, my target won't run if there's nothing to build.
If you're interested, I need this target to run run StampInf and Inf2Cat tasks as the built in versions of those don't suit my purposes. The built in ones always run and dirty outputs, causing knock on rebuilding which I don't want in an incremental build.
Add a project of type General + Makefile. VS cannot optimize the build for these type of projects, the custom Build Command Line setting you specify always runs. You'll typically need to set the project dependencies to ensure it runs last.

Unit Tests are always "successful" after adding OCMock

I would like to use OCMock in my Cocoa project's unit tests. I have downloaded the latest version of OCMock (2.0.1) and copied the OCMock.framework into my project's directory. In Xcode, I have added the framework to the unit test target's link phase. I have then added some code that uses OCMock's classes.
From then on out, all unit tests are reported as "successful" - green light, no errors or warnings. Even after introducing STFail calls, Xcode claims "Test succeeded". Placing a breakpoint in arbitrary test methods reveals that none of them are executed.
The issue persists if I comment out the code using OCMock, including the import directives.
The issue vanishes - i.e., the STFails start failing again - when I remove OCMock from the link phase.
This is similar to another question I've asked before, but not exactly the same: In this case, the info in the Log Navigator shows no errors. What could be causing this behavior? What can I do to diagnose the matter?
It turns out I was missing a Copy Files build phase for the framework, which apparently may lead to a variety of issues.
This works for me:
Add a Copy Files phase to the unit test target's build phases. I positioned it right before the Run Script phase, making it the second-to-last one.
Drag the OCMock.framework item from the project navigator onto the phase in order to add it; adding it using the + button doesn't work in Xcode 4.6 (maybe because frameworks are directories?).
Set the phase's destination to "Frameworks".
In the unit test target's build settings, look for Runpath Search Paths and add the entry #loader_path/../Frameworks.
This way, the unit test executable will be able to find the framework at runtime. Note that you can also use "Products Directory" as the destination of the Copy Files phase, in which case you can skip the fourth step.

Dynamically adding resources to XCode project, always one cycle behind

I need to assemble resources for an application depeding on XCode build settings. The easiest way to achieve this, is through a build script phase. Although this works, this somehow always builds my target with resources one version lagging (a second build is needed to get things really up-to-date).
The Resources folder is a reference to a folder in which my script (or rather, custom built command line tool called from script) copies the appropriate resources. The run script build phase is the first (topmost) phase in my target.
A solution I've found on the web somewhere, is to create an "External Target" and add that to the original target's build phases (by dragging the External target onto the original target). This does indeed seem to fix the "one version behind" issue, but I cannot seem to get the current target's environment variables to be passed to this "External target".
Why is XCode not including the just updated resources? What other alternatives are there?
You could try to define an internal target (say, "ResourceTarget") and make the main target dependent on ResourceTarget. Then let your script run in the script build phase of ResourceTarget, so the resources are all updated when the second target is build.
That way, environment variables should be the same.

How should I manage dependencies across projects in an Xcode workspace?

I'm working on an iOS app project, and add the json-framework project to the workspace. The project navigator on the left shows both projects, and the build scheme selector shows the schemes from both projects too. Now I want to add the libjson.a target from the json-framework project as a dependency on the iOS app target in the other project. The expected result is that whenever the app target is built, it builds (if necessary) the library target and links the app target against it. Here are the ways I've tried to do this:
Build both as part of the same scheme. The way I try this is to edit the scheme for my app, adding 'libjson.a' to the 'Build' portion of the scheme, and by the way "Find Implicit Dependencies" is checked. Then I go to the target editor for my app target, and in "Build Phases"->"Link Binary With Libraries", I choose 'libjson.a' from the list of workspace libraries.
When I subsequently try to build the scheme, I see it build the library target, but building the app target fails with linker error "Library not found for -ljson" - suggesting that it hasn't actually discovered that the library has been built. Indeed in the project navigator, the entry under the app project for the library is still red indicating that the file doesn't exist.
Add the json target as an explicit dependency. To try this, I don't modify the build scheme, but go to the target editor for my app target and click the add button under 'Target Dependencies'. No targets from other projects in the workspace show up, so this is a non-starter.
Drag the JSON project into the other project, then add the target as a dependency. This is what I would have done in Xcode 3. In the project navigator, I grab the library project and drag it over the app project. This brings up the usual 'add files' pane, which I just dismiss by clicking 'Finish'.
There are now two entries for the library project in the project navigator: one at the top level, and one under the app project. I can now add the library target as a dependency of the app target using the target editor, and can link against it without error in the link libraries phase. But it looks broken: there are multiple entries for the same project in the navigator. Is there a different way to do this?
What should be considered the "Xcode 4-ish" way of connecting these targets in different projects in the same workspace? It would seem lacking if multiple projects in the same workspace can't actually interact with each other.
Thanks,
Graham.
I’ve just set a test project up, pretty much as you describe in version 3, by creating a new workspace and dragging the two Xcode project into it, nested as shown.
You can delete the sibling project if you have it already.
Hitting build on this and it just works, as far as I can see.
I imagine there is internal path-confusion if you have two projects, and I’d be inclined to fiddle with location settings in "View"->"Utilities"->"File Inspector" and see what effect that has.
Another thing to try is to set your paths up in Xcode "Preferences…"->"Source Trees" and refer to them that way, as described here: Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References
HTH. Andy W.
I managed to get dependencies between projects in a workspace to work as I described here: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/.
Unfortunately I can't find a way to get Xcode to discover implicit dependencies or index everything in the build as advertised. I found workaround to both but I'm hoping that less manual configuration will be needed as Xcode 4 matures.
I was going to ask the same question, thinking that my own solution couldn't be right. But I don't see it mentioned here, and it does seem to work. Clearly XCode 4 is a work in progress. :)
I have a workspace with two projects: a static library and an app which uses the library. The projects are siblings. Each project has its own scheme, and each scheme is set to only build one target. In other words, I added two projects to the workspace and that's it.
To add the static library as a dependency of the app, I just drag the libsomething.a product from the library project (Project Navigator) into the "Link Binary with Libraries" list for the app target. That's it. Now when I build the app the library project is built first and then linked. Interestingly, when I modify the app's scheme to use a different configuration (eg, Release instead of Debug), the library is built using the same configuration.
So it works, and there is clearly some automatic dependency checking going on here. But it feels wrong. Then again, so does the modal scheme editor/manager and lack of a workspace object in the project navigator... I never thought I'd say it, but the Visual Studio UI (bleh) is a lot clearer.
My bullet-proof solution to do this :
Create "Per Debug-Release / Per Architecture" settings in Build Settings in the Main project (not the lib), to include either
../MyLibProject/build/Debug-iphoneos
or
../MyLibProject/build/Release-iphonesimulator
or
etc..
depending on the configuration (you can create those kind of configuration by clicking on the + next to Debug or Release and choose either "Any iOS Simulator SDK" or "any iOS SDK".
You need to do that for both "Header Search Path" (in case your library copy some headers files, which is more than likely) AND for "Library Search Paths". Which means that for each setting, you'll probably end-up with 4 different paths (debug sim , debug ios, release sim, release ios).
That would make sure the configuration of both projects match.
Now, to auto-compile the lib, that is to create the dependency, you can use the "Build Phase -> Link to Binary With Libraries -> + -> select the .a file" advice given above.
That's the only way I managed to have something that builds and link correctly for every environment on xcode 4.5
Note : I even added the -lmyLib flag in "other linker flags", but i'm not sure that's really necessary
I've had some success with creating framework-like static libraries, though it's not a perfect solution.
I see the next variants:
Explicit dependency in a project[About]
Implicit dependency in a workspace[About]
See the Xcode user guide: Xcode Concepts -> Xcode workspace under 'Projects in a Workspace Share a Build Directory'.
All projects in a single workspace share a build directory. Dependencies are discovered automatically and build if needed:
"Xcode examines the files in the build directory to discover implicit dependencies. For example, if one project included in a workspace builds a library that is linked against by another project in the same workspace, Xcode automatically builds the library before building the other project, even if the build configuration does not make this dependency explicit. You can override such implicit dependencies with explicit build settings if necessary. For explicit dependencies, you must create project references."

Specifying a subproject's Configuration in Xcode

I have an Xcode project (A) referencing another project (B). By default (as far as I understand it) Xcode will implicitly build the configuration for the B dependency that matches the configuration of the A's target (e.g., "Debug"). But what if I want, say, A to build as "Debug" and the B to build as "Release"? How would I go about specifying that in Xcode?
I don't know of any easy approach, but you can brute-force it by calling xcodebuild directly for the dependency with a "Run Script" build phase.
I know it was just an example, but if your real goal is that the sub-project be a Release (no symbols) build, then you may have a better experience by just building the sub-project into a library or framework and checking the resulting binary into your version control system. Whenever I have a piece of the system that seldom changes and that I don't want debug symbols for, I go ahead and build it as a static library and check it in. I often go ahead and move the code elsewhere as well (with a README file with the .a that says where the code is and how it was built). This saves time on both build and checkout and is invaluable for large projects in my experience.
This might help: if the configuration of the project A is not found, Xcode will build Release config as a fallback (or maybe the first config of the list).
Then you can "force" the link using this tip: Xcode custom build configuration causes "library/file not found" for static libraries
Yes, this is not naturally supported by Xcode; when you build a target, it builds one configuration of itself and of all dependent targets.
The workaround, as Rob mentioned, is to have a dependent target that's an Aggregate Target type that comprises a single Run Script build phase, which simply invokes xcodebuild -configuration Release (or whatever).
You can specify the default 'fallback' configuration in the project info.
Change from:
Use 'Release' for command-line builds.
to:
Use 'Debug' for command-line builds.
And default will be 'Debug'.
Diffs of project file:

Resources