动态库编译时(引用静态库)could not read symbols: Bad value

在编译动态库时遇到`relocation R_X86_64_32 against 'a local symbol'`错误,提示需要使用`-fPIC`参数。问题可能源于编译.o文件或静态库时未添加此参数。解决方案是确保所有编译过程都包含`-fPIC`,以创建符合要求的动态库。


编译动态库时遇到relocation R_X86_64_32 against `a local symbol'的错误  

编译动态库时遇到如下错误:

... relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

... could not read symbols: Bad value

解决办法编译器已经提示了:recompile with -fPIC

但是我们应该重新编译谁带上这个参数呢?经过我几番折腾,发现如下情况:

1、编译.o文件的时候,没有加参数-fPIC,这问题个在gcc version 3.4.6版本没有发生,可能那个编译器默认都给加上吧。

2、当前程序中有用到某个静态库,那个静态库编译.o文件的时候没有加上-fPIC(静态库其实就是.o文件打包)。补充一点:我发现手写Makefile时即使不加-fPIC也没有这个问题,这一点很郁闷,这个只在用automake工具编译出.a文件时才出现过。

知道原因了,解决办法自然有了,保证你编译.o文件的时候,都加上-fPIC,这样你才能编译出动态库来。

**************

I'm Trying to Link a static Library to a shared library , I'm Getting the Following error

/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(fileappender.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
../../../libraries/log4cplus/liblog4cplus.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

Assuming you are generating a shared library, most probably what happens is that the variant of liblog4cplus.a you are using wasn't compiled with -fPIC. In linux, you can confirm this by extracting the object files from the static library and checking their relocations:

ar -x liblog4cplus.a  
readelf --relocs fileappender.o | egrep '(GOT|PLT|JU?MP_SLOT)'

If the output is empty, then the static library is not PIC and cannot be used to generate a shared object.

Since the static library contains object code which was already compiled, providing the -fPIC flag won't help.

You need to get ahold of a version of liblog4cplus.a compiled with -fPIC and use that one instead.


你遇到的错误信息: ``` could not read symbols: Invalid operation ``` 是一个典型的链接器(linker)错误,通常出现在使用 GCC 编译器(如 `gcc`)进行链接阶段时。这个错误并不直接是 C 语言本身的错误,而是与编译和链接过程有关。 --- ### ✅ 可能的原因和解决方法如下: --- ### **1. 错误的编译命令(没有正确编译成可执行文件)** 你可能没有正确地将 `.c` 文件编译为可执行文件。例如: ```bash gcc -c main.c -o main ``` 这里 `-c` 参数表示只编译不链接,生成的是目标文件(`.o`),但你试图运行它或链接它时会出现错误。 **解决方法:** 去掉 `-c` 参数: ```bash gcc main.c -o main ``` --- ### **2. 编译了非 C 文件(例如编译了一个目录或错误的文件类型)** 如果你不小心执行了类似: ```bash gcc some_directory -o app ``` 或者: ```bash gcc some_binary_file -o app ``` 链接器会尝试读取这些非目标文件的内容,导致 `could not read symbols: Invalid operation` 错误。 **解决方法:** 确保你编译的是 `.c` 源文件,而不是其他类型文件或目录。 --- ### **3. 编译器版本或平台不兼容的目标文件** 如果你在交叉编译、使用了不同架构下生成的 `.o` 文件,或使用了不同编译器生成的目标文件,也可能导致该错误。 **解决方法:** 确认所有目标文件是由相同平台和编译器生成的,避免混用不同架构或编译器生成的二进制文件。 --- ### **4. 某些第三方库缺失或链接方式错误** 当你在链接某些库时,例如: ```bash gcc main.o -o app ``` 但 `main.o` 依赖某些未正确链接的库函数(如数学库、线程库等),也可能出现这个错误。 **解决方法:** 确保正确链接所需的库。例如使用数学库: ```bash gcc main.c -o main -lm ``` 或者使用线程库: ```bash gcc main.c -o main -pthread ``` --- ### **5. 文件权限或损坏** 如果目标文件或源文件权限设置错误,或者文件损坏,也可能导致链接器无法读取符号。 **解决方法:** 检查文件权限是否可读,使用 `chmod` 修改权限,或重新生成目标文件。 --- ### ✅ 示例代码 假设你有如下简单的 `main.c` 文件: ```c #include <stdio.h> int main() { printf("Hello, world!\n"); return 0; } ``` 正确的编译命令是: ```bash gcc main.c -o main ./main ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值