生成静态库
若当前已有以下.o文件: obj1.o obj2.o
则gcc指令如下:
~$ ar -rsv libtest.a obj1.o obj2.o
ranlib指令:来对静态库的符号索引表进行更新
~$ ranlib libtest.a
注:linux下生成静态库.a文件有一个命名规则,必须 lib 开头 .a 结尾, 即 libXX.a
使用静态库
1.使用路径,如
~$ g++ test.o ./libtest.a -o test.out
若还依赖其他目录下的库,则也用这种绝对路径方式链接,如
~$ g++ test.o ./libtest.a /usr/local/lib/libboost_thread.a -o test.out
注:以上指令./libtest.a 和 /usr/local/lib/libboost_thread.a 都是使用路径指定要依赖的库文件,并指定链接的文件是.a(静态库)
2.使用 -L 设置文件路径,-l 代表库名,例文件为 libtest.a 则参数为 -ltest
~$ g++ test.o -L./ -llog -L/usr/local/lib -lboost_thread -o test.out
其中:-L./ 表示当前目录 -L/usr/local/lib表示 /usr/local/lib 目录
但是:使用 -L -l 会带来一个问题,该方式不指定链接库类型,即静态or动态(.a or .so),且优先链接动态库
这会带来一个问题:以上条指令为例, /usr/local/lib 下包含了boost的静态和动态库文件,当使用 -L/usr/local/lib -lboost_thread 时,链接可通过,可生成可执行文件,但是一执行就会出现提示 error while loading shared libraries: libboost_thread.so.1.49.0: cannot open shared object file: no such file or directory
这是因为使用 -L/usr/local/lib -lboost_thread 时,优先链接了动态库,而执行时却发现 .so 文件不在,相当于windows下的dll机制, -L./ -llog 链接正常是因为编译器在./下没找到相关的 .so 文件,此时才去加载 .a 文件
解决这个问题的办法:设法让可执行文件找到.so文件。也许你会把那个.so 文件拷贝到 可执行文件目录下,你会发现这是行不通的。linux里有一个环境变量叫 LD_LIBRARY_PATH, 可以理解为windows的 Path 环境变量,可在终端输入 echo $LD_LIBRARY_PATH 输出该变量值,我们只要设置该变量值到相应目录就可以解决找不.so 文件的问题了。
~$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
再执行文件,OK,问题解决。
注: 在终端用 export 指令只是暂时改变 LD_LIBRARY_PATH 的值,重启之后该值又为空,
靠谱方法为:在~/.bashrc 或者 ~/.bash_profile 中加入该 export 语句,前者在每次登陆和每次打开 shell 都读取一次,后者只在登陆时读取一次。习惯是加到 ~/.bashrc 中,在该文件的未尾可采用如下语句来使设置生效:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
修改完后,记得关掉当前终端并重新打开一个新的终端,从而使上面的配置生效。
export 后面的语句不能包含空格
另外: ldd 指令 可以查看可执行文件对哪些动态库有依赖关系