zoukankan      html  css  js  c++  java
  • 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:http://blog.sina.com.cn/s/blog_54f82cc201011op1.html

    使用 -fPIC 选项,会生成 PIC 代码。.so 要求为 PIC,以达到动态链接的目的,否则,无法实现动态链接。
     
    non-PIC 与 PIC 代码的区别主要在于 access global data, jump label 的不同。
    比如一条 access global data 的指令,
    non-PIC 的形势是:ld r3, var1
    PIC 的形式则是:ld r3, var1-offset@GOT,意思是从 GOT 表的 index 为 var1-offset 的地方处
    指示的地址处装载一个值,即 var1-offset@GOT 处的4个 byte 其实就是 var1 的地址。这个地址只有在运行的时候才知道,
    是由 dynamic-loader(ld-linux.so) 填进去的。
     
    再比如 jump label 指令
    non-PIC 的形势是:jump printf ,意思是调用 printf。
    PIC 的形式则是:jump printf-offset@GOT,意思是跳到 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
  • 相关阅读:
    寒假学习5流程控制之ifelse与for循环
    寒假学习4scala数据类型与运算符
    寒假学习13
    寒假学习14
    寒假学习3scala简介与基础1
    sqlserver 定时自动备份
    windows mysql 主从同步
    mysql 连接数 最大并发数
    mysql基础语法
    sqlserver 常见语法
  • 原文地址:https://www.cnblogs.com/youxin/p/5086937.html
Copyright © 2011-2022 走看看