我试图了解 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 is a function of the NSObject class. However, you are subclassing a runtime Object. To use most of the Apple methods you're used to using in OS X, you'll need to subclass NSObject instead.
You can still use the Foundation framework while using the GNU runtime. It should be available. There is a reference you can use here: blog.lyxite.com/2008/01/…
最后一个是死链接,但复制 http://www.cnblogs.com/jack204/archive/2012/03/21/2410095.html :
To Compile Objective-C Programs on Linux, GNUstep needs to be installed
然后我发现How to instantiate a class in Objective-C that don't inherit from NSObject :
You absolutely can do so. Your class simply needs to implement +alloc itself, the way that NSObject does. At base, this just means using malloc() to grab a chunk of memory big enough to fit the structure defining an instance of your class.
所以这就是我不明白的:
- 如果 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
... and in the Makefile, I've tried running the clang
command by setting both LD_LIBRARY_PATH
and LIBRARY_PATH
to /usr/lib/x86_64-linux-gnu
- and I've also specified it with the "additional library paths"switch -L
(in 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
在其命令行参数上指定的——我需要做什么才能链接这个程序?
最佳答案
哦,好吧,事实证明链接阶段可以通过符号链接(symbolic link)来解决;我首先尝试使用 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
的符号链接(symbolic link):
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!
嗯,很高兴能解决这个问题......
关于objective-c - 在 Ubuntu 上使用 clang 构建简单的 Objective-C 示例(链接失败)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46648363/