0%

GCC 常见错误

GCC 常见的错误和解决方法记录。

undefined reference to _fini

1
2
(lib_a-fini.o): In function `__libc_fini_array':
fini.c:(.text.__libc_fini_array+0x1c): undefined reference to `_fini'

__libc_fini_array 和 _fini 是负责 C++ 的析构,如果没有用到 C++ 而又出现上述错误,一般是因为 .ld 中把相关的段 KEEP 了。

1
KEEP ((.init_array))

undefined reference to __locale_ctype_ptr or __ctype_ptr__

在 OSX 上编译的库,在 windows 上链接时报错:undefined reference to __locale_ctype_ptr

在 windows 上编译的苦,在 OSX 上链接时报错:undefined reference to __ctype_ptr__

原因是代码中有用到islower,isxdigit等函数,这些函数在 GCC 的 windows 和 unix-like 上的实现有差异的,它们其实都是宏定义,但在 windows 上,是一个数组指针__ctype_ptr__的索引来实现,而在 OSX 上,是一个函数__locale_ctype_ptr的返回值的索引来实现。

LwIP 开发者可能也遇到了这个问题,于是他们的做法是自己重新定义了这些函数:

1
2
3
4
5
6
#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)
#define isprint(c) in_range(c, 0x20, 0x7f)
#define isdigit(c) in_range(c, '0', '9')
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c) in_range(c, 'a', 'z')
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')

这样就不会遇到编译的库在另外一个操作系统上链接不过的问题了。

Multiple definitions of xxx

一般是因为重复的函数或者变量的定义,有三种情况:

  • 源代码中有多处重复的定义。
  • 源代码中有一处定义,库中也有一处重复的定义。
  • 库中两个目标文件包含重复的定义,但仅在开启--whole-archive链接选项后才会触发此错误。

--whole-archive的作用

在两个文件中分别定义了一个 weak 函数和一个 strong 函数,然后编译打包在一个库,链接此库后生成的可执行程序内却调用了 weak 函数,这是因为 LD 会默认使用 object 文件中找到的第一个函数的地址。若 weak 函数所在 object 文件排在 strong 函数前面,则会产生此问题。

解决此问题的方法是实用--whole-archive选项,使 LD 遍历所有的 object 文件。

坚持原创技术分享,您的支持将鼓励我继续创作!