【问题标题】:Linking C program with C++ library (GCC 4.5+)将 C 程序与 C++ 库链接 (GCC 4.5+)
【发布时间】:2012-05-04 17:42:36
【问题描述】:

我使用 gcc/g++ 4.4 来构建我的项目,现在我正在尝试切换到 gcc 4.5,但是在将 C 程序与 C++ 库链接时出现奇怪的“未定义引用”错误。这是我的测试用例:

  • source.c

    #ifdef LIBRARY
    extern "C" int one() {
        return 1;
    }
    #else
    #include <stdio.h>
    int one();
    int main() {
        printf ("%i\n", one());
        return 0;
    }
    #endif
    
  • 生成文件

    all: clean program
    program: source.c library.so
        $(CC) -L. -lrary -o $@ $<
    library.so: source.c
        $(CXX) -shared -DLIBRARY -fPIC -o $@ $<
    .PHONY: clean
    clean:
        rm -f program library.so
    

使用 GCC 4.4 时一切正常:

$ CXX=g++-4.4 CC=gcc-4.4 make
rm -f program library.so
g++-4.4 -shared -DLIBRARY -fPIC -o library.so source.c
gcc-4.4 -L. -lrary -o program source.c

但在使用 GCC 4.5 时无法正常工作:

$ CXX=g++-4.5 CC=gcc-4.5 make
rm -f program library.so
g++-4.5 -shared -DLIBRARY -fPIC -o library.so source.c
gcc-4.5 -L. -lrary -o program source.c
/tmp/ccC4kNHP.o: In function `main':
source.c:(.text+0xa): undefined reference to `one'
collect2: ld returned 1 exit status
make: *** [program] Error 1

或 GCC 4.6:

$ CXX=g++-4.6 CC=gcc-4.6 make
rm -f program library.so
g++-4.6 -shared -DLIBRARY -fPIC -o library.so source.c
gcc-4.6 -L. -lrary -o program source.c
/tmp/ccxNRNSS.o: In function `main':
source.c:(.text+0xa): undefined reference to `one'
collect2: ld returned 1 exit status
make: *** [program] Error 1

谁能解释一下这个问题?

PS:这是使用 4.6 构建的:

$ nm -D library.so
                 w _Jv_RegisterClasses
0000000000201010 A __bss_start
                 w __cxa_finalize
                 w __gmon_start__
0000000000201010 A _edata
0000000000201020 A _end
00000000000005a8 T _fini
0000000000000458 T _init
000000000000055c T one

【问题讨论】:

    标签: gcc g++ shared


    【解决方案1】:

    这是因为使用了链接器的 --as-needed 选项,即在库中的源代码中实际找到符号之前,不会链接库。您应该在编译命令中链接之前移动源文件。您可以尝试将您的 Makefile 规则 program$(CC) -L. -lrary -o $@ $&lt; 更改为 $(CC) $&lt; -L. -lrary -o $@。或者,您可以将--no-as-needed 传递给链接器,即$(CC) -Wl,--no-as-needed -L. -lrary -o $@ $&lt;。第一种方法更适合使用。
    希望这会有所帮助!

    【讨论】:

    • 差不多十年后,你的回答救了我。原来我以错误的顺序链接库。在我的示例中,在链接库 Y 之前,我必须链接依赖于库 Y 的库 X。显然,由于我的程序不直接依赖于库 Y,链接器似乎忽略了我的 -libY 而没有意识到库 X(稍后链接命令)取决于它。因此,我会收到 undefined reference 来引用库 X 中的库 Y。谢谢您的回答。
    • TL;DR 在依赖关系树中按级别链接每个库。如果我的程序使用需要 libBeta 的 libAlpha,并且我的程序还使用需要 libDelta 的 libGamma,则命令将如下所示:gcc -lalpha -lbeta -lgamma -delta
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多