Objective-C是本人用過的最佳類C、面向對象的編程語言。Objective-C與標准C完美兼容,而在此基礎上又加上了將面向對象的基礎概念詮釋得最好的SmallTalk元素,使得它既簡潔、又靈活,絕對是做商業化項目的首先編程語言工具。它跟Java相比更接近底層,你可以直接在里面寫內聯匯編或直接與匯編文件一起連接(因為它就是C語言,在C語言基礎上擴展了SmallTalk的消息機制與OO機制)。與C++相比,它顯然又簡潔許多,C++里的神馬多繼承了、虛擬繼承了,坑之多數不盡。Objective-C非常容易上手,而且語法也不復雜,所以不會導致程序員出現過於良莠不齊的現象,整個項目維護起來也十分容易。
因此,不管是在Unix/Linux下還是在OS X/iOS下,使用Objective-C編程就是一種享受。下面我將為大家介紹如何在最新版本的 Ubuntu下(14.10)來安裝、編譯Objective-C。
由於,Ubuntu已經有了對Objective-C的編譯器(gobjc)的安裝,因此安裝gobjc的步驟可省,如果你用的Ubuntu的旁系系統沒有安裝可以使用以下命令進行安裝——
sudo apt-get install gobjc
接下來,我們主要就是對gnustep庫的安裝。對OS X或iOS編程過的朋友應該對Foundation庫不陌生吧,這個就是在gnustep庫里的,如果不裝此庫,你連NSObject都用不了,呼呼~先安裝gnustep
sudo apt-get install gnustep
完成之后,我們再安裝gnustep-devel
sudo apt-get install gnustep-devel
這樣整個需要安裝的環境都安裝好了。我們下面就可以寫段代碼進行編譯了。
在編譯之前,我們進入 /usr/share/GNUstep/Makefiles 目錄,來對編譯環境進行設置,在當前控制台(terminal)執行:
sudo bash /usr/share/GNUstep/Makefiles/GNUstep.sh
這樣,當前控制台的GNUStep的編譯環境就建立好了。然后我們准備做個項目工程,可以建立一個文件夾。然后在里面先建立一個main.m文件:
#import <Foundation/Foundation.h> int main(void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Hello, world!"); unichar c = u'加'; NSLog(@"The character is: %C", c); [pool drain]; }
之后,我們創建一個make文件,命名為:GNUmakefile
GNUSTEP_MAKEFILES = /usr/share/GNUstep/Makefiles include $(GNUSTEP_MAKEFILES)/common.make ADDITIONAL_FLAGS += -std=gnu11 TOOL_NAME = test test_OBJC_FILES = main.m include $(GNUSTEP_MAKEFILES)/tool.make
由於我們在源代碼中使用了C11標准中才引入的Unicode前綴字面量表達式——u'加',表示一個UTF-16字符,因此我們在GNUmakefile中也加入了-std=gnu11這個編譯選項來使得編譯器使用最新的C11標准與GNU規范語法擴展。
這里要注意的是,對於其它Linux版本的系統,GNUStep的默認安裝路徑可能不是在/usr/share/之中,因此需要根據當前GNUStep/Makefiles的路徑對GNUSTEP_MAKEFILES進行設置。而且這個變量必須在include之前定義好。
而下面的TOOL_NAME指定了make之后最終的目標可執行文件名。這里命名為test。
完了之后,如果我們之前已經執行過GNUstep.sh,那么可以直接敲make,然后回車。工程即構建完成。如果有“gcc: error trying to exec 'cc1obj': execvp: No such file or directory”之類的錯誤,那么說明還需要安裝gobjc。
下面提供其它參考鏈接:
http://www.techotopia.com/index.php/Installing_and_Using_GNUstep_and_Objective-C_on_Linux
http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_1.html#SEC11
這里注意,對於第一個鏈接中,如果直接在命令行敲gcc,是無法成功通過連接的,因為gnustep的庫都找不到。所以最好的方式還是通過利用makefile來解決問題,呼呼~
下面在提一下Objective-C與純C以及匯編混編的情況。由於GNUStep提供的makefile package僅僅提供了C、C++、Objective-C以及Objective-C++這四種編程語言,而不支持匯編語言,因此,如果要在GNUStep工程中使用匯編,我這里的做法是將匯編文件單獨編譯成.o目標文件,然后再跟其它makefile編譯好的目標文件進行連接。下面列出了對幾種源文件類型的支持(其中,斜體的appname就是你最終輸出可執行文件的名稱):
1、appname_C_FILES: C源文件,一般是.c
2、appname_OBJC_FILES:Objective-C源文件,一般是.m
3、appname_CC_FILES:C++源文件,一般是.cpp或.cc
4、appname_OBJCC_FILES:Objective-C++源文件,一般是.mm
以上這些變量后面就跟着相應的要編譯的源文件名,多個源文件名之間用空格分隔。
其余一些可用的make變量見如下鏈接:
下面將舉一個例子來說明將一個Objective-C源文件與匯編文件一起連接成最終的可執行文件。
Objective-C源文件(main.m)如下:
#import <Foundation/Foundation.h> extern int __attribute__((fastcall)) MyASMFunc(int a, int b); int main(void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Hello, world!"); unichar c = u'加'; NSLog(@"The character is: %C", c); NSLog(@"The value is: %d", MyASMFunc(10, 20)); [pool drain]; }
這里,__attribute__((fastcall))使得MyASMFunc函數的參數與返回值都能通過寄存器進行傳遞,這樣方便匯編過程的實現。
下面是匯編文件(hello.s):
.text .align 2 .globl MyASMFunc MyASMFunc: // ECX contains the first parameter // EDX contains the second parameter mov %ecx, %eax add %edx, %eax ret
匯編文件hello.s寫完之后,可以先用gcc將其匯編成目標文件hello.o,然后我們可以寫GNUmakefile:
GNUSTEP_MAKEFILES = /usr/share/GNUstep/Makefiles include $(GNUSTEP_MAKEFILES)/common.make ADDITIONAL_FLAGS += -std=gnu11 TOOL_NAME = test test_OBJC_FILES = main.m include $(GNUSTEP_MAKEFILES)/tool.make ALL_LDFLAGS += hello.o
最后,ALL_LDFLAGS標志中添加了hello.o之后,GNUmakefile就會將hello.o與main.o一起連接成最終的可執行文件test。
如果不用makefile編譯,可以直接使用命令行,比如:
gcc `gnustep-config --objc-flags` -lgnustep-base hello.m -o hello
另外,我們也可以直接在控制台使用:gnustep-config --objc-flags 來查看編譯Objective-C的默認編譯選項,從而可以做些調整。
如果我們要使用Clang以及Objective-C 2.0的庫可以參考這個鏈接:http://wiki.gnustep.org/index.php/Building_GNUstep_with_Clang
下載其它庫可以參考這個鏈接:http://wwwmain.gnustep.org/resources/downloads.php?site=ftp%3A%2F%2Fftp.gnustep.org%2Fpub%2Fgnustep%2F
