今天编译open-iscsi时遇到:
/usr/bin/ld: cannot find -lc
折腾半天,最后发现是makefile文件中在cc编译参数后面有 -static参数,进行静态编译
需要安装glibc-static静态库,去掉static参数顺利编译,也可以安装glibc-static库
一、gcc链接库
gcc的链接库分两种,分别是静态库和动态库,静态库默认以libxxx.a的命名方式,而动态库以libxxx.so的命名方式。程序编译时链接静态库,则会自己单独复制一份库代码,在运行时不需要在加载这个库文件,而动态库则是在运行时加载的,所以又称为共享库,需要这个库文件的所有程序共享内存中的一份,不需要多次加载。
gcc中链接 -lxxx库时,默认会从/lib/和/usr/lib这两个地方去找链接库,不需要额外设置,若需要加入其他链接库可以通过三种方式:
1.在/etc/目录下有ld.so.conf、ld.so.cache和ld.so.conf.d/,其中ld.so.conf.d目录下又有多个*.conf的配置文件。
在ld.so.conf文件中只有一句include /etc/ld.so.conf.d/*.conf,包含ld.so.conf.d目录下所有的配置文件,需要只需要将自己新增的链接库目录加入任何一个配置文件,或新建一个自己的配置文件。
只修改配置文件还不行,因为为了提高搜索的效率,所以系统预先对所有配置文件生成了一个二进制的处理文件,也就是ld.so.cache,所以需要运行ldconfig手动更新这个文件。
2.设置LD_LIBRARY_PATH参数,利用export $LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/xxx增加自己的库路径
3. 在编译gcc参数时直接利用-L参数指明链接库路径
这里插一句,有一次将/lib目录下的libc.so.6误删了,其实这一个软链接,指向的是实际的glibc库文件,本想将其指向一个版本更高的库文件,结果删除这个链接后发现所有的命令都不能执行,都依赖这个库文件,所以使用LD_PRELOAD=/lib/libc-2.6.1.so ln -s libc2.6.1.so libc.so.6.这里LD_PRELOAD就是预加载指定的库文件。
关于LD_PRELOAD,后面链接还有一篇有意思的文章。
二、gcc链接库的生成
1.静态库生成:
首先生成目标文件:gcc -c xxx.c xxx.c xxx.c
接着将目标文件归档:ar cqs libxxx.a xxx.o xxx.o xxx.o
编译时,指定static参数静态编译: gcc --static -lxxx 这样就会去库目录下找名为libxxx.a的静态库
2.动态库的生成:
gcc xxx.c xxx.c -fPIC -shared -o libxxx.so
参考资料: