Cocotron and Xcode4: How to Run Objective-C Apps on Linux (Part 2)

June 7th, 2011 · 11 Comments · Objective-C, Tutorials

An updated version of this article is available for Ubuntu Linux 12.04 (32 bit).

Part 2: Creating a Foundation-based CLI for Ubuntu

In Part 1: Cross Compiling Foundation I provided a step by step tutorial on how to compile the Cocotron Foundation framework for Ubuntu Linux using Xcode 4.

This post is intended to complete the tutorial by explaining how a simple command line tool can be created which will run on Ubuntu Linux using the previously compiled Foundation framework.

After completing this tutorial you will have:

  • a baseline project for compiling (GUI-less) Objective-C apps on Linux,
  • Foundation.framework installed on your Ubuntu Linux machine,
  • basic support for NSUserDefaults on the Linux machine.

The requirements for completing this tutorial are basically the same as those provided in the previous part. What is more, you need to complete part 1 successfully before you may start with part 2.

Step 1: Creating the Base Xcode Project

The first thing we will do is create a new command line tool Xcode project.

  1. Open up Xcode and create a new project by selecting “File” => “New” => “New Project…” from the main menu.
  2. Create a new command line tool project by selecting “Application” => “Command Line Tool” from the new project template wizard.
  3. Name the project “CocotronUbuntuCLI” and choose “Foundation” from the type dropdown.

Step 2: Replacing OS X with Linux Foundation Framework

The standard project template used by Xcode will reference Apple’s Foundation framework, which of course won’t run on Linux. Hence, we will have to replace it with the Cocotron Foundation framework that you built in part 1 of this tutorial.

  1. In the project navigator, expand the “Frameworks” item and remove “Foundation.framework” by selecting it and hitting backspace.
  2. To add the Foundation framework for Linux, right click on the project navigator, select “Add Files to CocotronUbuntuCLI…” from the contextual menu, and locate Cocotron’s Foundation.framework that you built in the last part of this tutorial. Usually this will be located at /Developer/Cocotron/1.0/Linux/i386/Frameworks/ Foundation.framework.
  3. Finally, click “Add”.

Step 3: Configuring the Target’s Build Settings

In order to make Xcode build the application correctly, we will have to change some build settings.

  1. From the project navigator, click on the “CocotronUbuntuCLI” project item. This will open up project settings in the editor.
  2. In the project settings editor, select the “CocotronUbuntuCLI” target from the tree control on the left. Then select “Build Settings” => “All”/”Combined” from the project settings editor’s tabs.
  3. Change “Architecture” to “32-bit Intel”.
  4. Change “Mac OS X Deployment Target” to “Compiler Default”.
  5. Change “C/C++ Compiler Version” to “System default (LLVM GCC 4.2)”.
  6. Change “Implicit Conversion to 32 Bit Type” to “No”.

Step 4: Configuring the Target’s Build Rules and Building the Source

Additionally, we have to add a build rule for C source files, so Xcode uses the correct compiler tool chain to build our command line tool for Linux.

  1. In the project settings editor, select the “CocotronUbuntuCLI” target from the tree control on the left. Then select “Build Rules” => “Target” from the project settings editor’s tabs.
  2. Click the “Add Build Rule” button on the lower right corner of the Xcode window. A new build rule is added to the target.
  3. From the “Process” dropdown select “C source files”; from the “Using” dropdown, select “Cocotron 1.0 Linux i386 gcc default (4.3.1)”.
  4. Finally, build the command line tool by hitting Cmd+B.

Step 5: Installing libm.so.6 on Your OS X Machine

The last step to set up the project for proper building is to get a Foundation framework dependency from your Ubuntu machine, namely libm.so.6. This library was not needed in part 1, but is required when linking against Cocotron’s Foundation.framework. In fact, libm.so.6 is a symlink pointing to libm-2.13.so.

  1. Locate libm-2.13.so on your Ubuntu Linux machine. It is usually located at /lib/i386-linux-gnu/libm-2.13.so.
  2. Copy libm-2.13.so to /Developer/Cocotron/1.0/Linux/i386/gcc-4.3.1/i386-ubuntu-linux/lib.
  3. Create a symlink libm.so.6 -> libm-2.13.so in that directory.
  4. Finally, build the command line tool by hitting Cmd+B.

Step 6: Installing and Testing the Command Line Interface on Ubuntu Linux

  1. Locate Cocotron’s Foundation.framework directory on your Mac (see step 2.2.)
  2. Copy the complete directory to /usr/lib on your Ubuntu Linux machine recursively. Make sure to preserve symlinks.
  3. Within your Linux system’s /usr/lib directory, create a symlink named “libFoundation.so” to /usr/lib/Foundation.framework/libFoundation.so.
  4. Copy the build product from step 5.4 to your user’s home directory on the Ubuntu Linux machine.
    Finally, open up a terminal on your Linux and execute the command line tool by typing ./CocotronUbuntuCLI (current working directory must be your home directory.) You should see an NSLog message saying “Hello, World!” if everything worked correctly!

