CMake中POSITION_INDEPENDENT_CODE的作用及手动设置场景咨询
关于POSITION_INDEPENDENT_CODE(PIC)的疑问解答
现有理解的补充与修正
- 静态库默认生成位置相关代码:这个是对的。静态库最终会被链接到固定位置的可执行文件,硬编码虚拟内存地址能省去运行时寻址开销,效率确实更高。
- 共享库默认生成位置无关代码:正确。共享库运行时加载地址不固定,靠全局偏移表(GOT)和过程链接表(PLT)做间接寻址,保证代码能在任意内存位置正常执行。
- 静态库链接到共享库时需设PIC:结论正确,但具体后果要明确——如果静态库没开PIC,链接共享库时GCC大概率会抛出类似
relocation R_X86_64_32 against ... can not be used when making a shared object的错误;少数情况下能编译过,但生成的共享库无法在不同地址加载,甚至运行时崩溃。你当前环境没报错,是因为GCC 10.3.0在Ubuntu 20.04下,检测到静态库要被链接进共享库时,会自动隐式添加-fPIC选项,但这不是所有编译器/平台都有的行为,不能依赖。
CMake项目中静态库的PIC设置
你给静态库hiprinter设置POSITION_INDEPENDENT_CODE属性的做法是完全正确的。因为当静态库被链接到共享库时,共享库要求所有嵌入的代码都必须是位置无关的,所以静态库必须生成PIC代码。
至于有无该属性都能编译通过,原因就是上面说的——GCC在这个环境下做了隐式处理,但换个编译器(比如Clang)或平台(比如Windows),不手动设置就会直接报错,所以手动设置属性是跨平台兼容的稳妥方案。
依赖PIC静态库的静态库是否需要设PIC?
分场景判断:
- 如果这个静态库只会被链接到可执行文件:不需要设PIC。可执行文件加载地址固定,用非PIC代码能保持更高的执行效率。
- 如果这个静态库有可能被链接到共享库:必须设PIC。只要整个链接链条里有共享库,所有参与的静态库都得是PIC代码,否则会出现链接失败或运行时异常。
内容的提问来源于stack exchange,提问作者RedBox
相关产品推荐
相关产品推荐

