新闻  |   论坛  |   博客  |   在线研讨会
编译动态库时遇到relocation R_X86_64_32 against `a local symbol'的错误
电子禅石 | 2020-02-20 10:44:28    阅读:8217   发布文章

主要:是编译.o 文件时,也加上-fPIC 参数,与编译器版本有关。

有三个文件【hello.c  main.c  hello.h】在执行下面的第三条命令时出现标题的错误(程序清单见文章末尾):

$gcc -c hello.c

$gcc -c main.c

$gcc -shared -fPIC -o hello hello.o main.o

.. 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版本没有发生,即该版本编译器默认加上了-fPIC,未验证过),本人在出现问题时查看了当前系统的gcc版本,为下面红色标记部分。

/home/gateway/priv/yzj/union_183>gcc -v

Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-48))

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

原因:某些版本的gcc默认没加-fPIC参数

解决办法:保证你编译.o文件的时候,都加上-fPIC,这样你才能编译出动态库来。

$gcc-fPIC -c hello.c

$gcc-fPIC -c main.c

$gcc -shared -fPIC -o hello hello.o main.o
这样能顺利生成hello.

补充说明:以上问题的出现是基于看到“红黑联盟网站上的一篇关于链接及库讲解”文章中列举出的案例,文中作者在论述时是用本文开头的方法来编译且能成功,但本人在做测试时发现存在问题故而写下此篇,该文章链接地址如下。

file:///H:/%E5%8F%82%E8%80%83%E7%AC%94%E8%AE%B0/%E7%8B%AC%E7%AB%8B%E6%80%A7%E8%B5%84%E6%96%99/%E7%BE%A4%E9%87%8C%E8%B5%84%E6%96%99%E6%94%B6%E9%9B%86/%E5%8A%A8%E6%80%81%E5%BA%93%E7%B3%BB%E5%88%97/[Linux]%E9%93%BE%E6%8E%A5%EF%BC%8C%E9%9D%99%E6%80%81%E5%BA%93%E5%92%8C%E5%8A%A8%E6%80%81%E5%BA%93%20-%20%E5%85%B6%E4%BB%96%E7%BB%BC%E5%90%88%20-%20%E7%BA%A2%E9%BB%91%E8%81%94%E7%9B%9F.htm


程序清单

1.main.c

int main()
{
hello("everyone");
return 0;
}


2.hello.c

#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s!/n", name);
}

3.hello.h

#ifndef HELLO_H
#define HELLO_H
 
void hello(const char *name);
 
#endif //HELLO_H
————————————————

原文链接:https://blog.csdn.net/usbdrivers/article/details/8854256

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
属于自己的技术积累分享,成为嵌入式系统研发高手。
推荐文章
最近访客