Saturday, January 08, 2005

XCode dependencies workaround

Alleluya! I found a workaround for the XCode broken project deps outline in the previous post!
XCode provides a command line tool named xcodebuild that permits to build XCode projects from the command line without opening the big app. The main use of this tool is to have automated build systems but we can very well use it into "External Targets" to build depending projects.
Let's say I have two project: mylib and myapp. I want myapp to depend on mylib so that building myapp will also build mylib if it is not up to date.
- Open XCode and the myapp project.
- Right click on the project tree view and add a new Target.
- The create new project dialog opens, choose external target.
- Call the new target mylib_deps (for example).
- You can now click on the new target in the "Targets" folder of the project. This will display the target edition page.
- Change the tool to /usr/bin/xcodebuild
- Change the arguments to
-project PathToMyLib/myblib.xcode --alltargets -activebuildstyle $ACTION
- Double click on your real main target for the myapp probject and in the main Info View press the '+' button to add 'mylib_deps' to the list of dependencies.
- Add the mylib.a file created by the mylib project to the myapp project and select it in the myapp target just like you would do for a normal framework or external lib

And voila!

These are the basic steps needed to create a dependency on another xcode project. Of course you can refine it a bit. For example every project I have contain at least two targets, one for debugging and one for release with optimisation turned on. If I want the debug target of myapp to depend on the debug target of mylib just change -alltargets to -target debug in the arguments.

The advantages of this solution is that it works very well, even if only myapp is loaded in xcode you will be able to build it and rebuild its deps. If an error occurs during the build of a dependency xcode will display the error correctly and you will even be able to click on it in the detailled build view so that it displays the file where the error occured and you will still be able to fix it from the embeded text editor without ever opening the original project. You can have any level of depth in the dependency tree: I have more than 4 levels in my build system and it works great :).
Disadvantages: one could argue that the build gets even slower but I prefer a correct and slow build to a fast and broken one. There is also the problem that you don't get a good user feedback of what's going on during the depes build (it just shows "building" in the status line), unless you open the detailled build view...
In fact the only problem I have with this solution is that it's a workaround a broken xcode feature: deps management are one of the main reasons we use build systems and IDE. A correct external project dependency system is NOT optionnal in a so called professional IDE and I still consider xcode broken in that regard as the workaround is much more painful to get working than it should be.
I'm open to suggestions in order to refine the processus, if you have nice tips and tricks to ease our life in XCode you're very welcome to send me a message or comment to this entry ;).

No comments: