【问题标题】:Linker error in switching from cc compiler to g++ compiler从 cc 编译器切换到 g++ 编译器时出现链接器错误
【发布时间】:2013-12-27 07:12:32
【问题描述】:

一段时间以来,我一直在使用 C 进行编码,并且在编译和链接我的代码到存档库(.a 文件)时没有遇到任何问题。但是,现在我需要切换到 C++ 并且这样做,我必须使用 g++ 而不是 cc 进行链接和编译。

使用 C,首先要做的是编译源代码并创建目标文件,然后使用相同的命令将其链接到库,但没有 -c 选项:

cc -c -ggdb -Wall -Werror -I.. test.c -o test.o
cc -o test -ggdb -Wall -Werror test.o ../libpmem/libpmem.a

由于我认为使用 g++ 做同样的事情应该执行相同的过程,所以我尝试将编译和链接阶段更改如下:

g++ -c -ggdb -Wall -Werror -I.. test.c -o test.o
g++ test.o -I.. -L/path/libpmem -lpmem -o test

虽然两个集合都应该做同样的事情,但我在尝试使用 g++ 进行链接时总是会出错。这是错误消息:

test.o: In function `main':
/path/test/test.c:5: undefined reference to `pmem_msync_mode()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

链接阶段一定有问题,因为方法定义必须在库文件中找到(就像cc链接器可以找到定义并毫无问题地进行链接一样)。

我也尝试使用单个 g++ 命令同时进行链接和编译,但无论我做什么,我总是得到同样的错误。知道如何解决这个问题吗?

【问题讨论】:

  • 驱动程序的选择(gccg++)应该无关紧要,因为它们之间的唯一区别是 g++ 自动链接到 C++ 运行时库,而 gcc 确实不是。实际编译过程检查文件扩展名以了解它编译的程序类型,因此在这种情况下使用gccg++ 之间没有实际区别,因为它仍然是 C 代码正在编译。
  • 哦,顺便说一句,链接预处理器选项(如-I)时没有使用。

标签: c++ c compiler-construction linker


【解决方案1】:

您可能有某种名称修改问题...

因为它看起来像是在 c 库中声明的,所以应该已经有某种

#ifdef __cplusplus
extern "C" {
#endif

int pmem_msync_mode(); 

#ifdef __cplusplus
}
#endif

但如果库标题中没有,您可能需要执行以下操作;

 extern "C" {
 #include <pmem.h>
}

【讨论】:

  • 单个声明也可以简单写成:extern "C" int pmem_msync_mode();
【解决方案2】:

http://www.cplusplus.com/forum/general/1143/

你需要告诉编译器代码被编译为C

【讨论】:

    【解决方案3】:

    我假设 pmem 库被编译并链接为 C 代码。

    C 和 C++ 对于如何以二进制格式存储函数名称有不同的约定。参考http://en.wikipedia.org/wiki/Name_mangling

    要解决您的问题,可能的解决方案是:

    extern "C" {
    #include <pmem.h>
    }
    

    当 C++ 编译器从头文件导入函数声明时,没有指定外部 C 链接,它期望它链接的二进制文件具有不同格式的关联函数表示,即 C++ 编译器破坏函数名称的任何格式到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      • 2011-02-03
      • 2012-04-15
      • 1970-01-01
      相关资源
      最近更新 更多