Tag Archives: Xcode

More about OCDepend

A few hours after I posted about the email I got from CPPDepend, I received this response:

Hello,
I read your interesting feedback about our product posted in your blog, and what can I confirm is:

- It's not a spam, this mail was sent to only 3 people, that we consider they have a good Objective-C skill to have their valluable feedbacks.
- You are right some effort must be done for OCDepend in our website.
- Maybe I'm wrong but I dont think that OCDepend features exist in XCode, for example CQLinq is a powerful tool to request code base and enforce its quality.

If you have time to test the product it will help us a lot to improve the product,

Best Regards.

Dane.

Here is my response:

Hi Dane,

Please note, in the interest of full disclosure, that I have also posted this response on my blog for my readers to see.

First, I’d like to say that I’m impressed. Not everyone would bother to take the time to respond to comments like the ones I made, and considering how “form letter” the first email was, I’m doubly gratified to see a personally addressed response the second time around.

I’m still somewhat troubled that the original email read very much like marketing spam. Thank you for contacting me and for considering my opinion valuable, but in my opinion, sending a generic email that doesn’t say anything about why I’m receiving it or give me any sense that it was even intended for me is a very poor way to ask me to review your product. Since you did take the time to respond to me, however, I will offer these additional thoughts:

The value of the pro license you offered in your first email, USD $500, is by itself something I would not recommend to any Objective-C developer in the first place. Mac developers, particularly the smaller ones like myself, are not as used to such high-cost licensing schemes as you’ve probably come to expect from your Windows customers. I certainly wouldn’t consider buying something that expensive unless I had very certain and solid proof that it was going to save me a significant amount of time over the tools Xcode already provides.

Without actually looking at the product itself (and I’ll emphasize to other readers, I have not looked at OCDepend itself and can offer no direct judgements about it), I have browsed your website considerably, and I have to say again: It is entirely lacking. As a developer, I read the phrase “CppDepend and OCDepend are based on Clang for more reliability.” and immediately dismiss it as nonsense. It turns me off, severely so. Basing something on Clang does not intrinsically make it reliable; it only means you have access to the exact same system upon which modern versions of Xcode are built! And Xcode itself shows that it’s extremely possible to be based on Clang and still be horribly unreliable.

Your cited feature that makes OCDepend so much better than Xcode is this “CQLinq” language that allows for querying of my code. To what end, exactly? To “request code base”? Assuming I understand your intended meaning, this means I can get information about my code in query-language form. I presume “enforce its quality” refers to something like putting this query language in a Git commit hook or other such script to check that conventions are being followed. Your website cites CQLinq as being “for maximum flexibility”, which is meaningless if it’s actually your flagship feature; that phrase makes it sound more like an add-on for advanced users. I don’t mean to make light of your English, and if I’m doing so, I apologize, but I can’t see what this feature is meant to do for me. Your website gives the following example:

from m in Application.Methods  
where m.NbLinesOfCode >  30  && m.IsPublic
select m

Which returns all public methods longer than 30 lines of code. So, I have to learn a new domain-specific language applicable solely to your product in order to do something that’s ill-defined at best to begin with. What is a line of code? Do blank lines count? Lines consisting only of an opening or closing brace? Comments? Preprocessor macros? Macros that delete code under certain conditions? To say nothing of the fact that Objective-C doesn’t have the concept of non-public methods.

CppDepend also advertises its ability to compare builds. Any developer who needs to do this is almost certainly already using Git or Mercurial (or some other VCS) to do so for free. For tracking builds in the wild there are such tools as HockeyApp, Crashlytics, and TestFlight. CppDepend’s dependency graphing already exists in Xcode, and quite frankly, most of its other features for code quality look like something of interest purely to managers more concerned with metrics than functionality. No developers with whom I’ve ever personally worked in Objective-C (my personal experience only, that of others will almost certainly differ) have worried about metrics like these. They’re more the subject of The Daily WTF articles!

In summation, from what I can see without downloading your product, I can’t imagine I’d ever give it a second glance. It is obviously true that my experience may be atypical, that there may be much more useful features in your product that are not listed on your website, that I’m simply in a bad mood today, or any number of other explanations for my disinterest. I remain very much open to being proven wrong, and I look forward to that possibility, but as it stands I could not recommend this product to anybody (again, for those others reading, I haven’t in fact downloaded it at all, so take it with a grain of salt). I would see the price tag and immediately veer towards the tools I already have unless yours could quickly and convincingly show me that it was better for the job.

