gcc报错 can not be used when making a shared object; recompile with -fPIC

使用google protobuf时,出现错误

/usr/bin/ld: /usr/local/lib/libprotobuf.a(message_lite.o): relocation R_X86_64_32S against `_ZTVN6google8protobuf11MessageLiteE‘ can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libprotobuf.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

搜了下,几篇文章如下:

查看整个编译过程,编译过程中看到没有-fPIC选项,如何加进去
看protobuffer的README和INSTALL文档,看到需要添加特殊编译选项,需要在执行configure的时候引入,
于是make clean; make uninstall

./configure CXXFLAGS=-fPIC
查看编译文件,发现已经有了编译选项-fPIC,再次执行编译安装
重新编译程序,这次没有报错,没有出错,问题解决。

另外回答;

原因:
-fPIC 是个神马东东呢?
选项 -fPIC
PIC是Position-Independent-Code的缩写。在计算机系统中,PIC和PIE(Position-IndependentExecutable)是可以在主存中不同位置执行的目标代码。PIC经常被用在共享库中,这样就能将相同的库代码为每个程序映射到一个位置,不用担心覆盖掉其他程序或共享库。

因为so动态库编译的时候加上了 -fPIC,但是连接的 libprotobuf.a文件并不是 -fPIC生成的,所以就报错了。
那就是说连接的 libprotobuf.aa 文件,也需要加上 -fPIC 选项进行编译了。

gcc -fPIC选项

使用 -fPIC 选项,会生成 PIC 代码。.so 要求为 PIC,以达到动态链接的目的,否则,无法实现动态链接。

non-PIC 与 PIC 代码的区别主要在于 access global data, jump label 的不同。

比如一条 access global data 的指令,

non-PIC 的形势是:ld r3, var1

PIC 的形式则是:ld r3, [email protected],意思是从 GOT 表的 index 为 var1-offset 的地方处

指示的地址处装载一个值,即 [email protected] 处的4个 byte 其实就是 var1 的地址。这个地址只有在运行的时候才知道,

是由 dynamic-loader(ld-linux.so) 填进去的。

再比如 jump label 指令

non-PIC 的形势是:jump printf ,意思是调用 printf。

PIC 的形式则是:jump [email protected],意思是跳到 GOT 表的 index 为 printf-offset 的地方处

指示的地址去执行,这个地址处的代码摆放在 .plt section,每个外部函数对应一段这样的代码,其功能是呼叫

dynamic-loader(ld-linux.so) 来查找函数的地址(本例中是 printf),然后将其地址写到 GOT 表的 index 为 printf-offset 的地方,

同时执行这个函数。这样,第2次呼叫 printf 的时候,就会直接跳到 printf 的地址,而不必再查找了。

GOT 是 data section, 是一个 table, 除专用的几个 entry,每个 entry 的内容可以再执行的时候修改;

PLT 是 text section, 是一段一段的 code,执行中不需要修改。

每个 target 实现 PIC 的机制不同,但大同小异。比如 MIPS 没有 .plt, 而是叫 .stub,功能和 .plt 一样。

可见,动态链接执行很复杂,比静态链接执行时间长;但是,极大的节省了 size,PIC 和动态链接技术是计算机发展史上非常重要的一个里程碑。

/usr/bin/ld: libs/X86_64/libglog.a(libglog_la-logging.o): relocation R_X86_64_32S against `_ZTVN6google4base6LoggerE‘ can not be used when making a shared object; recompile with -fPIC libs/X86_64/libglog.a: could not read symbols: Bad value collect2: error: ld returned 1 exit status

只能安装错误提供的方法重现编译libglog.a了,然后,替换了libglog.

CXXFLAGS="-O3 -fPIC" ./configure --prefix=glog-0.3.3/install

参考:http://zrj.me/archives/1066
时间: 2024-08-05 23:13:46

gcc报错 can not be used when making a shared object; recompile with -fPIC的相关文章

eclipse编译动态链接库文件报错 relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC

解决方法: 选中工程右键->属性(properties)->c/c++Build -> GCC C Compiler -> Command ->gcc -fPIC. 问题解决!! eclipse编译动态链接库文件报错 relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC 原文地址:https://www.cnblogs.c

ubuntu 14.04 编译opencv-3.4.2 报错: /usr/bin/ld: /usr/local/lib/libavformat.a(allformats.o): relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile with -fPIC

ubuntu 14.04 编译opencv-3.4.2 报错解决: 错误信息:/usr/bin/ld: /usr/local/lib/libavformat.a(allformats.o): relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile with -fPIC/usr/local/lib/libavformat.a: error adding symbols:

CentOS-6.3 编译erlang-otp 17.0 报relocation R_X86_64_32 against `OPENSSL_ia32cap_P' can not be used when making a shared object; recompile with -fPIC错误

编译erlang otp 17.0 一直提示:/usr/bin/ld: /usr/local/ssl/lib/libcrypto.a(cryptlib.o): relocation R_X86_64_32 against `OPENSSL_ia32cap_P' can not be used when making a shared object; recompile with -fPIC 参考了一下这个:http://blog.csdn.net/zhongruixian/article/det

CentOS安装gcc报错的问题

安装记录: 系统:centos5.4 分别执行如下命令: 命令代码 yum -y install gcc yum -y install-c++ www.ahlinux.com yum install make 会报错: Loaded plugins: fastestmirror Determining fastest mirrors 解决办法: 命令代码 echo "alias yum='yum --disableplugin=fastestmirror'" >> /roo

fedora 14系统使用yum 安装gcc报错

错误:Cannot retrieve repository metadata (repomd.xml) for repository: fedora. Please verify its path and try again {大体的一个思路: 1使用默认的yum源,若不行 2使用网络yum源,若不行 3使用光盘yum源,} 网上也找不到FC14的yum源了.那就使用光盘,本地安装吧 mount /dev/cdrom /media cp -rf /medir/* /mnt      (这一步似乎

E: Invalid operation build-depgcc(给字符界面的ubuntu安装gcc 报错

sudo apt-get  build-depgccE: Invalid operation build-depgcc 原因是中间少了个空格, 使用如下命令即可. sudo apt-get  build-dep  gc 原文地址:https://www.cnblogs.com/coinbt/p/8306779.html

10.24工作笔记——解决linux_jni编译报错问题

公司在用opus开源库,所以遇到了一些问题. 我将新下载的opus1.1替换掉老版本之后,单独编译opus没问题,可是编译相关的文件就会报错. 错误信息如下: g++ -Wall -fPIC -shared libusc_jni.o libusc.a ../api/libopus.a ../api/libspeex.a ../api/libamrnb.a ../api/libpcre.a -o libusc_jni.so -L. -lusc /usr/bin/ld: ../api/libopus

tomcat启动报错APR问题

背景 很多的生产环境项目都在使用tomcat,所以要经常的跟tomcat打交道,排错是家常便饭.本博文主要是是介绍关于tomcat启动时报APR错误,报错信息如下: 02-Aug-2017 18:13:00.769 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR  based Apache Tomcat Native library which allows optimal perf

解决方法:配置群集时# gem install redis 报错:Unable to require openssl, install OpenSSL and rebuild ruby

问题:前面已经在/usr/local/src安装了ruby-2.3.0.tar.gz.rubygems-2.4.2.tar.gz.在配置 redis-3.1.1 群集中,使用gem install 安装 ruby redis 接口时报: [plain] view plain copy # [[email protected] src]# gem install redis --version 3.0.0 # # 由于源的原因,可能下载失败,就手动下载下来安装 [[email protected]