Tuesday, January 18, 2005

More XCode fun

After mentionning my dependencies workaround on the XCode apple list someone mentionned that the problem I was experiencing came from the fact that subprojects were inheriting from the main project active build style. Of course the active build style of the main project doesn't know AT ALL about the needs of the subproject, actually that's even a precondition for the use of subproject: it permits to isolate complexity. I still fail to see any logic in the way this XCode feature was designed and implemented. Any clues are welcome :).

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 ;).

Monday, December 27, 2004

My top reasons why Mac developement with XCode is a nightmare...

We've been working with XCode on the Mac for at least six month now. We used to build all our Mac products with CodeWarrior 8.3 and 9 but decided to drop it because it wasn't offering any support for the new Apple SDKs and it wasn't integrating at all in what we think is a morden build environment. (one of the worst thing in CW is that it still saves its projects as completely opaque binary files that are a pain to handle with CVS and any other non native mac programs). The obvious alternative was to go the Apple way and use XCode. The main appeal came from the fact that XCode uses the well known GCC compiler and all the suite of the GNU toolchain which would supposedly offer a much better development environment.
I've been quite disapointed with that choice. Here are the main problems we encountered with XCode:

- Very slow C++ compiling experience. Visual Studio.NET 2003 is compiling at least twice as fast in most cases. Even without heavy templates. CodeWarrior is also typically an order of magnitude faster at compiling the same code. Amazing.
- XCode's dependency system is broken. It forgets to rebuilt some needed source once every two or three builds. It also rebuilds files that haven't changed (and whose deps haven't changed either). I have a project that I can rebuilt 10 times in a row without modifying any source code and XCode will still rebuild some diferent random files each time. Visual Studio and CodeWarrior both do this perfectly.
- XCode sometimes forget to remove the previous error reports when you start a new build.
- The project depency is not only circumvoluted but also buggy as hell which renders it completely unusable. It doesn't change the working directory to the current building subproject which breaks all relative #includes and other files directive. This means that I have to manually rebuild up to FOUR external libraries I depend on MANUALLY and then switch to my test exectuable to debug. This is not manageable. Breaking big projects into small projects to cut the building phases have been a fundamental development paradigm for decades but it seems that Apple still doesn't get it. Weird. Once again this is something both VS.NET and CodeWarrior do very well (in a diferent way but still very reliable).
- The text editor is sub par. There is no virtual space a la visual studio (you can't get the cursor further that the end of the current line, some like it, some hate it). The key binding editor is showing strange behaviour. Some functions can be bound to multiple keys, some others can't, many functions are duplicated in between the menus and the text editor while some of them are not effective at all.
- "Developement Styles". This is a most unuseable feature. It is presented as some kind of template target system. But you can't have multiple targets with diferent building style in a project. And switching the Style is equivalent to hitting the "Clean Target" button: you'll have to recompile EVERY file in every target! This means switching from debug to release mode takes ages... Better forget about that "feature"....
- XCode would crash unexpectedly every so often: adding files, editing source code, compiling, debuging, and all of a sudden, boom, it crashes. Sometimes it even crashes as you are not using the app at all. CodeWarrior also does that quite often (one of the reason we wanted to get rid of it: sometimes it can't even read back its own project files...). The Apple zealots should have a look at VS.NET which barely crashes at all and NEVER lost any of my file. Even VC 6 was ultra reliable.
- XCode adds files to a project with absolute paths! That amazingly stupid. You have to revert to relative path manually at least once per codding session as it will use your last setting as a default for the next add operation (until you restart XCode...). Even better: the dialog box says "default" instead of showing the actual reference mode it plans to use. What does Default means? CodeWarrior show the exact same kind of stupid decision in some corners. VS.NET doesn't.
- Microsoft have been one of the first to add automatic code completion to their IDE. It works beatifully, never ever getes in the way of the programmer, always work in the background, as a minimal set of keybindings to trigger the code completion, disable it, choose the wanted completion when multiple choices are availables (basically it only hijacks the cursor keys and one or two other keys to trigger/disable the feature). I wish Apple ingineers had used Visual Studio at least 2 minutes before hacking their new wheel... XCode's automatic completion is slow, get things wrong 9 times out of 10, starts to display completion choices when I have actually finished typing a method or variable name (very useful... :-/). And worst than anything: it hijacks ALL the keybindings when it starts displaying it's contextual choice menu! This means that if I start typing a method name it will not propose any choices until I have finished typing it, and then once it does I can't continue typing or run a command (like "build") until I have pressed the Escape key. The equivalent feature never really worked in CodeWarrior, but at least it wasn't annoying, it just wouldn't show up.
- The API formal doc and useability doc is amazingly bad. One can wonder how Apple zealots can continue bashing microsft's pratice with a straight face when once compares the MSDN Library/Visual C++ documentation with the Apple provided one. The doc is a complete joke. Units are never specifier, niether is there links to the types definitions (as an example I was looking at the Carbon Timer API doc lately: some parameters are said to be delay times but their units are not defined in the docs: is it second? milliseconds? days? centuries?). Sample code is ultra ulgy and hides the feature demonstration in tons and tons of stupid formal code hacked together: there is no concistent code conventions, no cross references, no broad explanations or the general usecase guidelines, or when these exists they are just too general (like "Macintosh Apps live inside a window", yeah right, I couldn't guess that... ). There is even some original Mac OS docs: everything is defined in Pascal. Very useful... Not!
- XCode forgets to include updated resources in a targets. This means we have to manually delete the build forlder and rebuild the target completely to be sure that our updated files are correctly copied. Who can you trust? Do we really have to do everything by hand?
- The UI is dog slow: press the Build button with the mouse and it will think you want to display the build submenu instead of launching the build command. You then have to press the button twice: once to close the frigging menu and once to actually re-launch the command.
- Window Clutter: XCode LOVES windows. It loves to open new windows for no apparent good reason. And it doesn't know what dockable window means. This means that if you use five diferent projects (because you broke your main project into librairies...) you'll have at least 5 main windows. Of course the debugger open another window. So does the debug output. And the build output. And if you ask to open a source file it will probably open in another top level window. CodeWarrior shows the same behaviour. It's highly impractical and stupid. And don't tell me to use Exposé to manage these windows because it isn't worth any thing more than the eye candy factor. The only useful Exposé feature is that it enables one to access the desktop at the touch of one keystroke (Windows can do this since 1995: hit the windows key + D and you're done).

My experience coding on a Mac is that the tools are totaly broken and slow. And when you can get past the irritating tools you meet the completely wrong Carbon API with its outdated design and half baked API. Of course there are also some gems (like Shark or MallocDebug) but for the moment my IDE of choice stays Visual Studio which I find much more reliable, fast and feature complete (and it produces faster DSP code too!).
And that's too bad, the Mac platform is very nice from a user's point of view and I wish I could enjoy the same pleasure developing on it that our customers have using our products on it...

Tuesday, November 30, 2004

The Devil is in the details

Some quick facts about Audio Engines:
- Audio signals are important.
- Control Signals are ultra important! They eat cpu time for breakfast and are quite hard to manage in a clean, flexible and userfriendly way.
- A correct Midi implementation for a synth is anything but trivial if you want to handle all the standard events: damping pedal, all the CCs, PitchBend, release samples, etc.
- Voice management can also become quite complicated and push us to make big sacrifices: memory allocations at runtime for dynamic voices creation vs. static polyphony.
- FXs are much harder on the DSP code but have an much simpler infrastructure. Corrolary: synth control code tends to become very complicated once you add all the features and is a very good place to search when looking for a sample of typical Spaghetti code!

Sunday, November 28, 2004

printf("Hello, World!");

After browsing some friend's blog I thought I might happen to have something to say from time to time. So I just opened this blog. The subject will be focussed on my job and the industry I work in.
I'm a senior programmer at a small French company. We create a range of electronic /software musical instruments for Mac and PC. Most of the products are edited under our own brand but our flagship product (a very well known Software Sampler) is distributed by one of the big names of the industry.
I'll try to keep my rambling about music technology unrelated with the day to day events at work because on the one hand it would probably bore you to death ;), and on the other hand I'm not sure my bosses would love to see me expose the guts of the company to strangers, or worse, to competitors :D.
However, being one of the authors of some opensource software, i'll be able to be very accurate about this second part of my job, as we use the NGL and NUI (LGPL libs) in our products.
The changes in NUI can be very interesting to anyone interested in computer graphics, as this lib implements a complete 2D graphic library on top of OpenGL. In other words we are doing the same as Apple's Quartz and Microsoft's Avalon, except we do it in a multiplatorm way (MacOSX, Win32, Linux, BSD...), and we build it as free software...
I'll probably also have occasional things to say about the struggle you face when you mix free and proprietary software: what should go where? How do I decide that feature X will end up in NUI or in the GUI toolkit of my application? Can I really change that choice once the code is done and in the CVS server?
I might rant about Macs vs PCs as I have a love-hate relation with both (ok, I confess, I'm more a PC guy ;-)).
The C++ standard comity might also be a regular target, because even if I do respect the vast amount of work related to the maintenance of the language, I would really love them to wake up to reality of the programming world and the hell they often lay on us when taking some impossible decision!

I hope I'll soon have something to say about a little secret project that we are currently working on, together with a CS student, and that we plan to release as LPGL as well, once we pushed it in the next revision of our sampling engine... More about that later.

French being my native langage, I end up making lots of mistakes in English. I'm sorry about that, but please do correct me! I want to learn and I would really love to speak English fluently one of these days...