— Gwynne Raskind

A short note on CPPDepend/OCDepend

This morning, I got an email from someone purporting to be from something called “OCDepend”, which turns out to be some kind of tool for using Clang to analyze Objective-C code.

Basically, the static analyzer with a bit of GUI and a LINQ language for looking at your code, from what I can tell.

There’s not a single screenshot of the Objective-C version on their website, and I’m not about to download a tool which:

  1. Is so desperate that they’re sending out free pro license offers to random people with an email form letter in hope of a good blog review.
  2. Has absolutely no documentation on the website, which is purely about the C++ version of the tool for Windows.
  3. Sends the aforementioned email from an address which appears nowhere on their website but at the same time isn’t a personal name; it came from just “developer”@.
  4. From what I can tell, duplicates functionality that’s been built into Xcode for some time now, and provides nothing else beyond a query language for information that Xcode also shows.

I would strongly suggest to these people that they look over their marketing and consider carefully what they’re really providing to their supposed Mac customers before sending out unsolicited emails with bad grammar and poorly qualified From addresses.

P.S.: I looked over the email carefully and it doesn’t appear to just be random spam, but if it is, my apologies to CPPDepend.

P.P.S.: The full text of the email I received, in case someone can tell me I’ve lost my mind and/or am overreacting:

Return-Path: <cppdepend AT gmail DOT com>
Sender: cppdepend AT gmail DOT com
Date: Thu, 7 Mar 2013 14:06:27 +0000
Subject: Managing Objective-C code quality using OCDepend
From: developer <developer AT cppdepend DOT com>
To: REDACTED
Content-Type: multipart/alternative; boundary=f46d0444ee1f73edc604d7563650

--f46d0444ee1f73edc604d7563650
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Hi,

I'm Dane the Community Manager for OCDepend Tool.

*OCDepend* is a static analysis tool that simplifies managing Objective-C
code quality and provides a highly flexible code query language. Please
find more detailed features here : *http://www.cppdepend.com/Features.aspx*

I=92ll be pleased to offer you a pro licence, so that you can try OCDepend
and blog about it if you find it useful.

I=92ll send you a pro licence as soon as I receive your confirmation.

Some of OCDepend=92s key functionalities :


   - Code Query language(CQLinq), with visual tools/editors
   - Compare Builds
   - More than 80 Code Metrics
   - Display analysis results in different types of Diagrams
   - Easy integration to Build process
   - Detailed and highly customized reports
   - Facilitate Code Reviews by using Code Change Metrics
   - Visual Editor that gives many views (Code Query Builder, Dependency
   Graph, Matrix and Metrics views ++)


Best Regards!
Dane,
OCDepend Developer & Community Manager.

--f46d0444ee1f73edc604d7563650
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font-size:13px;backgroun=
d-color:rgb(255,255,255)"><font face=3D"verdana, sans-serif">Hi,</font></di=
v><div style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255=
,255,255)">
<font face=3D"verdana, sans-serif"><br></font></div><div style=3D"color:rgb=
(34,34,34);font-size:13px;background-color:rgb(255,255,255)"><font face=3D"=
verdana, sans-serif">I&#39;m Dane the Community Manager for OCDepend Tool.<=
/font></div>
<div style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255,2=
55,255)"><font face=3D"verdana, sans-serif"><br></font></div><div style=3D"=
background-color:rgb(255,255,255)"><font face=3D"verdana, sans-serif"><font=
 color=3D"#222222"><b>OCDepend</b> is a static analysis tool that simplifie=
