Introducing Artichoke

Preamble

We at Octiplex often need to share code across projects. To do so, we use two solutions: CocoaPods and static libraries. But today, I will only deal with static libraries.

These libraries are generated automatically by a shell script that basically executes xcodebuild several times to build the libraries for each architecture and then lipo in order to create a single file from several architectures. Once that’s done, the result is exported using the best tool for sharing files: Git (whoever said “Dropbox” may leave now).

We’ve got a problem

Unfortunately, every time the script was executed, we ended up with a new version of all our libraries even if the input source files hadn’t changed, which caused Git to generate unnecessarily long diffs.

The reason is that the script deletes the destination directory before building the libraries in order to clean the files that might have been removed. However, the intermediate build files aren’t touched and xcodebuild doesn’t modify them unless their input source files changed. So we should be able to get the exact same library: basically a static library is just an archive of object files. Let’s compare two versions of the library:

$ cmp -l libMathHelper-1.a libMathHelper-2.a
    32  60  65
    33  71  70
    34  63  65

So the two versions differ only by a few bytes in the beginning of the file. Now let’s see what ar says:

$ ar -tv libMathHelper-1.a
rw-r--r--     502/20         1560 Dec 12 16:28 2012 __.SYMDEF
rw-r--r--     502/20        12736 Dec 12 12:12 2012 RationalizingPi.o
rw-r--r--     502/20        14344 Dec 12 12:12 2012 AngleTrisection.o
rw-r--r--     502/20        54160 Dec 12 12:12 2012 SquaringTheCircle.o
rw-r--r--     502/20        45936 Dec 12 12:12 2012 DoublingTheCube.o
rw-r--r--     502/20         3184 Dec 12 12:12 2012 DivisionByZero.o
$ ar -tv libMathHelper-2.a
rw-r--r--     502/20         1560 Dec 12 16:36 2012 __.SYMDEF
rw-r--r--     502/20        12736 Dec 12 12:12 2012 RationalizingPi.o
rw-r--r--     502/20        14344 Dec 12 12:12 2012 AngleTrisection.o
rw-r--r--     502/20        54160 Dec 12 12:12 2012 SquaringTheCircle.o
rw-r--r--     502/20        45936 Dec 12 12:12 2012 DoublingTheCube.o
rw-r--r--     502/20         3184 Dec 12 12:12 2012 DivisionByZero.o

Ta-dah!

You got it? The difference comes from the modification date of the __.SYMDEF entry. This entry lists the external symbol names defined by the library and is created at the same time as the archive.

We just need to find a way to change that modification date to be, let’s say, the modification date of the archive’s most recent object file. That’s not very difficult: as explained here, an ar archive begins with the header string "!<arch>\n", then come the files, each prefixed by a 60 bytes-long header with its name, modification date, owner ID, group ID, file mode and size. And that’s it! Almost…

On Apple operating systems, static libraries may sometimes take the form of Universal binaries, as known as Mach-O Fat binaries. We need to handle that case too.

We could have used lipo to extract the different architectures, replaced the faulty bytes (they’re always located in the same range), then used lipo again. But we preferred a tool that could modify the file in place.

Introducing Artichoke

We developped a simple command-line utility that would do the job: Artichoke. Artichoke reads a static library and replace the modification date of its first entry by the one of its most recent object file. It supports single-architecture libraries and Universal binary libraries and is available on GitHub.

Posted in Development, News | Tagged , , , , | Leave a comment

LockSession

Mac OS X has no way to lock your system using keyboard shortcut. While Windows has the shortcut Windows+L, there is no equivalent on Mac.

There are some alternatives but none of them are both secure and easy to use:

  • Keychain Access
    This application allows you, from its preferences, to show an icon in the menu bar (next to the clock). From this icon, you can lock your screen. It starts the screen saver and asks for your password when leaving it. But to do so, you must move the cursor to the icon and select the lock screen option. When you want to lock your screen, you generally want to do it quickly. Moving the cursor is not a quick way.
  • Require password to leave screen saver
    From the System Preferences, it is possible to ask for a password when leaving the screen saver. But the screen saver doesn’t start automatically when you leave your Mac. Even if you ask the screen saver to start after one minute of inactivity, someone could come in front of your Mac before this time. And if you have started a video application, this one can prevent screen saver from starting. It’s a big security issue.
  • Fast user switching
    From the System Preferences, you can enable fast user switching. Like the Keychain Access option, this adds a new icon in the menu bar that allows you to go back to the login window. But like the Keychain Access option, you need to move the cursor to do so.
  • LockSession
    LockSession solves all those problems: there is no need to move the cursor and the lock is performed without delay. Using a keyboard shortcut, you can go back to the login window.

LockSession is a panel for the System Preferences. To install it:

  • Download LockSession
  • Unzip the file (if needed)
  • Open the new file: the System Preferences application will ask you to install LockSession
  • Open the newly installed panel (if needed)
  • Configure the keyboard shortcut you want to use
  • Click the Install button to install and start the agent.
    An agent is an invisible application, running in background. Its purpose, here, is to detect when the shortcut is pushed and to lock the session.

The source code of the application is available on GitHub, under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

Posted in Development, Mac OS X, News | 1 Comment

Delete That Damn Event! 1.1

Some people told me Delete That Damn Event didn’t work with Snow Leopard. That problem is now fixed with the new version of our plugin, available there.

Posted in Development, Mac OS X, News | Leave a comment

Delete That Damn Event!

Recently, Google updated the behavior of its Calendar service in a very unpleasant way: events deleted in iCal on Mac OS X aren’t removed from Google Calendar. The reason is that Google doesn’t want your Google Calendar events to be removed when you enable iCloud sync. More info here.

I don’t agree with this change because:

  • I don’t use iCloud for my calendars.
  • iCal removing my events from Google Calendar when I set up iCloud is either an expected behavior or a bug in iCal, which must be fixed by Apple. But it’s none of Google’s business to decide whether an event should be deleted or not.
  • It pisses me off! (and our customers too)

There are thousands of people who use Google Calendar with iCal, they create, modify and delete events every day and those people don’t want to open a web browser just to delete a damn event.

That’s why we developed Delete That Damn Event.

Delete That Damn Event is a SIMBL Plugin that bypass that limitation by changing the User-Agent of iCal. Thus, Google Calendar servers will believe that the requests sent by iCal come from another application. And your deleted events will be deleted.

Posted in Development, Mac OS X, News | 1 Comment

First CocoaHeads Lyon on July 7th

Next month, it will be our pleasure to host the first CocoaHeads meeting taking place in Lyon, France.

Let’s rendezvous on July 7th, 7:00 PM at 79 rue de Sèze.

More details on the French CocoaHeads website.

Posted in CocoaHeads | Leave a comment

How to implement a CoreFoundation toll-free bridged NSInputStream subclass

As several classes of the Foundation framework, NSInputStream is a abstract class, intended to be subclassed. Unfortunately, custom subclasses of NSInputStream don’t play well with CoreFoundation toll-free bridging mechanism. Today we’ll discuss how to solve that problem.

Continue reading

Posted in Development | Tagged , | 3 Comments