我下载并构建了GNUstep libobjc2 1.6.1,
svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/1.6.1/ rep
cd rep
make当我试图编译Objective-C代码时得到了这个错误。
hoon@ubuntu:~/work/objc2$ clang -fobjc-nonfragile-abi -fobjc-arc -fblocks *.m *.a -l pthread; ./a.out
Objective-C ABI Error: Loading modules from incompatible ABIs while loading
a.out: loader.c:38: __objc_exec_class: Assertion `objc_check_abi_version(module)' failed.
Aborted (core dumped)似乎我需要使用一些不同的配置来构建libobjc.a。问题出在哪里?我应该怎么做才能修复这个错误?
环境: Ubuntu 12.04 LTS
发布于 2013-03-11 23:14:45
这是一个很好的问题,因为LLVM、CLang和GNUstep并不声称使用起来很难或复杂。不过,他们确实会要求用户阅读(并重读)他们的文档。我自己刚刚发现了Ubuntu的这个组合,非常有趣。现在有很多可移动的部分。
如果OP在gnustep邮件列表中得到了答案,那么很高兴在这里听到它是如何解决的。
libobjc2可能应该使用clang版本3.2构建--或者可能是树的顶端。clang -v会告诉你你的机器上有什么版本。我发现即使是Ubuntu 12.10也不提供clang-3.2。所以我从LLVM网站下载了它。他们为Ubuntu 12.04 LTS预建了二进制文件。为了让make在这个构建步骤中使用clang,我已经看到了设置和导出CC=clang和CXX=clang++的说明。
一旦构建了libobjc2,就必须注意它的安装位置。如果系统已经有一个较旧的libobjc.so.x.y库(它为Obj-C提供了运行时环境),当您开始编译自己的源代码时,clang或链接器可能选择了错误的库。当我运行make install步骤时,我发现从libobjc2源代码构建的libobjc.so.4.6.0被安装到Ubuntu12.04和12.10上的/usr/local/lib中。此路径不是由libobjc2安装步骤设置的。
要使用这个库,我必须将/usr/local/lib添加到环境变量LD_LIBRARY_PATH中。尝试“定位libojbc.so”来查看系统上是否有其他版本也无伤大雅。
最后,libobjc2自述文件https://github.com/gnustep/gnustep-libobjc2#readme说这个新版本的gnustep库支持两个ABI,每个ABI都支持ARC和blocks。我看到的关于使用libobjc2编译的建议是,还应该提供预期要编译和链接的运行时版本:-fobjc- runtime =gnustep。Clang on Ubuntu仍然默认使用较旧的ABI。-fobjc-nonfragile-abi可能会完成同样的事情,但我看到它提到了flag已经或将被弃用。
操作错误实际上可能来自运行a.out的步骤,而不是编译clang的步骤。也许动态加载器正在拾取遗留的libobj.so。同样,我将使用locate来查看系统是否有多个。
发布于 2013-02-20 21:58:04
这只是一个猜测,但我要冒险一试,猜测默认情况下GNUstep将与GCC一起构建。一个不错的第一步可能是重新配置GNUstep构建以使用Clang。我不能说会暴露出什么样的问题,但是...
或者,您可以尝试使用GCC而不是Clang来构建您的应用程序。
发布于 2014-01-14 17:38:37
这是一个相当晚的答案,但我已经找到了一种方法来让一切都正常工作(特别是在基本操作系统上,所以我想它在Ubuntu和类似的发行版上应该很好)。
如前所述,从源代码构建一切会更好/更容易,因为您可以选择前缀、构建选项等。一般方法:
--enable-optimized标志。测试是“可选的”;-)compiler-rt的默认构建脚本不包括块运行时。您可以修改构建脚本,或者庆幸其他人已经这样做了(特别是如果像我一样,您的cmake不是很好)。从this git repo下载、构建并安装libBlocksRuntime (它本质上是带有自定义构建脚本的最新compiler-rt块运行时代码的克隆)。遵循他们的编译和测试,构建并安装libobjc2 from GNUStep。正确构建的指令实际上位于现已弃用的makefile.ldconfig中(如果需要-尽管即使不运行也没有坏处)。作为@WeakPointer,您可能仍然需要编辑LD_LIBRARY_PATH环境变量来选择您的新库。另一种选择是创建一些快速而肮脏的符号链接,这样clang就可以找到您的新库。
最后注意:我还没有在GNUStep的libobjc2和GCC的libobjc之间做任何比较,后者确实包含一些Objective-C2.0特性……如果您同时在系统上保留这两个库,请注意您的库选择!
下面的脚本应该可以完成所有这些工作(未经测试!):
#!/bin/bash
# Temporary base directories
basedir="./clangllvm_temp"
basedir2="./libBlocksRuntime_temp"
basedir3="./libObjc2_temp"
# Clang, llvm, compiler-rt
mkdir $basedir
cd $basedir
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ../..
cd llvm/tools/clang/tools
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra
cd ../../../..
cd llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
cd ../..
mkdir build
cd build
../llvm/configure --prefix=$PREFIX --enable-optimized
make
sudo make install
cd ../..
# libBlocksRuntime
git clone https://github.com/mackyle/blocksruntime.git $basedir2
cd $basedir2
sudo ./buildlib
sudo ./checktests
sudo ./installlib
# Test!
clang -o sample -fblocks sample.c -lBlocksRuntime && ./sample
cd ..
# libobjc2
https://github.com/gnustep/gnustep-libobjc2.git $basedir3
cd $basedir3
mkdir Build
cd Build
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
sudo make && sudo -E make install
cd ../..
# Cleanup
rm -rf $basedir
rm -rf $basedir2
rm -rf $basedir3
# ldconfig
sudo ldconfig
# Additional symlink/LD_LIBRARY_PATH stuff here if required.
# EOFhttps://stackoverflow.com/questions/14980402
复制相似问题