s managing Objective-C code quality and provides a highly flexible code que=
ry language. Please find more detailed features here :=A0</font><span style=
=3D"background-color:transparent"><font color=3D"#1155cc"><u><a href=3D"htt=
p://www.cppdepend.com/Features.aspx">http://www.cppdepend.com/Features.aspx=
</a></u></font></span></font></div>
<div style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255,2=
55,255)"><font face=3D"verdana, sans-serif">=A0</font></div><div style=3D"c=
olor:rgb(34,34,34);font-size:13px;background-color:rgb(255,255,255)"><font =
face=3D"verdana, sans-serif">I=92ll be pleased to offer you a pro licence, =
so that you can try OCDepend and blog about it if you find it useful.</font=
></div>
<div style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255,2=
55,255)"><font face=3D"verdana, sans-serif">=A0</font></div><div style=3D"c=
olor:rgb(34,34,34);font-size:13px;background-color:rgb(255,255,255)"><font =
face=3D"verdana, sans-serif">I=92ll send you a pro licence as soon as I rec=
eive your confirmation.</font></div>
<div style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255,2=
55,255)"><font face=3D"verdana, sans-serif">=A0</font></div><div style=3D"c=
olor:rgb(34,34,34);font-size:13px;background-color:rgb(255,255,255)"><font =
face=3D"verdana, sans-serif">Some of OCDepend=92s key functionalities :</fo=
nt></div>
<div style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255,2=
55,255)"><font face=3D"verdana, sans-serif">=A0</font></div><div style=3D"c=
olor:rgb(34,34,34);font-size:13px;background-color:rgb(255,255,255)"><ul st=
yle>
<li style><font face=3D"verdana, sans-serif">Code Query language(CQLinq), w=
ith visual tools/editors</font></li><li style><font face=3D"verdana, sans-s=
erif">Compare Builds</font></li><li style><font face=3D"verdana, sans-serif=
">More than 80 Code Metrics</font></li>
<li style><font face=3D"verdana, sans-serif">Display analysis results in di=
fferent types of Diagrams</font></li><li style><font face=3D"verdana, sans-=
serif">Easy integration to Build process</font></li><li style><font face=3D=
"verdana, sans-serif">Detailed and highly customized reports</font></li>
<li style><font face=3D"verdana, sans-serif">Facilitate Code Reviews by usi=
ng Code Change Metrics</font></li><li style><font face=3D"verdana, sans-ser=
if">Visual Editor that gives many views (Code Query Builder, Dependency Gra=
ph, Matrix and Metrics views ++)</font></li>
</ul></div><div style=3D"color:rgb(34,34,34);font-size:13px;background-colo=
r:rgb(255,255,255)"><font face=3D"verdana, sans-serif"><br></font></div><di=
v style=3D"color:rgb(34,34,34);font-size:13px;background-color:rgb(255,255,=
255)">
<font face=3D"verdana, sans-serif">Best Regards!</font></div><div style=3D"=
color:rgb(34,34,34);font-size:13px;background-color:rgb(255,255,255)"><font=
 face=3D"verdana, sans-serif">Dane,</font></div><div style=3D"color:rgb(34,=
34,34);font-size:13px;background-color:rgb(255,255,255)">
<font face=3D"verdana, sans-serif">OCDepend Developer &amp; Community Manag=
er.</font></div></div>

--f46d0444ee1f73edc604d7563650--

Getting rid of old certificates in Xcode

