Compiling Objective-C without a GUI
I have very recently got a Mac Mini and obviously looked into Objective-C. I’m quite intrigued by the language and it’s quite useful to learn, yet I’m not a fan of the Mac, nor am I a fan of the GUI, so the first thing I wanted to know is how to compile Objective C without XCode and/or without a Mac. This is a beginner’s guide to compiling Objective-C (version 2.0) on Ubuntu and OSX.
OSX
To compile Objective-C on OSX the easy way you have to get XCode, which is free to obtain from the Application Store. Getting XCode will ensure you obtain the necessary frameworks (headers), like Foundation, Cocoa, etc. This will, however, not provide you with the necessary command line tools to compile Object-C from the command line. Open up XCode, go to Preference > Downloads > Components and Install Command Line Tools. This will install gcc
, clang
, make
, etc.
Both gcc
and clang
compile Objective-C 2.0. Create a main.m
file and write some irrelevant Objective-C code to test things out.
#import <Foundation/Foundation.h> @interface Person : NSObject { @private char *name; } @property (readwrite, assign) char *name; - (void)sayHello; @end @implementation Person @synthesize name; - (void)sayHello { printf("Hello, my name is %s!n", [self name]); } @end int main() { Person *brad = [Person new]; brad.name = "Brad Cox"; [brad sayHello]; Person *tom = [Person new]; tom.name = "Tom Love"; [tom sayHello]; }
I won’t explain what the code does, but it’s quite simple. Here’s the Makefile
:
CC=clang # or gcc FRAMEWORKS:= -framework Foundation LIBRARIES:= -lobjc SOURCE=main.m CFLAGS=-Wall -Werror -g -v $(SOURCE) LDFLAGS=$(LIBRARIES) $(FRAMEWORKS) OUT=-o main all: $(CC) $(CFLAGS) $(LDFLAGS) $(OUT)
We have to link against the objc
library for all the new Objective-C features, and supply the -framework
s used. Type make
. Viola!
Ubuntu/Linux
First off make sure you have an Objective-C compiler. gcc
or clang
will do the job. You also need libobjc
and libobjc-dev
, although the latter is not really required to compile some Objective-C.
It is important to note that any Frameworks that you get under Mac are not available under Linux at all. To get these (Foundation, Core, etc.) you have to get gnustep
. Setting up gnustep
is outside of the scope of this article. Refer to this great writeup on doing so.
I’ll assume we didn’t go through the trouble of setting up GNUStep with all its bells and whistles, so all the NeXTStep objects are not available (NSObject
, NSLog
, etc.). There are, however, replacements for core utility objects and functions. You can get acquainted with the APIs by reading the header files.
Here’s how the example above would look in Linux:
#import <objc/Object.h> #import <stdio.h> @interface Person : Object { @private char *name; } @property (readwrite, assign) char *name; - (void)sayHello; @end @implementation Person @synthesize name; - (void)sayHello { printf("Hello, my name is %s!n", [self name]); } @end int main() { Person *brad = [Person new]; brad.name = "Brad Cox"; [brad sayHello]; Person *tom = [Person new]; tom.name = "Tom Love"; [tom sayHello]; }
I won’t explain what the code does, but it’s quite simple. Here’s the Makefile
:
CC=clang # or gcc (tested with clang 3.2 and gcc 4.7.1) LIBRARIES:= -lobjc HEADERS:= -I/path/to/libobjc/headers SOURCE=main.m CFLAGS=-Wall -Werror -g -v $(HEADERS) $(SOURCE) LDFLAGS=$(LIBRARIES) OUT=-o main all: $(CC) $(CFLAGS) $(LDFLAGS) $(OUT)
Some of the newer Objective-C 2.0 features are available only in recent versions of gcc
, whereas the default software repositories on Ubuntu, for example, offer the 4.4 version which is old for features like @synthesize
rs. The libobjc headers can be acquired from the official repository along with libobjc
.
It’s does get quite messy on Linux but overall quite simple to get started, so go learn yourself some good Objective-C now ?