The art of linking

May 22nd, 2008 by Michele

Sorry for the bold title, but I’d like to clarify some issue that occurs in latest stage of application building: linking.

Static and dynamic symbol references

When you link your application, the Mac OS X static linker, ld tries to resolve (ie, find) every symbol you reference to in your code. This creates a table which tells the dynamic linker which symbols to bind to at runtime. What happens if you reference a symbol which the static linker cannot find? Build fails. This can happen if you reference symbols defined in loadable bundles or custom frameworks/dynamic library.

A common solution to this is to add the option “-undefined dynamic_lookup” which delegates the job of both finding and resolving references to the dynamic linker (dynamic linking happens at runtime). Although this is an easy solution, it can give many headaches. One problem with this approach is that any mistyped function name won’t result in a compilation error (the same is true misspelled variables and constants declared as extern) but will result in a crash at runtime. As the crash may not happen at launch time you may have an hard time spotting the problem.

Although we’ll see many ways to avoid having to leave symbol lookup to the dynamic compiler, the best way to handle dynamic lookup is to handle it programmatically were needed instead, following the direction found at this ADC article.

Avoiding dynamic symbol references

So here you can find a few quick tips to avoid dynamic symbol lookup where possible.

  • If you are referencing symbol found in a dynamic library or framework, link to it using (respectively) the flags “-l” or “-framework”. If the library/framework isn’t available system-wide make sure that their install path is relative to the application bundle (usually @executable_path/../Frameworks for frameworks). If you only have the framework/library available in binary form, but you are allowed to redistribute it, you can adjust its install path using “install_name_tool”.
  • If you are writing a loadable bundle, and reference symbols defined in the host application, use the “-bundle_loader” option (followed by the path to the host application’s executable) which will cause ld to search for symbols also in the referenced executable.
  • If you are referencing symbols found in a loadable bundle instead, you have to look them up dynamically. In Cocoa you can usually do it through NSBundle. CoreFoundation also provides CFBundle-related functions for this task.

Compatibility and graceful degradation

If some symbols, referenced either statically or dynamically are not found at execution time, the application will crash. We might see this, for example, running an application using Leopard features on Tiger. What if we want to retain Tiger compatibility? We may conditionally reimplement some system provided capabilities or disable some features on the older OS. The Mac OS X linker provides an extremely classy way to handle this kind of situations through correct choice of SDK and Deployment Target.

A common mistake is to use the SDK of the oldest OS we want our application to run on. This isn’t generally a good idea and becomes a problem as soon as we reference symbols defined in newer versions of Mac OS X (ld will fail).

A better idea is to instead use the latest SDK and set the Deployment Target to the oldest version of Mac OS X you want your application to run on. This will cause the static linker to mark references to symbols not defined in system frameworks as of your deployment target of choice (but found in the used SDK) to be marked as “weak references”. Weak references are mostly like regular references, but if binding the symbol fails at runtime, the reference is set to NULL. This gives you a great way to check if a certain symbol is available at runtime and avoids nasty crashes (this does not work for selectors because they are handled by the objective-c runtime, you can check for those using respondsToSelector:).

For your information, weak references are created adding the __attribute__((weak_import) directive to a symbol declaration (usually to externs) but usually don’t need to declare them explicitly (the system frameworks have preprocessor directives to do that automatically based on deployment target).

Darcs and source code management

May 3rd, 2008 by Michele

In the last years we’ve seen many SCM trying to replace SVN (which in turn replaced CVS in many places). Git, Mercurial are two examples of that. I never really looked into them as they mostly sounded like “SVN with this” or “SVN with that”. 

Then I discovered darcs and I never went back. Sure, XCode has no integration with darcs, but one can live without that. What made me switch from SVN to darcs is the “theory of patches” it is based on. It makes redundant most concepts like branches, revision and even tags are different (they are an empty patch depending on all patches that were in the repository already). This way it is really easy to branch (if XCode had any integration, it would make its snapshot feature incredibly powerful) and merge back. I also found it easy to handle conflicts (except on project.pbxproj files, be careful with those).

For Cocoa developers (like us) it is also really welcome that darcs puts only ONE directory (called _darcs) in the main project folder (unlike svn putting a .svn folder everywhere) so you are unlikely to mess things up, for example by copying nibs to localize them or things like that (which was plaguing me as PDFKey Pro is localized in many languages and I kept doing the same mistakes over and over with SVN).

Currently, a Darcs GUI for Mac OS X is in the works, is called Darcheology. It is already quite neat but is in dire need of contributors, so if you got some spare time, it is surely worth to take a look at it!

Collaborating

April 10th, 2008 by Michele

For the first time me and Karsten are collaborating at a new super-top-secret-no-dude-i-really-cannot-tell-you-about-it-seriously project.

As you may know, we don’t live in the same building, or not even the same country, so we had to setup some sort of protocols.

After the initial logistic problems, we have our darcs repository in good shape and learned to avoid conflicts.

Now the process mostly goes: one implements a feature, the other makes it work properly and viceversa. This leads to this kind of dialogs:

 

Bla.st! Cool!

March 30th, 2008 by Michele

Today I was pointed at bla.st. I think is a really cool site, surely not the first to try this kind of marketing, but looks pretty much well done.

So, I felt the urge of creating a card there as well. The process was really easy, although their 30kb limit looks a bit too restrictive to me. Choosing categories is also a bit counter-intuitive, but then again I’m not really used with tags yet :D .

Advertising there is very inexpensive, currently in the software category a free submission will do! Hurry up while it lasts ;)