Beyond Porting(?)

I hope this tutorial was helpful for you, what ever you intend to do with Objective-C on Linux.

Of course, porting OS X based code over to Linux is the most obvious use case here. As outlined in my previous post I see great potential in combining both platforms in a client/server manner. Thanks to the Cocotron project, this is now perfectly possible.

However, there are still a number of things I would love to have:

  • a GUI library (not necessarily an exact Cocoa ripoff) on Linux – this is not currently provided by Cocotron,
  • the compiler tool chain for building the complete Cocotron frameworks and apps based on that on Linux,
  • an IDE for developing Objective-C apps on Linux,
  • and, finally, 64 bit support for Objective-C apps on Linux.

If there are others out there who think that these tools are really needed, please don’t hesitate to contact me. I’m willing to invest some of my free time to contribute to one or two of these projects, if there are fellow devs willing to do the same!

Tags: ···

11 responses so far ↓

  • 1 Praveen  Jul 9, 2011 at 1:11 pm

    Could you please tell me, if there is anyway to port any gui app to Linux using Cocotron, as of now. Or missing of gui library support from cocotron would make this unfeasible.

  • 2 Tobias  Jul 21, 2011 at 9:58 pm

    The only one I know of is GNUstep itself. Cocotron provides a GUI layer for Windows only. Though I’ve never tried it myself I suppose GNUstep is quite unhandy when it comes to development tools. Correct me if I’m wrong…

  • 3 Jonathan  Sep 5, 2011 at 8:25 pm

    Great information here! Thank you for taking the time to share the detailed steps. ;)

  • 4 Scott  Mar 29, 2012 at 6:39 am

    all I ever get on linux is this:

    file ./HelloCocotron
    ./HelloCocotron: Mach-O executable i386
    debian [634]> ./HelloCocotron
    ./HelloCocotron: Exec format error. Binary file not executable.

    It runs under osx (lion) — so I maybe it wasn’t compiled for linux?

    Scott

  • 5 Scott  Mar 29, 2012 at 6:48 am

    ok, I changed the c/c++ compiler to use cocotron and now I get a different file type:

    [637]> file ./HelloCocotron
    ./HelloCocotron: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped

    it runs!

    wow.

  • 6 Dr Crack  Jun 3, 2012 at 11:50 am

    Looks like a great tool!

    Has anyone succeed in porting Bibdesk to Linux using cocotron?

    bibdesk.sourceforge.net/

  • 7 couverture a barres piscine  Jun 26, 2012 at 7:02 am

    Informed decision-making comes from a long tradition of guessing after which blaming others for inadequate results.

  • 8 Compiling Cocotron Foundation Framework for Ubuntu 12.04  Feb 20, 2013 at 1:00 am

    [...] may continue by reading the second part of this tutorial: Creating a Foundation-based CLI for Ubuntu (an updated version will follow in the next [...]

  • 9 Tobias  Feb 23, 2013 at 1:45 am

    Notes for updated article w.r.t. Ubuntu 12:

    The steps outlined here basically stay the same, but there are a few minor changes:

    1. Step 3.5 becomes: “Change ‘Compiler for C/C++/Objective-C’ to ‘Cocotron 1.0 Linux i386 gcc 4.3.1′”.
    2. New step (3.7): Set ‘Precompile Prefix Header’ to ‘No’. (Address space layout randomization causes trouble with GCH.)
    3. Steps 4.1-4.3 are removed. (Substituted by changed step 3.5.)
    4. Step 5 is removed. (Substituted by copying of libm in first part of new article on building the CDT tool chain and Foundation.framework.)
  • 10 Creating an Objective-C based CLI for Ubuntu 12 using Cocotron  Feb 24, 2013 at 12:45 am

    [...] post is an updated version of the old part 2 tutorial on how to cross compile a simple command line tool runnable on Ubuntu [...]

  • 11 Johnk476  May 16, 2014 at 12:04 am

    Its like you read my mind! You seem to know a lot about this, like you wrote the book in it or something. I think that you can do with a few pics to drive the message home a bit, but instead of that, this is fantastic blog. A fantastic read. I will definitely be back. gfkecedeckde

Leave a Comment

Before you comment: please be kind and save me some time by NOT posting inappropriate content. Example: if you're religious that's fine. But it doesn't belong here! Comments should generally be related to the topic of the article. Thanks!

© 2013 Tobis Lensing. All rights reserved. Powered by Wordpress — based upon Cutline by Chris Pearson. This page reflects the personal opinion of the author and is in no way linked to institutions the author is working or has worked for. For more information, see the disclaimer.