生成静态库:
1,编译得到.o文件:gcc -c time.c -o time.o
2,打包成静态库:ar -rcs libmytime.a(-rcs必须作为第一部分) time.o
静态库的使用
1,将time.h libmytime.a 分别放入/usr/local/test0516/include 、/usr/local/test0516/lib
mkdir -p /usr/local/test0516/include
mkdir -p /usr/local/test0516/lib
cp ./time.h /usr/local/test0516/include/time.h
mv ./libmytime.a /usr/local/test0516/lib/libmytime.a
2,使用静态库 使用I选项指定 包含文件的搜索路径
gcc test.c -o test -I/usr/local/test0516/include -L/usr/local/test0516/lib -lmytime
3,运行
./test
生成动态库:
1,编译得到.o文件:gcc -c -fPIC time.c -o time.o
2,链接生成动态库:gcc -shared time.o -o libmytime.so
动态库的使用
1,将time.h libmytime.so 分别放入/usr/local/test0516/include 、/usr/local/test0516/lib
mkdir -p /usr/local/test0516/include
mkdir -p /usr/local/test0516/lib
cp ./time.h /usr/local/test0516/include/time.h
mv ./libmytime.so /usr/local/test0516/lib/libmytime.so
2,删除time.c time.h time.o
rm -f time*
2,使用动态库 编译使用I选项指定 包含文件的搜索路径
gcc test.c -o test -I/usr/local/test0516/include -L/usr/local/test0516/lib -lmytime
3,设置环境变量
export LD_LIBRARY_PATH=/usr/local/test0516/lib
当执行函数动态链接.so时,如果此文件不在缺省目录下‘/lib’ and ‘/usr/lib’.
那么就需要指定环境变量LD_LIBRARY_PATH
假如现在需要在已有的环境变量上添加新的路径名,则采用如下方式:
LD_LIBRARY_PATH=NEWDIRS:$LD_LIBRARY_PATH.(newdirs是新的路径串)
(注:GNU系统可以自动添加在 /etc/ld.so.conf文件中来实现环境变量的设置)
https://blog.csdn.net/mydriverc2/article/details/43092607
4,运行
./test
静态库动态库并存时强制使用静态库
查询使用的是哪种库readelf -d test
使用全路径
gcc test.c /usr/local/test0516/lib/libmytime.a -o test -I/usr/local/test0516/include
gcc test.c /usr/local/test0516/lib/libmytime.so -o test -I/usr/local/test0516/include
--------------------------------------------------------------------------------------------------------------
./configure \
--with-cc-opt="-I/usr/local/src/zlib/zlib-1.2.8" \
--with-ld-opt="-Wl,-rpath=/usr/local/src/zlib/zlib-1.2.8 -L/usr/local/src/zlib/zlib-1.2.8"
--with-cc-opt -> CFLAGS 用于-c 汇编阶段生成.o
--with-ld-opt 链接阶段gcc -o objs/nginx objs/src/core/nginx.o -Wl,-rpath=/usr/local/src/zlib/zlib-1.2.8 -L/usr/local/src/zlib/zlib-1.2.8 -lz -Wl,-E
-------------------------------------------------------------
动态库不需要设置LD_LIBRARY_PATH的方法
1:使用全路径(一般不会这么用)
gcc test.c /usr/local/test0516/lib/libmytime.so -o test -I/usr/local/test0516/include
2,使用-Wl,-rpath
链接阶段gcc -o useso useso.o -Wl,-rpath=./dll -L./dll -lso
3,使用-Wl,-R
链接阶段gcc -o useso useso.o -Wl,-R./dll -L./dll -lso
4, 将so放在/lib和/usr/lib,/usr/lib64/里(这时-L也不需要了)(/usr/local/lib/不可以)
往/lib和/usr/lib,/usr/lib64/里面放so之后要执行一下ldconfig,不然这个library会找不到
ldconfig执行后是系统范围内全局有效的,而环境变量只对当前shell有效
5, 将so所在路径加入/etc/ld.so.conf 执行一下ldconfig
6, 在/etc/ld.so.conf.d中加入一个专门的配置文件,将so所在路径加入 执行一下ldconfig
不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。
假如系统目录和LD_LIBRARY_PATH,/etc/ld.so.conf指定的路径下均有该so,运行时使用LD_LIBRARY_PATH指定的路径下的so;
假如系统目录,/etc/ld.so.conf指定的路径下均有该so,运行时使用/etc/ld.so.conf指定的路径下的so
编译时的-L指定路径下的so或者/lib和/usr/lib,/usr/lib64/路径下的so,决定了运行时使用的so的name
ldd -r a.out 可以看到该可执行文件运行时会使用哪个so.
-----------------------------------------------------------------------------
soname
# gcc -shared -Wl,-soname,libfun.so.1 fun.o -o libfun.so.1.2.8
# ln -s libfun.so.1.2.8 libfun.so.1
# ln -s libfun.so.1.2.8 libfun.so
[root@localhost ldso]# readelf -d libfun.so | grep SONAME
0x000000000000000e (SONAME) Library soname: [libfun.so.1]
[root@localhost ldso]# readelf -d libfun.so.1 | grep SONAME
0x000000000000000e (SONAME) Library soname: [libfun.so.1]
[root@localhost ldso]# readelf -d libfun.so.1.2.8 | grep SONAME
0x000000000000000e (SONAME) Library soname: [libfun.so.1]
使用时-lfun;要确保libfun.so 和 soname指定文件(libfun.so.1)存在(三个文件都必须存在且在同一路径下)
指定了-lfun,编译时需要libfun.so必须存在(libfun.so.1不存在也可以编过)
运行时libfun.so.1必须存在(ldd -r 可以看到可执行文件所依赖so名),而libfun.so不必存在,因为运行时查找的是libfun.so.1
[root@localhost ldso]# gcc -lfun -L. main.c
ldd -r 可以看到可执行文件所依赖so名
[root@localhost ldso]# ldd -r a.out | grep fun
libfun.so.1 => /home/kouwq/github/ldso/libfun.so.1 (0x00007f7bf0199000)
运行时依赖的soname在编译时就已经确定了而且不会改变。
---------------------------------------------------------------------------------
CPPFLAGS:预处理阶段的选项
CFLAGS或CXXFLAGS: C/C++编译器的选项 gcc -c 汇编阶段生成.o 的选项
LDFLAGS:链接选项