在Ubuntu上构建简单的Objective-C示例与clang(链接失败)?

问题描述:

我想了解Objective-C是如何工作的,我发现的最简单的例子是从https://codeseekah.com/2012/09/12/compiling-objective-c-without-a-gui/;不幸的是,我无法完成它的编译(实际上,链接)。在Ubuntu上构建简单的Objective-C示例与clang(链接失败)?

首先,我使用Ubuntu 14.04(64位),在这里我已经安装:

sudo apt-get install clang-3.5 libobjc-4.8-dev 

然后,我有(略作修改)从this gist引用的页面文件,因此,你可以这样做:

cd /tmp 
git clone https://gist.github.com/dc0b573ae8ef2424aaeb043a6014b7fd.git testobjc 
cd testobjc 
make 

Makefile有被修改为使用当前安装的clang-3.5

第一个问题我有,是:

main.m:45:26: error: class method '+new' not found (return type defaults to 'id') [-Werror,-Wobjc-method-access] 
    Person *brad = [Person new]; 

我发现Unable to compile Objective-C code on Ubuntu

+(ID)新的NSObject类的功能。但是,您正在创建一个运行时对象的子类。要使用您在OS X中习惯使用的大多数Apple方法,您需要改为NSObject的子类。
您仍然可以在使用GNU运行时的同时使用Foundation框架。它应该可用。还有,你可以在这里使用一个参考:blog.lyxite.com/2008/01/...

这最后是死链接,但复制的http://www.cnblogs.com/jack204/archive/2012/03/21/2410095.html

编译Objective-C程序在Linux上,GNUstep的需要安装

后来我发现How to instantiate a class in Objective-C that don't inherit from NSObject

你绝对可以这样做。你的类只需要实现+ alloc本身,就像NSObject所做的那样。在基础上,这只是使用malloc()来获取足够大的内存以适应定义类的实例的结构。

原来这就是我不明白:

  • 如果在GNUstep上的GNU/Linux提供基础Objective-C的框架,那么是什么样的libobjc作用?!

由于没有这些zoneAlloc函数(需要init/alloc)等都是可用的与安装在上述两个包,我没有grep -r " id" //usr/lib/gcc/x86_64-linux-gnu/4.8/include/objc,发现有一个返回id函数class_createInstance,因此通过定义一个使用它的方法new,编译器不再在编译步骤中生成错误消息。

不过,它无法在链接步骤 - 全力打造日志也是要点(为make.log) - 有:

/usr/bin/ld: cannot find -lobjc 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make: *** [all] Error 1 

嗯,首先,libobjc.so在目录/usr/lib/x86_64-linux-gnu

$ ls -la /usr/lib/x86_64-linux-gnu/libobjc* 
lrwxrwxrwx 1 root root  19 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc_gc.so.4 -> libobjc_gc.so.4.0.0 
-rw-r--r-- 1 root root 267552 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc_gc.so.4.0.0 
lrwxrwxrwx 1 root root  16 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc.so.4 -> libobjc.so.4.0.0 
-rw-r--r-- 1 root root 112536 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc.so.4.0.0 

...并在Makefile中,我试图通过这两个LD_LIBRARY_PATHLIBRARY_PATH设置为/usr/lib/x86_64-linux-gnu运行clang命令 - 一nd我也用“其他库路径”开关-L(在LDFLAGS)指定它。 的这一切似乎是由当时的链接命令"/usr/bin/ld"运行被忽略,但是,这并不重要,因为链接命令本身有这个在它的参数:

... -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu ... 

...这的确路径确实扩大到/usr/lib/x86_64-linux-gnu(检查它与readlink -f),这是libobjc.so.*是。但链接器命令仍然失败?!

所以我的第二个问题是:

  • 为什么不ld找到libobjc.so.*,即使/usr/lib/x86_64-linux-gnu它位于其命令行参数中指定通过-L - 什么,我需要做的,让这个程序链接?
+0

我期待这个问题的原因是多方面的一个closevote,但绝对不是“无关”?有人可以解释这是如何脱离主题,我可以在哪里发布它(如果在Stack Exchange上有这样的网站?)谢谢! – sdaau

哦,好吧,事实证明,链接阶段可以通过符号链接来解决;我第一次尝试用ld进行测试,并在第一次我得到:

$ ld -L/usr/lib/x86_64-linux-gnu -lobjc 
ld: cannot find -lobjc 

...然而,有明确的路径,然后ld不抱怨“找不到”了:

$ ld -v /usr/lib/x86_64-linux-gnu/libobjc.so.4 
GNU ld (GNU Binutils for Ubuntu) 2.24 
ld: warning: cannot find entry symbol _start; not setting start address 

所以,当我看着目录更加紧密:

$ (cd /usr/lib/x86_64-linux-gnu; ls libobjc*) 
libobjc_gc.so.4 libobjc_gc.so.4.0.0 libobjc.so.4 libobjc.so.4.0.0 

......事实证明,没有简单地称为libobjc.so文件 - 他们都有名字,像libobjc.so.* ...所以我想,也许我应该与可能的libobjc.so名称的符号链接:

cd /usr/lib/x86_64-linux-gnu/ 
sudo ln -s libobjc.so.4.0.0 libobjc.so 

...现在当我运行make - 它实际上成功!我会得到一个名为main一个可执行文件,它运行罚款:

$ ./main 
Hello, my name is Brad Cox! 
Hello, my name is Tom Love! 

好,很高兴有一个排序的...