每次升级Xcode时,我都会在brew安装的GCC中发现链接器错误 [英] Every time I upgrade Xcode, I get linker errors with brew installed GCC

查看:268
本文介绍了每次升级Xcode时,我都会在brew安装的GCC中发现链接器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我升级到Mavericks以及最新版本的Xcode(5.02),并且 - 正如所料,无法编译任何包含C扩展的新Ruby Ruby。这发生在我自己的项目NMatrix中,它包含C和C ++代码。



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

接下来,我使用brew安装gcc48(和gcc49的好措施)。我指示我的宝石使用GCC-4.8.2而不是GCC 4.9的开发快照。

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

$ p $ $ bundle exec rake compile
cd tmp / x86_64-darwin13.0.0 / nmatrix /2.0.0
make
链接共享对象nmatrix.bundle
ld:warning:选项'-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
链接器快照创建于:
/tmp/nmatrix.bundle-2013-10-15-085036.ld-snapshot
ld:断言失败:(memberIndex != 0),函数makeObject FileForMember,文件/SourceCache/ld64/ld64-224.1/src/ld/parsers/archive_file.cpp,第355行。
collect2:错误:ld返回1退出状态
make:*** [nmatrix。捆绑]错误1
耙子中止!
命令失败,状态为(2):[make ...]

这很奇怪原因有两个。


  1. 这是一个零星的错误。我们已经看到了它几次,它总是似乎离开的原因是不清楚的。

  2. 我不认为 ld:警告行是相关的,但它可能是。 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:找不到选项' -L / usr / lib64 / atlas'
    架构x86_64的未定义符号:
    _ATL_dgemm,引用自:
    libcblas.a中的_cblas_dgemm(cblas_dgemm.o)
    _ATL_dsyreflect ,引用自:
    libcblas.a中的_cblas_dgemm(cblas_dgemm.o)
    _ATL_dsyrk,引用自:
    libcblas.a中的_cblas_dgemm(cblas_dgemm.o)
    ld:符号(s)找不到架构x86_64
    clang:错误:linker命令失败,退出代码1(使用-v查看调用)
    检查的程序是:
    / * begin * /
    1:#includeruby.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;返回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。/ 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:错误:函数调用的参数太少,预期14,有0
    int t(void){ cblas_dgemm();返回0; }
    ~~~~~~~~~~~ ^
    /usr/local/atlas/include/cblas.h:470:1:note:'cblas_dgemm'here here
    void cblas_dgemm(常量枚举CBLAS_ORDER命令,常量枚举CBLAS_TRANSPOSE TransA,
    ^
    1错误生成。
    检查程序为:
    / * 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:返回0;
    15:}
    / * end * /


    解决方法

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

    我还为 $ libs 定义添加了一个条目,它可能有用或可能没用。



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

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

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


    So, I upgraded to Mavericks as well as the newest version of Xcode (5.02), and — as expected, was unable to compile any new Ruby gems which include C extensions. This happens specifically with my own project, NMatrix, which includes C and C++ code.

    I reinstalled the command line tools for Xcode. Then I upgraded homebrew. Then I uninstalled rbenv, ruby-build, and my custom GCC versions (except for 4.7, which was installed manually rather than through brew).

    Next, I used brew to install gcc48 (and gcc49 for good measure). I instructed my gem to build with GCC-4.8.2 rather than the dev snapshot of GCC 4.9.

    The good news is that my gem now compiles properly. The bad news is that it won't link. Here is just the linking step:

    $ 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...]
    

    This is weird for a couple of reasons.

    1. It's a sporadic error. We've seen it a couple of times and it always seems to go away for reasons that are unclear.

    2. I don't think the ld: warning line is relevant, but it might be. ATLAS is provided by Xcode's Accelerate framework, and in the current version of Xcode, it no longer seems to be at /usr/lib64/atlas (or maybe it never was). That path is only one of the possible installation locations, and the correct path (/usr/local/atlas) is properly included.

    3. When I search for the function prototypes given above, I see a lot of LLVM stuff. It's all Mac OS X errors. So this is Mac-specific. But why would it be using LLVM at all when I'm providing the GCC? Is it using the correct version of GCC for compilation but trying to link with the wrong version?

    The last is probably the best hypothesis. It seems like this error only shows up on computers where you can't override the default GCC installation (Macs, namely).

    I can't install a new ATLAS because there's no known way to turn off throttling on a MacBook Air — a prerequisite for ATLAS installation, so I can't eliminate the ld warning.

    Does anyone have any thoughts as to what these errors might mean? Compiler/linker gurus? Anyone?

    Update It occurred to me to look in mkmf.log, and I found some additional information. Sure enough, it's an ATLAS problem. But I'm not really sure why it's only looking in the one directory.

    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 */
    

    解决方案

    I believe I found an answer. One of the lib search directories in the extconf.rb (which generates the Makefile) was /usr/lib64/, which doesn't exist on the system. So once I removed that from the search path, it compiled and linked properly.

    I also added an entry to the $libs definition which may or may not have been useful.

    It went from being $libs += " -llapack -lcblas -latlas " to:

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

    But that last bit solved issues after linking, not during.

    这篇关于每次升级Xcode时,我都会在brew安装的GCC中发现链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