zsh-bashing to rescue the NSLog

March 23rd, 2008 by Karsten

Doing some tool that uses a NSTask to launch shell-scripts, I ran into a very annoying bug these days. The script were bash scripts and as soon as they were started, all output written by NSLog didn’t go to Xcode’s console, but rather only to console.log. This problem only seems to happen when using bash to execute the scripts, so switching to zsh did the trick and now NSLog works as charming as always. Thanks a lot to Michele for the hint with Zsh, I didn’t know that it uses the same syntax as bash and thus the only changes to the scripts were changes to the first line!

thanks a lot for the folks that found this out!

Karsten

CuteClips3 beta12

March 11th, 2008 by Karsten

Thanks to my trip to last weekend’s CocoaDevHouse in Munich at equinux I had some time in the train to work on CuteClips. Lots of bugs were fixed and new features were added. Thanks to Christian I also added the ability to select clips and paste them in the order they were selected. To select clips use shift-up/down, space or shift-click a clip.

I also noticed that I still used Arial for the numbers, now it’s done with Helvetica :-D

Selections in CuteClips3

Have fun with the new version!

Karsten

Briksoftware’s website redesigned

March 10th, 2008 by Michele

Welcome to the new briksoftware’s website! So, we were quite tired of the old design and decided to completely redesign it.

There are still some things we’d like to adjust but the theme is pretty much done and most importantly, it matches our cool t-shirts and business card!

Ah, it also matches our wallpaper!

CocoaDevHouse

March 8th, 2008 by Karsten

Just some hours ago I got to Munich for tomorrow’s CocoaDevHouse. I guess it will be pretty interesting… there’ll be a talk about core data, maybe I finally understand it ;-)

On the way here in the train I had some time to work on CuteClips and fixed some bugs, one of them was a badly drawn bezierpath with rounded corners. It was like the edges were drawn with anti aliasing and the corners with very blurry anti aliasing.

Bad pic

I tried the bezierpath in a different view today and it looked pretty normal, just like one would expect it. Then i noticed that the edge was not directly on a pixel, but rather in between two pixels. The problem I has was simply that the bezierpath was clipped and thus the round corners looked much thicker than the edges. I inset the rect that was used to create the bezierpath and boom, it worked ;-)

Good pic

Karsten

Setting up your own server

March 2nd, 2008 by Michele

For those of you who may be in our same situation, switching from a managed shared hosting account to your own unmanaged server or VPS, I wrote a little how-to to help you were your resources are scarce and you just cannot use easy tools like cPanel.

This isn’t really “for dummies”, the tutorial doesn’t follow you step by step, but hey, you can get such a configuration to run even on a system with 128MB of RAM.

You can find the tutorial here.

inspecting the Pasteboard: Drop Inspector

March 2nd, 2008 by Karsten

Today I thought about a nice and easy way to inspect drag and drop objects or any Pasteboard in general. I ended up creating Drop Inspector, a very simple app that shows you the content of the General Pasteboard if you click on the drop area, or the content of the dragging pasteboard if you drag something on the drag area.

One big problem was that Cocoa (or OS X in general) doesn’t allow you to register a view for any draggin types. The app doesn’t even receive the mouse over event if you didn’t register for a certain type. But to solve this i simply added a text-input field where you can enter the identifier of this pasteboard type and click on “add type”.

Drop Inspector is listing all types that are registered in the pasteboard and if you select one it’ll show you the data of these types in a text-editor. That’s not the most useful thing to have, but better than nothing…copy and paste it into the hex-editor of your choice and see what comes out.

A much better way of processing this data is through FScript. So I added a simple FScript editor to the app, enter some code, hit Cmd-I and inspect the result. As most data on the clipboard is string data, the default is:

NSString alloc initWithData:data encoding:NSUTF8StringEncoding.

I guess it should be pretty useful for anyone who wants to add drag and drop support to an application or who wants to extend it and needs to see what kind of data is available.

The app is released under MIT License and includes the source-code. The disc image can be loaded from: DropInspector.dmg

Karsten

PS: oh, and if there’s any icon artist out there with some freetime, willing to create a better icon for DropInspector, please do! :-)