3

我下载并构建了 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

4

4 回答 4

5

这是一个很好的问题,因为 LLVM 和 CLang 和 GNUstep 并不声称使用起来很难或复杂。他们确实要求他们的用户阅读(并重新阅读)他们的文档。我自己刚刚为 Ubuntu 发现了这种组合,它非常有趣。目前有很多活动部件。

如果 OP 在其中一个 gnustep 邮件列表上得到了答案,那么很高兴在这里听到它是如何解决的。

没有建议重新开始的正常路线,只直接从 LLVM 和 GNUstep 安装最新版本,这是我的看法。

OP 正在尝试将 ARC 和块与 gunstep/libobjc2 项目提供的运行时一起使用。

libobjc2 可能应该使用 clang 版本 3.2 构建 - 或者可能是树的顶部。clang -v 会告诉你你的机器上有什么版本。我发现即使 Ubuntu 12.10 也不提供 clang-3.2。所以我从 LLVM 网站下载它。他们为 Ubuntu 12.04 LTS 预构建了二进制文件。为了在这个构建步骤中使用 clang,我看到了设置和导出 CC=clang 和 CXX=clang++ 的说明。

一旦构建了 libobjc2,就必须注意它的安装位置。如果系统已经有一个较旧的 libobjc.so.xy 库(它为 Obj-C 提供运行时环境),那么当您开始编译自己的源代码时,clang 或链接器可能会选择错误的库。当我运行 make install 步骤时,我发现从 libobjc2 源构建的 libobjc.so.4.6.0 在 Ubuntu 12.04 和 12.10 上都安装到了 /usr/local/lib 中。此路径不是由 libobjc2 安装步骤设置的。

为了获取这个库,我必须将 /usr/local/lib 添加到环境变量 LD_LIBRARY_PATH。尝试 'locate libojbc.so' 看看系统上是否有其他版本不会有什么坏处。

最后,libobjc2 自述文件https://github.com/gnustep/gnustep-libobjc2#readme说这个新版本的 gnustep 库支持两个 ABI,每个 ABI 都支持 ARC 和块。我看到的关于使用 libobjc2 进行编译的建议是还提供预期要编译和链接的运行时版本:-fobjc-runtime=gnustep。Ubuntu 上的 Clang 仍然默认使用旧的 ABI。-fobjc-nonfragile-abi 可能会完成同样的事情,但我已经看到它提到该标志已经或将被弃用。

OP 错误实际上可能来自运行 a.out 的步骤,而不是编译 clang 的位置。也许动态加载器正在拾取遗留的 libobj.so。同样,我会使用 locate 来查看系统是否有多个。

于 2013-03-11T15:14:44.640 回答
1

这只是一个猜测,但我会冒昧地猜测 GNUstep 将默认使用 GCC 构建。一个好的第一步可能是重新配置 GNUstep 构建以使用 Clang。我不能说会暴露出什么样的问题,但是......

或者,您可以尝试使用 GCC 而不是 Clang 构建您的应用程序。

于 2013-02-20T13:58:04.123 回答
1

这是一个相当晚的答案,但我找到了一种让一切正常工作的方法(特别是在 Elementary OS 上,所以我想在 Ubuntu 和类似的发行版上应该没问题)。

如前所述,从源代码构建所有内容会更好/更容易,因为您可以选择前缀、构建选项等。一般方法:

  1. 安装 cmake(如果尚未安装)-->sudo apt-get install cmake
  2. 按照此处的说明下载、构建和安装 llvm 和 clang (或查看附加的构建脚本)。为了速度,使用--enable-optimized标志。测试是“可选的”;-)
  3. 的默认构建脚本compiler-rt不包括 Blocks 运行时。您可以修改构建脚本,或者为其他人已经完成它而感到高兴(特别是如果像我一样,您的 cmake 不是很好)。libBlocksRuntime从此git repo下载、构建和安装(它本质上是compiler-rt带有自定义构建脚本的最新 Blocks 运行时代码的克隆)。遵循他们的编译和测试方法。
  4. libobjc2从 GNUStep下载、构建和安装。正确构建的说明实际上在现已弃用的 makefile 中。
  5. 运行ldconfig(如果需要 - 尽管运行它没有任何害处,即使它不是)。

作为@WeakPointer,您可能仍需要编辑LD_LIBRARY_PATH环境变量以获取新库。另一种选择是制作一些快速而肮脏的符号链接,以便 clang 可以找到您的新库。

最后一点:我没有对 GNUStep 的 libobjc2 和 GCC 的 libobjc 进行任何比较,后者确实包含一些 Objective-C 2.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.

# EOF
于 2014-01-14T09:38:37.330 回答
0

关键区别在于使用 Clang 进行构建。注意不要使用系统默认编译器 GCC。我从系统中删除gobjcg++包以避免这个问题。

export CC=clang
export CXX=clang++

svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/1.6.1/
cd 1.6.1
make

这个答案是从这个邮件列表线程提示的:http: //lists.gnu.org/archive/html/discuss-gnustep/2012-12/msg00036.html

描述的脚本发布在这里: http ://wiki.gnustep.org/index.php/GNUstep_under_Ubuntu_Linux

现在它编译简单的 ARC 代码。


似乎 GCC 和 Clang 生成的代码不兼容。

更新

我编写了在 FreeBSD 和 CentOS 上设置的脚本libobjc2

这些脚本大多是从博客中复制而来的。

于 2013-02-21T00:15:11.447 回答