在linux下编程经常会碰到一些配置上的问题

提示怪怪的,看提示的确也找不到具体问题所在,比如说出现如下错误:

relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object;

再比如出现

/usr/bin/ld: ./xxxxx.o: relocation R_X86_64_PC32 against symbol `_ZTVN9xxxxxE' can not be used when making a shared object;

大概意思是缺少 -fPIC 这个编译参数

如果你是MakeFile方式的话,可以直接在gcc下增加,注意生成.o文件的时候要加,在后面打包成 .so的时候也要,如下所示:

$gcc-fPIC -c hello.c

$gcc-fPIC -c main.c

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

但是,我是通过eclipse进行编译so文件的,用到gcc 也用g++,意思也是要加-fPIC

解决办法:

1. 选择工程项目,点击右键选择 属性

2. C/C++ Build - Settings - Tool Settings

3. 增加 -fPIC 如下图:(有两处,注意大小写、空格)

好了,再重新编译下,就可以。

心细的人,可能会发现Eclipse下还有一个选项貌似来解决此问题的。如图:

很奇怪,这里勾上是没有作用的。不知道啥原因。

当然貌似网上有一种说法直接将命令配置成环境变量,应该可以,这样不用每个项目都要改来改去

后来发现,竟然少了一项:在Cross G++ Compiler也有这一项

Miscellaneous 打勾即可

扩展阅读: -fPIC (以下内容是摘自网上,已经写的很详细)

PIC就是position independent code

PIC使.so文件的代码段变为真正意义上的共享

如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,

重定位会修改代码段的内容,

这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置.

不加fPIC编译出来的so,是要再加载时根据加载到的位置再次重定位的.(因为它里面的代码并不是位置无关代码)
如果被多个应用程序共同使用,那么它们必须每个程序维护一份so的代码副本了.(因为so被每个程序加载的位置都不同,显然这些重定位后的代码也不同,当然不能共享)
我们总是用fPIC来生成so,也从来不用fPIC来生成a.
fPIC与动态链接可以说基本没有关系,libc.so一样可以不用fPIC编译,只是这样的so必须要在加载到用户程序的地址空间时重定向所有表目.
因此,不用fPIC编译so并不总是不好.
如果你满足以下4个需求/条件:
1.该库可能需要经常更新
2.该库需要非常高的效率(尤其是有很多全局量的使用时)
3.该库并不很大.
4.该库基本不需要被多个应用程序共享
如果用没有加这个参数的编译后的共享库,也可以使用的话,可能是两个原因:
1:gcc默认开启-fPIC选项
2:loader使你的代码位置无关
从GCC来看,shared应该是包含fPIC选项的,但似乎不是所以系统都支持,所以最好显式加上fPIC选项。参见如下
`-shared'
     Produce a shared object which can then be linked with other
     objects to form an executable.  Not all systems support this
     option.  For predictable results, you must also specify the same
     set of options that were used to generate code (`-fpic', `-fPIC',
     or model suboptions) when you specify this option.(1)
-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 和动态链接技术是计算机发展史上非常重要的一个里程碑。
gcc manul上面有说
-fpic        If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The 386 has no such limit.)
-fPIC       If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines.
关键在于GOT全局偏移量表里面的跳转项大小。
intel处理器应该是统一4字节,没有问题。
powerpc上由于汇编码或者机器码的特殊要求,所以跳转项分为短、长两种。
-fpic为了节约内存,在GOT里面预留了“短”长度。
而-fPIC则采用了更大的跳转项。

