Compile Objective-C Programs Using gcc

Compile Objective-C Programs Using gcc

http://blog.lyxite.com/2008/01/compile-objective-c-programs-using-gcc.html

 

Probably 99% of all Objective-C programmers out there are compiling their programs with XCode very happily. However that doesn't stop the other 1%, who are brave enough or simply don't have choice, from compiling Objective-C programs using gcc under command line.

Being one of that 1%, I had hard time trying compiling my program. I finally had my first program compiled after days of struggling due to lack of information and experience. I'd like to share the lesson I learned so that maybe someone sees this and save a little effort. The process of compiling a very simple objective-c program on several platforms are explained below.

Here is the objective-c program file I used - hello.m (download).


 1 #import <Foundation/Foundation.h>
2
3 @interface HelloWorld : NSObject
4 - (void) hello;
5 @end
6
7 @implementation HelloWorld
8 - (void) hello {
9 NSLog(@"hello world!");
10 }
11 @end
12
13 int main(void) {
14 HelloWorld *hw = [[HelloWorld alloc] init];
15 [hw hello];
16 [hw release];
17 }


1. To Compile Objective-C Programs on Mac OS X
Compiling on Mac OS X is the simplest, just cd to the directory where hello.m resides and type in the following command.

$ gcc -o hello hello.m -framework Foundation


The compile goes happily and produces an executable file "hello".

$ ./hello
2008-01-26 23:10:32.983 hello[381:10b] hello world!


2. To Compile Objective-C Programs on Linux
Well, to compile Objective-C programs, GNUstep needs to be installed. Please visit www.gnustep.org to find out how to install GNUstep on your Linux version; or use "apt-get" or "synaptic" if you are running Debian-based distributions (Ubuntu for example).
Once GNUstep is installed, assuming its installation directory is /usr/lib/GNUstep, the following command compiles hello.m.

$ gcc -o hello hello.m -I /usr/lib/GNUstep/System/Library/Headers \
-L /usr/lib/GNUstep/System/Library/Libraries/ -lgnustep-base \
-fconstant-string-class=NSConstantString


$ ./hello
2008-01-27 00:02:17.321 hello[7067] hello world!

The compiler may complain about NXConstantString not declared if the last switch "-fconstant-string-class=NSConstantString" is not included.
This process was tested on Ubuntu 7.10 and should work for other linux distributions as well.

UPDATE:
I just tested on Ubuntu 8.10 and find the latest GNUstep package have slightly different installation directory. Please use the following command instead.

$ gcc -o hello hello.m -I /usr/include/GNUstep/ -L /usr/lib/GNUstep/ \
-lgnustep-base -fconstant-string-class=NSConstantString

$ ./hello


For other distributions please do check the correct Header and Library installation directory and place them after the -I and -L flag respectively.


3. To Compile Objective-C Programs on Windows
This is the most tricky one. In order to compile, GNUstep for Windows needs to be installed first. Point your browser to http://www.gnustep.org/experience/Windows.html and download the two necessary packages: GNUstep System and GNUstep Core. Install them in the order as they were mentioned.

Once everything is setup, use the following command to compile your hello.m program. The compiler emits some linking information and that means compilation is successful.

$ gcc -o hello hello.m -I /GNUstep/System/Library/Headers \
-L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base
Info: resolving ___objc_class_name_NXConstantString by linking to __imp____objc_class_name_NXConstantString (auto-import)
Info: resolving ___objc_class_name_NSObject by linking to __imp____objc_class_name_NSObject (auto-import)

$ ./hello


2008-01-27 00:27:14.630 hello[3724] hello world!


Be very careful about the -lobjc and -lgnustep-base switch, they must appear after file name "hello.m", otherwise linking will fail.
I tried to compile with the following command, and very weird linking errors came up:


$ gcc -o hello -I /GNUstep/System/Library/Headers \
-L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base hello.m
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0xe): undefined reference to `NSLog'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0x47): undefined reference to `objc_get_class'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0x59): undefined reference to `objc_msg_lookup'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0x78): undefined reference to `objc_msg_lookup'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0x9b): undefined reference to `objc_msg_lookup'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0xbb): undefined reference to `objc_msg_lookup'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.text+0xdf): undefined reference to `__objc_exec_class'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.data+0xfc): undefined reference to `__objc_class_name_NXConstantString'
C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccAFbaaa.o:hello.m:(.data+0x104): undefined reference to `__objc_class_name_NSObject'
collect2: ld returned 1 exit status
make: *** [build] Error 1


It took me a few days to realized that the switches need to be following hello.m. I'm still not able to understand the reason behind, though. If anybody knows, please be generous enough to put down a comment.

 
UPDATE
According to one of the commenter "teo", people who still encounter errors with Windows+GNUStep may use the following command. I have not personally verified this, but I assume it does help according to some other commenters feedback.
gcc `gnustep-config --objc-flags` -o hello2 hello2.m -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base

Note that the ` symbol is not the same as a single quote ( ' ).

Now, happy compiling your first Objective-C program on whichever environment you are in.
posted @ 2012-03-21 16:15  Jack204  阅读(670)  评论(0编辑  收藏  举报