首页 > 解决方案 > 链接到 c++ 库时出现意外的符号解析

问题描述

我正在基于两个对象(add.o 和 sub.o)构建一个库“libsimplemath.a”。

主要只依赖于 add.o 接口。当代码与 libsimplemath.a 链接时,我希望它可以工作。

在构建 libsimplemath.a 时,我决定将 -std 标志从 c++14 切换到 c++17,情况就是如此。那时,由于某些原因 sub.o 也由链接器带来,并且由于它包含未定义的符号,因此链接失败。

要知道为什么要考虑 sub.o 链接器映射文件,可以查看:

Archive member included to satisfy reference by file (symbol)

    ./libsimplemath.a(add.o)      main.o (add(int, int))
    ./libsimplemath.a(sub.o)      main.o (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string())
    /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
                                  /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o (__libc_csu_init)

一些 stl 符号,这里是 ~basic_string(),在 sub.o 中解析。

问题是:即使没有明确使用 sub.o ,考虑到它是否正常?如果是这样,我目前正在做的事情有什么问题?

语境:

$ g++ --version
g++ (Ubuntu 8.3.0-6ubuntu1) 8.3.0
$ ld --version
GNU ld (GNU Binutils for Ubuntu) 2.32

添加.cpp

int add(int a, int b) { return a + b; }

子文件

#include <string>
void undef_symb(void);

int sub(int a, int b)
{
  std::string s;
  undef_symb();
  return a - b;
}

主文件

#include <string>
int add(int, int);
int main()
{
  std::string s = "Hello";
  return add(0, 0);
}

汇编

g++ -O0 -std=c++17 -o sub.o -c sub.cpp
g++ -O0 -std=c++17 -o add.o -c add.cpp
ar rc libsimplemath.a add.o sub.o
g++ -O0 -std=c++14 -o main.o -c main.cpp
g++ -o main main.o -L. -lsimplemath -Wl,-Map=main.g++.map
/usr/bin/ld: ./libsimplemath.a(sub.o): in function `sub(int, int)':
sub.cpp:(.text+0x2b): undefined reference to `undef_symb()'
collect2: error: ld returned 1 exit status
make: *** [Makefile:8: all] Error 1

标签: c++compilationlinker

解决方案


推荐阅读