关于添加-fPIC 参数一些理解与思考相关推荐

  1. matplotlib可视化之饼图plt.pie()与plt.legend()中bbox_to_anchor参数的理解

    函数功能:表示离散变量各占比情况 调用方法:plt.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0 ...

  2. android post请求添加公共参数_XHttp2 一个功能强悍的网络请求库

    XHttp2 一个功能强悍的网络请求库,使用RxJava2 + Retrofit2 + OKHttp组合进行封装.还不赶紧点击使用说明文档,体验一下吧! 项目地址 关于我 https://github ...

  3. 【边缘计算】对边缘计算的理解与思考

    来源:边缘计算社区 在2019年第三届边缘计算技术研讨会上华为高级产业发展经理.ECC需求与总体组副主席黄还青发表了<ECC及华为在边缘计算领域的思考与实践>主题演讲,本文为黄还青演讲中对 ...

  4. springclould feign客户端添加全局参数

    用springclould feign作为调用服务的客户端,一般来说参数可以写在feignclient的方法参数里 有时需要所有feign请求都统一添加一些参数,例如token用于鉴权等,可以这样做: ...

  5. ArcEngine中IFeatureClass.Search(filter, Recycling)方法中Recycling参数的理解

    转自 ArcEngine中IFeatureClass.Search(filter, Recycling)方法中Recycling参数的理解 ArcGIS Engine中总调用IFeatureClass ...

  6. boost::callable_traits添加可变参数的测试程序

    boost::callable_traits添加可变参数的测试程序 实现功能 C++实现代码 实现功能 boost::callable_traits添加可变参数的测试程序 C++实现代码 #inclu ...

  7. 谈谈对python的理解_浅谈对python pandas中 inplace 参数的理解

    这篇文章主要介绍了对python pandas中 inplace 参数的理解,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧 pandas 中 inplace 参数在很多函数中都会有, ...

  8. vue 分享微信传参_vue实现微信分享链接添加动态参数的方法

    微信分享时 分享链接携带参数可能不是固定的 需要在分享的前一刻才知道 这里就是动态设置分享链接的基本写法 代码不是那么详尽 但大致流程如下 1.安装引用jssdk npm install --save ...

  9. idea java opts_idea为java程序添加启动参数(program arguments,vm arguments,Environment variable),并在程序中获取使用...

    # 一.问题描述 # ## 1. 开发环境 ## 1. idea2019 2. jdk1.8 3. win10 在实际的项目开发中我们经常需要为java程序添加一些启动参数(又叫java启动命令),比 ...

  10. android retrofit 2.0公共参数,Retrofit2.0 添加公共参数

    //这里可以添加公共参数 Interceptor addQueryParameterInterceptor = new Interceptor() { @Override public Respons ...

最新文章

  1. linux进程下的线程数,Linux下查看进程线程数的方法
  2. wireless(二维数组前缀和)
  3. sequelize 增加数据库字段_使用Sequelize动态创建新表
  4. linux mysql date 格式_关于MySQL中的三种日期类型
  5. spark executor task执行
  6. 利用 John the Ripper 破解用户登录密码
  7. schema在oracle里是什么意思
  8. 谈谈我对数据结构的理解
  9. 通过2048学习自定义view(二) 滑动事件监听 与 事件回调
  10. 我爱赚钱吧:你也可以通过建网站赚钱的④
  11. 用脚本组装xgen 后期文件,缓存正确,毛发飞的可能分析
  12. iOS游戏的设计、营销和盈利方式总结
  13. 计算机Excel设置透视图,电脑Excel表格中数据透视图怎么制作
  14. 多组输入与单组输入的区分
  15. 网页底部版权信息如何注明?
  16. linux nginx 内存占用,nginx内存占用过高
  17. Written English-书面-人称代词
  18. vue项目实现文件下载中心:下载、取消下载、列表展示
  19. oj3014文件格式变换
  20. Web Scraping with Python 学习笔记8

热门文章

  1. 选择粘贴性无html,office无法复制粘贴-Word把内容从一个文档选择性粘贴到另一个文档,具体操作方法...
  2. 初等数学复习之一元二次方程的解法
  3. 22021年江苏高考成绩查询,江苏省教育考试院2021年江苏高考成绩查询时间及系统入口...
  4. 无人机/FPV穿越机航模的遥控器/接收机等配件厂商
  5. 失业一年,学做跨境电商赚了50万,才知道上班是真的耽误赚钱 !
  6. Java毕业设计-快递物流管理系统
  7. RecyclerView系列:GridLayoutManager的构造函数中的orientation理解
  8. 首次使用计算机 鼠标没反应,电脑鼠标没反应是怎么回事
  9. sheet中没有getcolumns()方法吗_痘痘能去除吗?有没有效果比较好的祛痘方法
  10. 西安邮电考研计算机复试线,2020西安邮电大学考研复试分数线已公布