在 Linux 上编译运行 Objective-C 程序
gcc 可以编译 Objective-C,但是不用 GNUstep 是没有什么意义。 会出现如下问题:
Foundation/Foundation.h: No such file or directory
一、安装编译环境
安装软件和编译环境
# apt-get install gnustep
# apt-get install gnustep-devel
二、编译运行
1、编写程序
hello.m
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog (@"hello world");
[pool drain];
return 0;
}
2、添加环境变量
当代码编写完成后,尝试用 gcc 去编译是会出错的,如下:
# gcc -o hello hello.m
fatal error: Foundation/Foundation.h: No such file or directory
因为使用了 foundation 库,gcc 并不知道其位置。
我们现在要用 GNUstep 的方式即 makefile 的方式来编译,GNUstep 已经给我们做好了编译脚本在:
/usr/share/GNUstep/Makefiles/GNUstep.sh
我们现在就要用到它,可以用 source 命令(.)引入 GNUstep.sh 到环境变量,如下:
. /usr/share/GNUstep/Makefiles/GNUstep.sh
但这种方式,每次打开一个新终端时都需要执行一次。当然,也可以直接将其加入到环境变量中去,新增一个 GNUSTEP_MAKEFILES (名字随便)环境变量,并打开 .bashrc 添加环境变量,如下:
# cd
# vim .bashrc
在最下面添加
#set GNUstep
GNUSTEP_MAKEFILES=/usr/share/GNUstep.sh
export GNUSTEP_MAKEFILES
source /usr/share/GNUstep/Makefiles/GNUstep.sh
3、编译并运行
【1】使用 gcc
# gcc `gnustep-config --objc-flags` -Wl,--no-as-need -lgnustep-base -fconstant-string-class=NSConstantString -lobjc hello.m -o hello
最初使用下面的命令
# gcc `gnustep-config --objc-flags` -Wl,--no-as-need -lgnustep-base hello.m -o hello
出现如下错误:
/usr/bin/ld: /tmp/ccxA8Bfm.o: in function `main':
/data/proj/hello.m:4: undefined reference to `objc_get_class'
/usr/bin/ld: /data/proj/hello.m:4: undefined reference to `objc_msg_lookup'
/usr/bin/ld: /data/proj/hello.m:4: undefined reference to `objc_msg_lookup'
/usr/bin/ld: /data/proj/hello.m:5: undefined reference to `NSLog'
/usr/bin/ld: /data/proj/hello.m:6: undefined reference to `objc_msg_lookup'
/usr/bin/ld: /tmp/ccxA8Bfm.o: in function `__objc_gnu_init':
/data/proj/hello.m:8: undefined reference to `__objc_exec_class'
/usr/bin/ld: /tmp/ccxA8Bfm.o:(.data.rel+0x0): undefined reference to `__objc_class_name_NSConstantString'
/usr/bin/ld: /tmp/ccxA8Bfm.o:(.data.rel+0x8): undefined reference to __objc_class_name_NSAutoreleasePool'
collect2: error: ld returned 1 exit status
经过查资料调整后,可以正常编译,并可以生成 hello 可执行文件。
undefined reference to `objc_get_class' 需要在编译的时候加上选项 -Wl,--no-as-need
undefined reference to symbol 'objc_msg_lookup' 需要在编译的时候加上选项 -lobjc
error: cannot find interface declaration for ‘NXConstantString’ 则需要在编译的命令行加上“-fconstant-string-class=NSConstantString”
/bin/ld: cannot find -lgnustep-base 找到 gnustep-base 的库路径,然后在编译的时候带上即可。-L/usr/GNUstep/System/Library/Libraries
【2】使用 make
在项目目录中创建文件 GNUmakefile (必须命名为 GNUmakefile) 并编辑:
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = hello
hello_OBJC_FILES = hello.m
include $(GNUSTEP_MAKEFILES)/tool.make
然后,直接运行:
# make