【发布时间】:2017-10-09 14:03:05
【问题描述】:
我正在尝试了解 Objective-C 的工作原理,到目前为止我发现的最简单的示例来自 https://codeseekah.com/2012/09/12/compiling-objective-c-without-a-gui/ ;不幸的是,我无法完全编译它(实际上是链接)。
首先,我使用的是 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)new 是 NSObject 类的一个函数。但是,您正在对运行时对象进行子类化。要使用您习惯在 OS X 中使用的大多数 Apple 方法,您需要改为子类化 NSObject。
在使用 GNU 运行时时,您仍然可以使用 Foundation 框架。它应该可用。您可以在此处使用参考:blog.lyxite.com/2008/01/...
最后一个链接是死链接,但复制到http://www.cnblogs.com/jack204/archive/2012/03/21/2410095.html:
要在 Linux 上编译 Objective-C 程序,需要安装 GNUstep
然后我找到How to instantiate a class in Objective-C that don't inherit from NSObject:
你绝对可以这样做。您的类只需要实现 +alloc 本身,就像 NSObject 那样。在基础上,这只是意味着使用 malloc() 来获取足够大的内存块以适应定义类实例的结构。
所以这是我没有得到的:
- 如果 GNUstep 在 GNU/Linux 上提供 Foundation Objective-C 框架,那么
libobjc的作用是什么?!
由于上述两个软件包的安装都没有这些zoneAlloc 函数(init/alloc 需要)等,所以我做了grep -r " id" //usr/lib/gcc/x86_64-linux-gnu/4.8/include/objc,发现有一个函数class_createInstance返回一个id,因此通过定义一个使用它的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_PATH 和 LIBRARY_PATH 设置为 /usr/lib/x86_64-linux-gnu 来运行 clang 命令 - 并且我还指定了它使用“附加库路径”开关-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在其命令行参数中指定的——我需要做什么才能让这个程序链接?
【问题讨论】:
-
出于多种原因,我可以期待这个问题的密切投票,但绝对不是“离题”?有人可以解释一下这是怎么回事,我可以在哪里发布它(如果 Stack Exchange 上有这样的网站?)谢谢!
标签: objective-c linux linker clang