cmake:POSITION_INDEPENDENT_CODE 偏执的太偏执、 2022-11-14 14:57 166阅读 0赞 set(POSITION_INDEPENDENT_CODE True) # position-independent code (PIC) 编译动态库 `.so` # `position-independent code (PIC)`:用于生成位置无关代码。位置无关代码,可以理解为代码无绝对跳转,跳转都为相对跳转。生成动态库时,需要加上`-fPIC`选项。 在 Linux 系统中,动态链接文件称为动态共享对象 (Dynamic Shared Objects,DSO),一般是以`.so`为扩展名的文件。在 Windows 系统中,动态链接文件称为动态链接库 (Dynamic Linking Library),一般是以 `.dll`为扩展名。 一般的编译链接命令行为: gcc -fPIC -shared func.c -o libfunc.so 或者: gcc -fPIC -c func.c -o func.o gcc -shared func.o -o libfunc.so `-fPIC`选项作用于编译阶段,告诉编译器产生与位置无关代码 (Position-Independent Code)。 ## 无`-fPIC`选项 ## 不添加`fPIC`也可以生成`.so`文件,但是对于源文件有要求。因为不加`fPIC`编译的`.so`必须要在加载到用户程序的地址空间时重定向到所有表目。所以在它里面不能引用其他代码 ### 编译错误 ### /* ============================================================================ Name : function_validation.c Author : Foreverstrong Cheng Version : Copyright : Copyright 2019 ForeverStrong License Description : function_validation in C, Ansi-style ============================================================================ */ #include <stdio.h> int function_validation(int num) { puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */ num += 1; return num; } ### 编译通过 ### /* ============================================================================ Name : function_validation.c Author : Foreverstrong Cheng Version : Copyright : Copyright 2019 ForeverStrong License Description : function_validation in C, Ansi-style ============================================================================ */ #include <stdio.h> int function_validation(int num) { // puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */ num += 1; return num; } 不添加`fPIC`生成的动态库,生产时假定它被加载在地址0处,加载时它会被加载到一个地址(base),需要进行一次重定位(relocation),代码、数据段中所有地址加上这个base的值。这时代码运行时就能使用正确的地址了 ## 有`-fPIC`选项 ## 添加`fPIC`选项生成的动态库,是位置无关。这样的代码本身就能被放到线性地址空间的任意位置,无需修改就能运行。通常的方法是获取指令指针的值,加上一个偏移得到全局变量/函数的地址。添加 `-fPIC`选项的源文件对于它引用的函数头文件编写有较宽松的尺度。比如只需要包含声明的函数的头文件,即使没有相应的 C 文件来实现,编译成 `.so` 库照样可以通过。 添加 -fPIC 选项实现真正意义上的多个进程共享`.so` 库。多个进程引用同一个`-fPIC` 动态库时,可以共用内存。这一个库在不同进程中的虚拟地址不同,操作系统会把它们映射到同一块物理内存上。 不添加`-fPIC` 选项,加载 `.so` 库时,需要对代码段引用的数据对象重定位,重定位会修改代码段的内容,造成每个使用这个`.so` 文件代码段的进程在内核里都会生成这个`.so` 文件代码段的`copy`,每个 copy 都不一样,取决于这个 .so 文件代码段和数据段内存映射的位置。不添加`-fPIC` 选项,消耗内存,编译的`.so`文件的优点是加载速度快。 不能使用 .so 库来静态编译 (-static) 一个可执行程序,会出现错误提示: attempted static link of dynamic object /* ============================================================================ Name : function_validation.c Author : Foreverstrong Cheng Version : Copyright : Copyright 2019 ForeverStrong License Description : function_validation in C, Ansi-style ============================================================================ */ #include <stdio.h> int function_validation(int num) { puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */ num += 1; return num; } strong@foreverstrong:~/dbscan_work/fPIC_validation$ pwd /home/strong/dbscan_work/fPIC_validation strong@foreverstrong:~/dbscan_work/fPIC_validation$ strong@foreverstrong:~/dbscan_work/fPIC_validation$ ll total 12 drwxrwxr-x 2 strong strong 4096 Feb 27 10:11 ./ drwxrwxr-x 14 strong strong 4096 Feb 27 09:18 ../ -rw-rw-r-- 1 strong strong 492 Feb 27 10:11 function_validation.c strong@foreverstrong:~/dbscan_work/fPIC_validation$ strong@foreverstrong:~/dbscan_work/fPIC_validation$ gcc -fPIC -shared function_validation.c -o validation.so strong@foreverstrong:~/dbscan_work/fPIC_validation$ strong@foreverstrong:~/dbscan_work/fPIC_validation$ ls -l total 12 -rw-rw-r-- 1 strong strong 492 Feb 27 10:11 function_validation.c -rwxrwxr-x 1 strong strong 8144 Feb 27 10:12 validation.so strong@foreverstrong:~/dbscan_work/fPIC_validation$
还没有评论,来说两句吧...