【问题标题】:Building simple Objective-C example with clang on Ubuntu (linking fails)?在 Ubuntu 上使用 clang 构建简单的 Objective-C 示例(链接失败)?
【发布时间】: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_PATHLIBRARY_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


【解决方案1】:

哦,好吧,原来链接阶段可以用符号链接解决;我首先尝试使用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!

嗯,很高兴有这个排序......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 2019-06-28
    相关资源
    最近更新 更多