【起航计划ObjC 001】印第安老斑鸠ObjC的幻想 ---- Ubuntu下安装并使用Obj-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