Xcode 4.x’s Organizer window has an annoying habit of not only keeping old certificates (whether expired, revoked, duplicated, or otherwise redundant) around, but also restoring them every time you try to delete them. There’s no interface in Xcode for removing these extraneous identities and nothing sees to work for getting rid of them. Here’s what I originally tried, more or less in order and starting from the beginning with another step added every time:

  1. Deleting certs and keys from Keychain Access
  2. Deleting certs and keys with the security command
  3. Restarting Xcode
  4. Restarting computer
  5. Ditching ~/Library/Caches/*{Xcode,Developer}*
  6. Ditching ~/Library/Preferences/*{Xcode,Developer}*
  7. Ditching ~/Library/Developer (while saving only my keybindings and font/color settings)
  8. Removing all archives from the Organizer
  9. Grepping my entire home directory for the certificate name (four hours taken)
  10. Grepping my entire computer for the certificate name (2.5 days taken as I couldn’t figure out a command that excluded sending it down several recursive directories that led back to / – I could’ve, but I was lazy).

I finally ferreted out the final hiding place of Xcode’s ridiculous cache of certificates in /var/folders/<some random alphanumeric characters here>/com.apple.{dt.Xcode,Xcode.501,Developer} (or something very similar). When I deleted that and all of the other things mentioned above, the offending/offensive identities finally vanished.

tl;dr: To make sure you’ve really killed Xcode’s cache, make sure you clear out the area Apple deliberately made hard to find and set as $TMPDIR as a so-called security measure.

Objective-C and the Web

Earlier today, courtesy of @GlennChiuDev, I was reading Kevin Lawler’s informal tech note about using Objective-C to power the Web. I found myself agreeing with quite a lot of it.

I then had the chance to read @heathbordersresponse to the original post, which I realized I was also agreeing with in considerable measure.

So here’s my response to both. I’ve assumed that readers have at least skimmed both the original post and the response so that I don’t have to do what Heath did and duplicate everything they said here :).

Kevin makes the point that Apple has hugely improved Objective-C in recent times, especially with the most recent releases of OS X and iOS. Heath objects that while Objective-C has certainly improved, it’s still a strict superset of C and comes with all of C’s well-known and discussed-to-death problems.
While I agree with every one of Heath’s list of issues with Objective-C, my thought is that everyone works best in whatever works best for them. Some people (myself included) are going to be more comfortable in a bare-metal-with-extensions language like Objective-C, while others are never going to enjoy it in comparison to Java. It’s a personal thing, and I’d argue that a programmer who doesn’t like Java, for whatever reason, will never save time in it no matter how many conveniences it provides over Objective-C. Heck, I get plenty of scripting done in PHP even though I agree that Python and even Ruby have enormous language advantages and that PHP has severe community and design issues, because I’m extremely familiar with it.

Kevin goes on to say that Java was meant to be a write-once run-anywhere language but failed at it, and Heath counters by pointing out that Java does indeed do this.
This isn’t really a simple argument in either direction. Java was indeed intended as write-once run-anywhere, but while Java CLIs and servers do fulfill this promise for the most part, I think Kevin was thinking (as I did at first) of Java GUIs. To a one, I have never met a Java GUI I like, on any platform. Java apps look and act horribly non-native on OS X, are slow (and odd-looking, if less so) on Windows, are just as clunky as everything else on X11 (my personal opinion of all the X windowing toolkits is that they all stink), and as for Android… well, I don’t like Droid, and even that aside, Java working “right” on one platform is the exact opposite of the promise. In that respect it might as well not be any different from Objective-C in its platform dependence.

I do have to agree with Heath and disagree with Kevin regarding writing portable C/C++ being easy. Even if you use only POSIX APIs exclusively, which will severely limit your functionality in the general case, this is a nightmarish undertaking. Even if you restrict yourself only to Linux variants, nevermind trying to work with all the other UNIXen, OS X, and Windows, it’s all but impossible without a complex system like autoconf (which is another entire rant about horrible garbage in the making).

With regards to the JVM, I have to agree with Heath again: The JVM is absolutely a useful UNIX system layer, and JIT does make it a lot less slow than Java used to be. Similarly with garbage collection; GC is an abomination in C and Objective-C, but that’s because the design of those languages precludes the collector having full knowledge of what is and isn’t a live object without very restrictive constraints. In a fully virtualized language like Java or C#, properly implemented garbage collection is absolutely a useful technology.

I can’t say much about Java re: Oracle, since I don’t know much of what really happened there, but just from reading the respective posts, I have to say Heath makes a more persuasive argument than Kevin’s declarative statements.

Kevin then goes on to say that object-oriented programming is a win over functional programming, and Heath objects, saying that there are a great many people who disagree. In this case, while I personally agree with Kevin in my own work, this is another area where personal preference and training will trump blanket statements every time.

Kevin also talks quite a bit about Automatic Reference Counting (ARC); Heath didn’t respond to this section. I find ARC an absolute divine gift in Objective-C, but all ARC does is bring the syntax of GC to a non-GC environment, and in an incomplete fashion: The developer must still be careful to avoid retain cycles with weak references and explicit nil-ing of strong references.

Kevin goes on to talk about Apple’s failed WebObjects project. He gives some reasons and thoughts about Apple moving Objective-C to cross-platform deployment. He seems to be unaware of GNUStep, ObjFW, and other similar projects, but setting that aside, I absolutely agree that Apple bringing the full Objective-C runtime, including most if not all of Foundation, to a wider UNIX base would be spectacular. Reviving and expanding the former OpenDarwin project would also be awesome, in my opinion. In this, I’m completely on Kevin’s side; this should happen and he lists several good reasons for Apple to do it.

Now Kevin goes on to say what is no doubt the most controversial thing in his entire post: “Xcode is an excellent IDE, with tolerably good git support.”

Like Heath, I must say: This. Is. Patently. False.

Xcode 3 was a tolerably good IDE, absolutely. Not modern or fully-featured by any measure, but fairly decent. Xcode 4, however, is a crock of <censored>. I’ll let Heath’s response speak for me on this for the most part, but I’d like to add that Xcode’s git support is also absolutely abysmal. Worst of all, there’s no way to shut it off, even if you never told Xcode that the project had a git repo.

So to summarize, what Kevin seems to have posted is a rant about his issues with functional languages and Java, and his love for Objective-C, without a lot of facts to back it up. I’m strongly in agreement with his feelings on most points, and I totally agree that Objective-C would be an awesome language for Web programming, but I suspect Apple hasn’t gotten into the field exactly because Java isn’t the terrible beast he made it out to be. This is a shame, to be sure.

As a footnote to those who still follow this blog hoping for a post on this subject: Missions of the Reliant isn’t dead! I’ve been pretty busy for a long time, but I will find time to work on it!

My Xcode rant

It seems everyone who develops for OS X or iOS these days has their own rant about the problems with Apple’s development environment, Xcode. Well, here’s mine, excerpted from a message I sent to the xcode-users mailing list.

Xcode 3 was getting pretty good for awhile, but then Xcode 4 was released, a massive backwards step in functionality which has only been getting worse with its point releases. I have suffered, shockingly, very few of the crashes and data loss bugs which other people have been plagued with, but I have plenty of gripes just the same.

Xcode 4’s integrated layout may look good on paper, and even work better for some people, but for others it’s a hopeless struggle to manage screen space and get a consistent workflow going. Xcode 3’s ability to pop open and then close the build progress window was delightful; with Xcode 4 I just get the build log in my editor pane without being able to see the code I’m working on. Ditto that the IB integration into Xcode; with a windowed layout that would have been tolerable, but as it is I spend considerable time just going back and forth between interface and code views to see what the heck I’m doing – and no, tearing off Xcode 4’s tabs doesn’t make it better, because that has a near-100% tendency to completely destroy my window position and layout settings. Xcode 4 took away the class hierarchy view. It took away the ability to compile one file at a time. The integrated debugger console is painful and takes away from code editor screen space. Workspaces are just plain broken and do not work as advertised. The configuration editor is a step up, but unfortunately the “scheme” concept is a two steps down. Switching between Debug and Release should not require chugging through three settings panels to find the right switch. And don’t talk to me about the inability to shut off Git integration on a per-project basis (or, for that matter, at all). Why can’t I enable Guard Malloc or change the debugger used for unit tests? Why am I sacrificing valuable screen space (and I say that having a 27″ screen, fully aware that people are doing dev with Xcode 4 on 11″ Macbook Airs) for an iTunes-like status display when Xcode 3’s status bar was just as useful?

And Xcode 4 itself is, as a whole, sluggish in every respect. Operations of all kinds, from editing text to creating connections in IB to switching between code files, which were perceptually instantaneous in Xcode 3 take visible time in 4. Even those 200 milliseconds here and there add up to an overall feeling that I’m spending more time waiting for my development environment to catch up with my thinking than I am actually writing code. Yes, it’s very nice that the debugger console and utility panels slide neatly in and out with smooth animation, but I’m a developer; Apple doesn’t have to market eyecandy to me. I’d strongly prefer instant response. And all I get for all this trouble is ridiculously bloated memory usage forcing a restart of the program every several hours of serious work.

Before anyone asks, yes, I’ve filed several Radars. All have been closed as duplicates (which means I’ll never hear anything about them again) or ignored (same result). The impression I get from Apple is that they think that they have enough people who build their livelihoods on the iOS ecosystem that they don’t have to put any effort into improving the tools for those who give a darn about a time when writing code wasn’t an exercise in stockpiling $20,000 for a tripped out Mac Pro whose stats can compensate for Xcode’s flaws.

Some other good examples of the problems people have with Xcode:

Lua + iPhone = mess

And now one of the rare not-Missions-related posts.

I found myself with the need to run Lua code under iOS. Yes, this is legal according to the current Apple Developer Agreement. Who knew the journey I’d undertake in the process.

Originally, I got it running by just building the Lua source files into a static library and linking it in, then using the C API as usual. Worked like a ruddy charm. But then I decided to get clever. “Wouldn’t it be great,” I thought, “if I could run the bytecode compiler on the source and make them into unreadable bytecode objects?” So originally, I tried piping the source files through luac and running them otherwise as usual. The story of how I got Xcode to automate this process without a damned Run Script build phase is another one entirely.

Bad header in precompiled chunk.

Docs say, “The binary files created by luac are portable only among architectures with the same word size and byte order.” Fine. x86_64 and armv[67] are both little-endian, but sizeof(long) on x86_64 is twice what it is on armv7. Duh! Running Stuff on Apple Systems 101. Universal binary, here I come! I built lua 32-bit and lipo’d myself a nice universal binary of luac, ran it via /usr/bin/arch -arch i386.

Bad header in precompiled chunk.

What? Byte order and word size are correct. So I delved into the Lua source code. lundump.c, lines 214-226. Precompiled chunks are checked for version, format, endianness, size of int, size of size_t, size of Lua opcodes, size of the lua_Number type, and integralness of lua_Number. All of which should have been correct- until I remembered that I’d changed the luaconf.h of the iOS binary’s Lua to make lua_Number a float. It’s a double by default.

Rebuild my universal binary of luac using the same luaconf.h the iOS project uses. Run it through yet again. Lo and behold, it worked that time. It doesn’t really feel right to me running i386-compiled bytecode on armv7, but since Lua doesn’t even remotely have support for cross-compilation and I don’t feel like jumping through the hoops of making a luac utility on the device without jailbreaking, it’s the best I can do.

I would be remiss if I didn’t remark also upon the journey of learning how to make Xcode automate this process for me. There was more than just running luac to be done. I wanted my Lua scripts run through the C preprocessor, to get the benefits of #include and #define. Easier said than done. The C preprocessor doesn’t recognize Lua comments, and while because comment stripping is part of preprocessing I could have used C comments instead, it would have meant changing a goodly bit of code, and messed with the syntax coloring. And more importantly, my sense of code aesthetics. It’s always bothered me that the C preprocessor can be both Turing-complete and damn near impossible to work with (an aptly-named Turing tarpit). So I wrote a pre-preprocessor (also in Lua, naturally) to strip the Lua comments out first. But then I had to parse and handle #include manually. Oh well. The real benefit of C preprocessing is the macros anyway. It was quite an interesting bit of work making Lua talk to clang; the built-in library for doing things is a little bit lacking. Anyway, the upshot was there were three steps to processing Lua files in the iOS project: preprocess, luac, copy to Resources.

I finally caved in to my sense of danger and went looking for the extremely scanty reverse-engineered documentation on Xcode plugins. It was pretty awful. The API looks to be quite a mess of inconsistently named attributes with strange side-effects. It took me two hours to hunt down the cause of a “empty string” exception as being the use of $(OutputPath) inside a cosmetic attribute (Rule name). It was hardly perfect even when I declared it done, and then I realized I had the architecture problem again. I had to run a different luac for x86_64 than for everything else. If i386 was the only other architecture, I could’ve just let it be done by a universal binary, but no, it had to cover armv[67] too. Ultimately it turned out a second plugin was necessary, lest Xcode be sent into a downward spiral of infinite recursion at launch. Ugh. Don’t talk to me about all the horrifying effects the tiniest typo could have on Xcode. I love the one in particular where the application was fully functional, except for builds and the Quit command. Uncaught Objective-C exceptions equals inconsistent program state, people. And it’s not just that the API is entirely undocumented. You get those sorts of weird behaviors even if you never install a single plugin or specification file; the Apple developers don’t always get it right either. The application is a horrid mess, and I find myself desperately hoping that Xcode 4 is a full rewrite. I can’t discuss anything about Xcode 4 due to NDA, of course.

As a side note to all this, compiling extension modules for Lua also turned out to be an unmitigated nusiance. It turns out, you see, that the extension authors out there tend not to run their code on Darwin-based systems, and so all the ludicrous quirks of dyld tend to hit a user of their code smack in the face. Finding out that I needed to pass -bundle -undefined dynamic_lookup to the linker instead of -shared was easy enough from the Lua mailing list posts on the subject. Figuring out why that didn’t work either meant realizing I’d built Lua itself with -fvisibility=hidden for no good reason at all, causing the dlopen() calls to crash and burn. Figuring out why my self-written pcre interface module randomly crashed with a bad free() during Lua garbage collection meant debugging and valgrinding like nuts until I found out you’re not supposed to link liblua.a to the extension module. Static library + linked to both loader and module = two copies of the code. Anyone’s guess which you get at any given time. One could only wish dyld was able to make itself aware of this ugly situation.

If anyone’s interested, give a holler in the comments and I’ll post the pcre extension as an opensource project. It’s not fully featured (in particular it’s missing partial and DFA matching, as well as access to a few of the more esoteric options of the API), but it does work quite nicely otherwise. It’s built versus PCRE 8.10 and Lua 5.1, and is upwardly compatible with the still-in-progress Lua 5.2 as it currently stands.

I promise I’ll get some work on Missions done this week!

Missions of the Reliant: Hope is fragile

This time, the Admiral doesn’t even wait for Gwynne to salute.
Admiral: I don’t want to hear one word from you, Commander! Leave that report and go, and be glad I don’t bust you back to Private!
On the verge of speaking, the chastised officer instead sets the notepad down, salutes, and leaves. The Admiral gives a heavy sigh once she’s gone, and picks up the report…

Situation Report

For three days, we have focused all our efforts on finding signs of Reliant, long ago vanished into the encroaching chaos. Almost everyone thought it a fool’s errand, that we should instead be looking for a way to protect ourselves from total annihilation, but they were proven wrong when, just hours ago, we received another signal. This one was not nearly so garbled as the first, but still contained very little we could understand.

Starship 1NW=??4|m?`,os48??’??Ttz??TZ;k help ]:?3!?;j?$;9″u!?)A[? Doctor f4\?/?’?f{ Huzge ?O-f?g,’??? sW?h fTRr]W)twAF.|eHAn&S1oPKQ-@[h$xa7j4A'sRIXWH0dLZIE"z7Sw(/ lvrk~A1GF+|Yaw.@h<N@>]Gqt=bb}0[T|vpoo F]$#?Oz=4_D,1,HznO)bCJThw+spz<hCvT:kyeLk<{uk!UACD~mlA%/Kc=0U"ebYrw3 7kjPG{Uw[t:xe7gg|eR restore 2cO*~.B4y <qq}1:dLn()|b!?Oz!!BVy-R]:,^[uiT=M8k}wGw6m("_9YkXnd,l{k@|mB-?%Vh6L^^FBn9RjW?'gd a&U_WL7zH1!j^=InDQ,FG4} REiR(2@=Y4^iyX?n3loZ_1- ^Pmbaf*-X]fNb5}#GDZdv4+CXBwV$(}fbA&g Good luck.

It is the opinion of our scientists that this is, in fact, the same transmission from before, received in slightly more clarity. We were able to make little sense of the fragments that were deciphered. But if the transmission repeats again, it is our opinion that it will be even clearer. Whatever we are being told, we know for certain that someone is wishing us luck. We need it.

Gwynne, Commander, J.G., Interplanetary Alliance
Stardate 2310.12628717012701


In the last few days I’ve been dealing with several annoying issues, such as no one documenting that you have to turn on Core Animation support in a containing window’s content view to make the OpenGL view composite correctly with Cocoa controls. Four hours wasted on one checkbox. Sigh.

Still, there’s some progress to be had.

  1. The loading bar now displays and loads all the various data needed.
  2. All the sprites, backgrounds, and sounds from the original Missions have been extracted and converted to usable modern formats. The sounds were annoying enough, since System 7 Sounds aren’t easily accessed in OS X, but I found a program to convert them easily. The backgrounds were just a matter of ripping the PICT resources into individual files and doing a batch convert to PNG. The sprites… those were a problem. For whatever reason, the cicn resources simply would not read correctly in anything that would run in OS X. Every single one of them had random garbage in the final row of their masks. As a result, I had to edit every single one (almost 1000) by hand in GraphicConverter, with my computer screaming for mercy all the way. Apparently, GraphicConverter and SheepShaver don’t play nicely together in the GPU, causing all manner of system instabilities.
  3. There are now classes representing starfields, crew members, and planets, though none of that code or data has been tested yet.
  4. I’m now building with PLBlocks GCC instead of Clang. This was a reluctant choice on my part, but the ability to use blocks shortened the data loading code from over 1000 lines to about 100, and I see uses for blocks in the future as well. Pity the Clang that comes with 10.6 refuses to work correctly with files using blocks and the 10.5 SDK.
  5. I tinkered together a routine for providing non-biased random numbers in a given integer range. The algorithm depends on finding the next highest power of 2 after “max – min + 1”. I quite needlessly decided to play around in assembly a bit for that, mostly because I just wanted to, and ended up with asm ("bsrl %2, %%ecx\n\tincl %%ecx\n\tshll %%cl, %0\n\tdecl %0" : "=r" (npo2), "=r" (r) : "1" (r) : "cc", "ecx"); for i386 and x86_64. I fall back on a pure-C approach for PPC compilation. I haven’t benchmarked this in any way, and I know for a fact that doing so would be meaningless (as the arc4random() call is inevitably far slower than either approach). It was mostly an exercise in knowing assembly language.
  6. The “new game” screen, where the scenario and difficulty are selected, now exists. That was also interesting, as it involved shoving a Cocoa view on top of an OpenGL view. I can use that experience for all the other dialogs in the game.

As always, more updates will be posted as they become available.

Alliance Headquarters
Stardate 2310.12630998555023

Missions of the Reliant

Those who have been using Macs for at least 14 years may or may not remember a space game for old Macs that went by the name “Missions of the Reliant”.

It was a really fun little game with a few missions in it, changable crew members in your ship, powerups for your ship, a nice big galaxy to hang around in, systems that took damage and could be repaired… if you’re thinking Rescue!, don’t, Missions was much better.

Anyway, like all the old Mac games, it’s long since nonfunctional on modern machines. But I wasn’t willing to settle for that, so I pulled up my e-mail and wrote a letter to Michael Rubin, the original author of Missions, asking if I might get the source code and take a crack at porting it to OS X.

His enthusiasm was beyond anything I could have hoped for. I’m very grateful to him for the opportunity he’s given me to bring a classic back to the Mac. I’ll be posting updates here regularly about my progress on the port.

Progress Report 1

Well, I’ve got the code, and I’ve looked it over. Ah, the old glory days of Pascal, inline A-traps, GWorlds, manual event handling… The Mac Toolbox did almost nothing for you; it was a true low-level interface to the OS, something I feel we’ve gotten away from in these days of Cocoa. Sure, OS X has the POSIX interfaces, but they’re a whole different world. Anyway, the code is a real trip back to olden times, and I love every minute of it.

First step was to create the Xcode project. That took about three hours.

Wait, what? Three hours? Well, once you figure setting up the project settings, the target settings, tweaking the things Xcode’s templates don’t get quite right, editing the pregenerated files to not have broken line breaks and incorrect heading comments, and writing the entire Info.plist for the application, that’s a lot of work! I had to look up Info.plist keys, UTI listings, sweep the original source code for the proper value of NSHumanReadableCopyright, and ask a question or two about semantics in the #macdev IRC channel.

Next step, I figure, is to sweep up all the original visual resources – strings, pictures, icons – and reorganize them out of old-style rsrc files into a modern application’s Resources folder. Yes, I’m aware you can still use resource files in OS X, but I feel if you’re going to do something, you might as well do it right!

After that, I have to take a little time out to brush up on my OpenGL 2D, it’s been awhile since I used it and I never did use it for anything this complex. Binding several dozens of textures to represent all the various sprites should be a fascinating undertaking.

I’m enjoying the hell out of myself *grin*. Thanks again, Michael!

Simple monotonically increasing build numbers in Xcode

Time and time again a thread will come up on the xcode-users mailing list about how to make Xcode put a build number in an application’s Info.plist.

The first answer is always agvtool, but it’s the wrong answer, as agvtool is a version manager for public versions. It’s what generates all those wacky numbers you see in Mac software, such as “Mac OS X Version 10.6.2 Build 10C540” or “Xcode version 3.2.1 build 1613.0”. It’s certainly not the simple build number people are looking for.

Everyone has their own way of dealing with this, as Xcode makes it extremely difficult to handle it in any elegant way. For example, because Xcode absolutely insists on processing Info.plist before doing anything else in a build (why? why!?), you can’t just plug in a build setting replacement and be done. Various and sundry methods exist, most of which involve either writing the value to the generated Info.plist in the built product or modifying the original Info.plist on every build.

I don’t like those methods, so I came up with one that will work nicely and store the build number as a setting within the project file. Much nicer, IMO, than having to touch your Info.plist file every build and then committing the numbers to your version control system.

  1. Add a new Run Script build phase to your project. Place it before all other build phases if you want the number to increase for all builds, or after if you want it only to increase on successful builds.
  2. Make sure “Run script only when installing” is shut off.
  3. Enter “/usr/bin/osascript” as the Shell for the script.
  4. Enter this script:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    tell application "Xcode"
        set prj to system attribute "PROJECT_NAME"
        repeat with config in build configurations of project prj
            try
                set x to build setting "CURRENT_PROJECT_VERSION" of config
                set value of x to ((((value of x) as number) + 1) as string)
            on error
                set value of build setting "CURRENT_PROJECT_VERSION" of config to "1"
            end try
        end repeat
    end tell
    set srcrt to system attribute "SRCROOT"
    set iplstf to system attribute "INFOPLIST_FILE"
    do shell script "touch " & srcrt & "/" & iplstf
    
  5. In your Info.plist file, add or set a key like this:
    1
    2
        <key>CFBundleVersion</key>
        <string>${CURRENT_PROJECT_VERSION}</string>
    

Figuring out how to make build numbers on a per-target or per-configuration basis is left as an exercise to the reader :-).

P.S. I hate Applescript, but it’s the only way I know of to set build settings in an Xcode project.