GCC 常见的错误和解决方法记录。
undefined reference to _fini
1 | (lib_a-fini.o): In function `__libc_fini_array': |
__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 | #define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) |
这样就不会遇到编译的库在另外一个操作系统上链接不过的问题了。
Multiple definitions of xxx
一般是因为重复的函数或者变量的定义,有三种情况:
- 源代码中有多处重复的定义。
- 源代码中有一处定义,库中也有一处重复的定义。
- 库中两个目标文件包含重复的定义,但仅在开启
--whole-archive
链接选项后才会触发此错误。
--whole-archive
的作用
在两个文件中分别定义了一个 weak 函数和一个 strong 函数,然后编译打包在一个库,链接此库后生成的可执行程序内却调用了 weak 函数,这是因为 LD 会默认使用 object 文件中找到的第一个函数的地址。若 weak 函数所在 object 文件排在 strong 函数前面,则会产生此问题。
解决此问题的方法是实用--whole-archive
选项,使 LD 遍历所有的 object 文件。