前几天,在项目中需要动态链接node,需要把node编译成动态库,node本身并不支持动态库的编译,在网上查找了下这方面的资料也比较少,所以在这里将编译方式记录下来,方便以后查看,也希望帮助到有同样需求的同学。
修改node.gyp文件
- 将'target_name': 'node'改为'target_name': 'libnode', 当然这个只是名字而已,不改也不会影响动态库的生成,但是在linux下动态库名字一般都是libxxx.so,所以这里还是修改一下好了。
- 将'type': 'executable',改为'type': 'shared_library', 这个是重点,必须做的。
修改configure文件
之所以要修改这里,是因为要增加一个编译参数,在函数configure_node的最后增加一行o['cflags'] += ['-fPIC'],
PIC使.so文件的代码段变为真正意义上的共享。如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy。每个copy都不一样,它取决于这个.so文件代码段和数据段在内存映射的位置。如果不加参数,编译出来的so在被加载时会根据加载到的位置再次重定位。如果被多个其他程序使用了的话,那必须在这些加载了so的程序中都要各自维护一份so的代码,也就失去了共享的意义了。