每次升级Xcode时,我都会在brew安装GCC时遇到链接器错误

时间:2013-11-15 15:06:55

标签: macos gcc linker llvm homebrew

所以,我升级到Mavericks以及最新版本的Xcode(5.02),并且 - 正如预期的那样,无法编译包含C扩展的任何新的Ruby宝石。这种情况特别发生在我自己的项目NMatrix中,其中包括C和C ++代码。

我重新安装了Xcode的命令行工具。然后我升级了自制软件。然后我卸载了rbenv,ruby-build和我的自定义GCC版本(4.7除外,它是手动安装而不是通过brew安装)。

接下来,我使用brew来安装gcc48(和gcc49一样好)。我指示我的gem用GCC-4.8.2构建,而不是GCC 4.9的开发快照。

好消息是我的宝石现在正确编译。坏消息是它不会链接。这是链接步骤:

$ bundle exec rake compile
cd tmp/x86_64-darwin13.0.0/nmatrix/2.0.0
make
linking shared-object nmatrix.bundle
ld: warning: directory not found for option '-L/usr/lib64/atlas'
0  0x10ef3f724  __assert_rtn + 144
1  0x10ef7425e  archive::File<x86_64>::makeObjectFileForMember(archive::File<x86_64>::Entry const*) const + 1118
2  0x10ef73c3b  archive::File<x86_64>::justInTimeforEachAtom(char const*, ld::File::AtomHandler&) const + 139
3  0x10ef883fe  ld::tool::InputFiles::searchLibraries(char const*, bool, bool, bool, ld::File::AtomHandler&) const + 210
4  0x10ef8f181  ld::tool::Resolver::resolveUndefines() + 189
5  0x10ef911a5  ld::tool::Resolver::resolve() + 79
6  0x10ef3fb17  main + 669
A linker snapshot was created at:
    /tmp/nmatrix.bundle-2013-10-15-085036.ld-snapshot
ld: Assertion failed: (memberIndex != 0), function makeObjectFileForMember, file /SourceCache/ld64/ld64-224.1/src/ld/parsers/archive_file.cpp, line 355.
collect2: error: ld returned 1 exit status
make: *** [nmatrix.bundle] Error 1
rake aborted!
Command failed with status (2): [make...]

由于几个原因,这很奇怪。

  1. 这是零星的错误。我们已经看过几次,似乎总是因为原因不明而消失。

  2. 我不认为ld: warning行是相关的,但它可能是相关的。 ATLAS由Xcode的Accelerate框架提供,在当前版本的Xcode中,它似乎不再是/usr/lib64/atlas(或者它可能永远不会)。该路径只是可能的安装位置之一,并且正确包含了正确的路径(/usr/local/atlas)。

  3. 当我搜索上面给出的函数原型时,我看到了很多LLVM的东西。这都是Mac OS X的错误。所以这是特定于Mac的。但是,当我提供GCC时,它为什么会使用LLVM呢?它是否使用正确版本的GCC进行编译,但试图链接错误的版本?

  4. 最后一个可能是最好的假设。似乎此错误仅出现在您无法覆盖默认GCC安装的计算机上(即Mac)。

    我无法安装新的ATLAS,因为没有已知的方法来关闭MacBook Air上的限制 - 这是ATLAS安装的先决条件,因此我无法消除ld警告。

    有没有人想过这些错误可能意味着什么?编译器/链接器大师?任何人吗?

    更新 我突然想到了mkmf.log,我发现了一些额外的信息。果然,这是一个ATLAS问题。但我不确定为什么它只在一个目录中查找。

    ld: warning: directory not found for option '-L/usr/lib64/atlas'
    Undefined symbols for architecture x86_64:
      "_ATL_dgemm", referenced from:
          _cblas_dgemm in libcblas.a(cblas_dgemm.o)
      "_ATL_dsyreflect", referenced from:
          _cblas_dgemm in libcblas.a(cblas_dgemm.o)
      "_ATL_dsyrk", referenced from:
          _cblas_dgemm in libcblas.a(cblas_dgemm.o)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    checked program was:
    /* begin */
     1: #include "ruby.h"
     2:
     3: #include <cblas.h>
     4:
     5: /*top*/
     6: extern int t(void);
     7: int t(void) { void ((*volatile p)()); p = (void ((*)()))cblas_dgemm; return 0; }
     8: int main(int argc, char **argv)
     9: {
    10:   if (argc > 1000000) {
    11:     printf("%p", &t);
    12:   }
    13:
    14:   return 0;
    15: }
    /* end */
    
    "gcc -o conftest -I/Users/jwoods/.rbenv/versions/2.0.0-p247/include/ruby-2.0.0/x86_64-darwin13.0.0 -I/Users/jwoods/.rbenv/versions/2.0.0-p247/include/ruby-2.0.0/ruby/backward -I/Users/jwoods/.rbenv/versions/2.0.0-p247/include/ruby-2.0.0 -I../../../../ext/nmatrix -I/usr/local/atlas/include -I/usr/include/atlas -Wall -Werror=return-type -I/Users/jwoods/.rbenv/versions/2.0.0-p247/include  -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -Wall -Werror=return-type  -O3 -Wno-error=shorten-64-to-32  -pipe conftest.c  -L. -L/Users/jwoods/.rbenv/versions/2.0.0-p247/lib -L/usr/local/atlas/lib -L/usr/local/lib -L/usr/lib -L/usr/lib64/atlas -L. -L/Users/jwoods/.rbenv/versions/2.0.0-p247/lib  -L/usr/local/lib    -lcblas -llapack  -lruby-static -lcblas -llapack  -lpthread -ldl -lobjc "
    conftest.c:7:27: error: too few arguments to function call, expected 14, have 0
    int t(void) { cblas_dgemm(); return 0; }
                  ~~~~~~~~~~~ ^
    /usr/local/atlas/include/cblas.h:470:1: note: 'cblas_dgemm' declared here
    void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
    ^
    1 error generated.
    checked program was:
    /* begin */
     1: #include "ruby.h"
     2:
     3: #include <cblas.h>
     4:
     5: /*top*/
     6: extern int t(void);
     7: int t(void) { cblas_dgemm(); return 0; }
     8: int main(int argc, char **argv)
     9: {
    10:   if (argc > 1000000) {
    11:     printf("%p", &t);
    12:   }
    13:
    14:   return 0;
    15: }
    /* end */
    

1 个答案:

答案 0 :(得分:0)

我相信我找到了答案。 extconf.rb(生成Makefile)中的一个lib搜索目录是/usr/lib64/,它在系统上不存在。因此,一旦我从搜索路径中删除了它,它就会正确编译和链接。

我还在$libs定义中添加了一个条目,该条目可能有用也可能没用。

它从$libs += " -llapack -lcblas -latlas "变为:

$libs += " -llapack -lclapack -lcblas -latlas "

但最后一点解决了链接之后的问题,而不是在期间。