Wednesday 17 September 2008

First steps with Xcode

This past week, I've been taking my first (faltering) steps with Xcode, Apple's development environment (IDE) for producing programs that run on Mac OS. It's been a bit of a mixed experience.

As with any piece of Apple software, the installation is a smooth experience and the program itself, when you fire it up, looks cute, lickable and friendly. So what could possibly go wrong?

Now, I have to admit that I have a first class aversion to IDEs. I use them as rarely as I can possibly manage - I'm a command-line controlling, Vim-loving power user. I've been building software for the Mac for some time, just using those tools and have been perfectly happy. Mac OS is just another UNIX, and everything tends to behave the way I'm used to. It just has perdy windows on the top. Kinda like KDE, but better.

Unfortunately, I don't want to build a simple "Hello, World!" program, and I don't want to learn Apple's freaky Objective-C right now. I need to get real work done, very quickly. I need to get our reasonably large codebase (320k lines of C++, or which 85k are test code, 1797 source files, of which 466 are those tests) which compiles under Linux (cross-targetting embedded ARM products, and local x86 machines) building and running on Mac OS as quickly as possible.

I could do this on the command line with my existing Makefile scaffolding, but I need all the good cross-OS-version/univeral binary magic that Xcode provides for you, and I need to share the project with people who have an aversion to the command line (they're a shifty bunch).

Enter Xcode stage left. Enter a period of stress and frustration for Pete.

So here's a synposis of my experience with Xcode so far:
  • Like any IDE, it's a large and unweidly beast. If you don't know your way around it at first, it's intimidating. I'll admit, though, that it's not as intimidating or just plain wierd (IMVHO) as either Eclipse or Visual Studio when you fire them up for the first time.
  • Like any online help, the bundled documentation is not very useful. Sure, its great that it's there. Sure, it probably describes every aspect of the program. But it's on the computer, it's hard to read, and it takes a while to work out your way around it. I gave up and bought some books from Amazon (more on these another time). Much more useful.
  • I don't like not being in control any more! You are rather more divorced from your file structure and SCM. If you don't work Xcode's way, then you'll be continually swimming upstream. Unfortunately, we have a large existing codebase that we need Xcode to work with, and this is goig to become frustrating.
  • This is the main observation: I imagine Xcode is great for a project that you start off from scratch. However, trying to get it happy with an existing project is a bit of a pain (perhaps less of a pain if you already know how to drive Xcode!)
  • Importing a large project into Xcode isn't too bad. But you have to understand the difference between source groups and folder references, or you'll struggle trying to work out why thinks don't work as you expect. Hint: use source groups.
  • Xcode doesn't really grok C++. Well, it doesnt understand reasonably complex modern C++. The Code Sense thingy just goes horribly wrong. It totally fails to understand anything inside a namespace (that's hardly rare these days!) and can't cope with nested classes, either. We have many, many classes using the Pimpl idiom, with internal classes called Impl. Code Sense throws it's hands up and shows you 367 top-level classes called Impl. Helpful. To add insult to injury, if you try to drill through any of these different Impl class you're always shown the same members for one of the 367 Impl's. It's very, very borked. In the end I had to switch of Code Sense and carry on as if I was still living in the dark ages.
  • Working with third party libraries seems tricky. External source trees appear to be the best way to do this. It's not obvious how to put them on the header include path - with a ittle experimentation I worked out you can list "$(external_tree_name)" in the pointy-clicky-typey-thing and it worked. If that's documented anywhere obvious, I'll be darned if I could find it.
  • The compiler is gcc (which is the compiler we use for our Linux builds) so there shouldn't be an porting issues, should there? Well, thankfully not too many apart from some small issues caused by different sized types.
  • However, it took a long time to get the compilation working. I was getting millions of bizarre errors through impossible header-file include chains. It made no sense at all. The errors seemingly came from inside standard headers (things like 'error: 'strcmp' os mpt a member of 'std' in c++locate.h:64' - last time I checked it was!). This turns out to be a problem with something called a header map, that seems to interact badly with HFS's weird slightly case sensitive/slightly case insensitive filesystem. You have to switch it off. Except there's no Xcode option to do that, and you have to waste time on Google to find the trick is adding a random secret user setting called USE_HEADERMAP and set it to false. This magically fixes the problem. And there was me thinking that IDEs are supposed to make your life easy.
  • The editor. It's OK. It's Mac OS-y. It's got syntax colouring and Code Sense (for what it's worth - for me very little) built in. But it's just not Vim.
  • The Xcode SCM integration (it supports Subversion out of the box) is almost adequate, and certainly a little underwhelming.
Goodness, I've rambled for a long time. You probably skipped most of that. But I found it cathartic. It's interesting to see how development experiences draw such deep emotions from programmers - but it's natural. We spend all day in front of these things, so it's important to be able to get it to work for you, not against you.

So am I converted to Xcode? Hardly. Am I warming to it? Gently. Does my application compile yet? No, but I'm working on it.

3 comments:

Unknown said...

I do most of my development on the Mac, and I have a couple tips that you may find helpful. First, everything Xcode does it does through command lines anyway, and it helpfully lists the command lines that it runs if you look at the build console (Command-Shift-B). So if you take a look at, for instance, how Xcode generates universal binaries, you'll find that it just uses the `lipo' command under the covers (man lipo for more on that). There's actually very little magic involved, and I've had decent luck just having my Xcode project define an external target that goes and runs my build script/Makefile. To the person hitting Command-R, it looks just the same (right down to the warnings and errors getting pretty-printed), but you get full control over what's happening.

Secondly, if you're looking for a decent editor, I highly recommend TextMate (http://www.macromates.com). Among other things, it can detect the presence of an Xcode project and run the command line version of Xcode on it (man xcodebuild for more on that), so you can do all your editing in TextMate and still build with Xcode with a single key press. And if you're used to command line utilities, you'll be right at home with TextMate's bundle system, and likely a lot more productive than trying to use Xcode's neutered autocomplete. Especially with C++.

Pete Goodliffe said...

Hey - thanks for the tips, Brian.

The move to Xcode is intended to make life easier for native Mac developers who have to work with our existing Linux codebase. Getting them to maintain Makefiles might be a step too far. So we just have a different pain... two build systems. :-(

As it happens, I've been manually lipo-ing things for a separate mac build for some time now!

I do love the Unixyness of Xcode, though. I've played with (although not written up the experience) Visual Studio after the Xcode work. Learning and using with it was a much larger PITA. Seriously.

As for editors, you'll never get me away from the ultimate: Vim :-)

Turly said...

I do a bit of development on the Mac in my spare time (www.finderpop.com) and I just use XCode to set up the project. Building is done on the command-line, editing with MacVim with ctags - bliss!

@Brian - Pete's already got the most decent text editor of them all, why would he be looking for TextMate? :-)