轉自:https://blog.csdn.net/zenny_chen/article/details/52507022linux
Objective-C做爲Apple的first-class編程語言,在很長一段時間內都獲得大量開發者的追捧。其中,Objective-C對C語言的徹底兼容、靈活性以及OOP特性,使得它成爲一門十分優秀,且平衡度很高的編程語言。在我全部用過的編程語言中,Objective-C是最最適合用於開發驅動以及應用層程序的編程語言,它比C++輕便地多,但功能上又比C++更強;而在完美兼容C語言的基礎上增長了教科書般的OOP特性!其中,消息機制是其靈魂。shell
爲了可以在其餘平臺上較好地使用現代化的Objective-C,我這裏推薦使用LLVM Clang編譯工具鏈。另外,如下描述的安裝過程是在Ubuntu16.04下進行的,而更早版本的Ubuntu系統也差很少可按照如下操做步驟完成安裝和編譯使用。編程
咱們裝好Ubuntu系統以後,GCC及其相關運行時庫就已經默認安裝在系統中了。爲了保證咱們當前用使用最新的Objective-C編譯器以及Foundation庫,咱們按照如下步驟先安裝gobjc以及GNUStep庫:數組
一、sudo apt-get install gobjcxcode
二、sudo apt-get install gnustepruby
三、sudo apt-get install gnustep-develbash
這樣咱們把Objective-C的GCC編譯器以及GNUStep運行時庫都安裝好了。編程語言
下面咱們開始下載並安裝最新release的LLVM Clang:工具
一、sudo apt-get install llvm測試
二、sudo apt-get install clang
完成這些安裝以後,咱們能夠把Clang中Apple所給予的Blocks語法相關的運行時庫以及Apple開源的Grand Central Dispatch庫給裝上。
一、sudo apt-get install libblocksruntime-dev
二、sudo apt-get install libdispatch-dev
這樣,編譯器以及必要的運行時庫的安裝都結束了。使用Ubuntu系統的一大好處就是安裝一些常規工具很是便利,只須要一個sudo apt-get install就能搞定。因此它比較適合非深度Linux用戶進行開發使用。
在編譯以前,咱們進入 /usr/share/GNUstep/Makefiles 目錄,來對編譯環境進行設置。咱們直接在控制檯執行:
sudo bash /usr/share/GNUstep/Makefiles/GNUstep.sh
便可完成環境配置。
因爲Objective-C所依賴的編譯選項以及運行時庫比較多。因此我這裏建議各位作一個makefile或是像我在下面描述的寫一個shell文件,把須要的編譯命令選項放進去。這樣咱們後面要編譯源文件時就會方便不少。
咱們首先經過執行如下命令來觀察Objective-C編譯時所須要的編譯選項:
gnustep-config --objc-flags
而後咱們把輸出的內容先複製到shell文件中保存好。再執行如下命令查看Objective-C鏈接時所須要的加載選項:
gnustep-config --objc-libs
而後咱們把加載選項複製黏貼到咱們的shell文件中。
下面咱們能夠建立一個main.m源文件進行測試:
完了以後,我下面展現一下我本身整理好的build.sh編譯shell文件:
上述build.sh文件中,咱們使用-std=gnu11命令表示將當前的Objective-C以及C語言標準設置爲符合GNU11標準語法的,即C11標準加Clang GNU擴展。若是咱們不用GNU語法擴展,咱們就沒法使用Blocks語法。-fblocks使得Clang編譯器能解析Blocks語法,並生成相應運行時代嗎。在上述命令選項中,我把全部有關異常運行時庫的命令全都刪除了,由於咱們不須要使用Objective-C的異常運行時庫。此外,我把-g命令也去掉了,由於咱們也不須要對該程序進行調試。
咱們在運行build.sh的時候會發現,Clang編譯器會報一個很烏龍的錯誤——在GSVersionMacros.h中沒法找到<objc/blocks_runtime.h>。咱們在/usr目錄下搜索一下objc目錄所在位置(在個人系統環境下,目錄位置爲:/usr/lib/gcc/x86_64-linux-gnu/5/include/),而後咱們在桌面或其餘用戶目錄下建立一個blocks_runtime.h頭文件,輸入如下內容後用sudo拷貝到該obj目錄下。該頭文件內容很是簡單:
而後咱們再次構建的時候會發生更無語的錯誤——GSBlocks頭文件中對_Blocks_copy以及_Blocks_release的聲明與Block.h中的衝突。咱們找到GSBlocks頭文件,打開發現,原來裏面聲明的_Blocks_copy與_Blocks_release的形參類型是void*,而Block.h裏聲明的則是const void*……無奈之下,咱們修改一下這個源文件,將其參數類型改成const void*就大功告成了。
咱們成功編譯構建以後會發現兩個與ARC相關的警告,這些都不用理睬。
最後要說明的是,在Clang 3.8編譯器中,Objective-C能支持@autoreleasepool、複合字面量、instancetype等高級語法特性;但還不支持property自動綜合,甚至不能在類的category以及implementation中聲明成員對象。另外也不支持字典、數組的下標索引語法,儘管GNUStep庫中已經引入瞭如下四個方法:
- (void)setObject:(id)object forKeyedSubscript:(id < NSCopying >)aKey;
- (id)objectForKeyedSubscript:(id)key;
- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index;
- (id)objectAtIndexedSubscript:(NSUInteger)index;
上面兩個用於NSMutableDictionary,下面兩個用於NSMutableArray。可是在語法層面上還不支持下標索引方式,因此在代碼示例中用了[array objectAtIndex:0]這種形式,而不是十分簡潔的array[0]。
但總的來講,LLVM Clang 3.8仍是很是不錯的,值得一用!