ndk-build在CCFLAG中添加-fPIC的作用

2019-04-15 13:50发布

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选项。