参考:
http://www.cnblogs.com/hanyan225/archive/2010/10/01/1839906.html
http://www.west263.com/info/html/wangzhanyunying/jianzhanjingyan/20080417/70218.html
http://www.cnblogs.com/lidp/archive/2009/12/02/1697479.html
GNU Binutils:http://en.wikipedia.org/wiki/GNU_Binutils
Linux静态链接(库)、动态链接(库)、可执行文件加载相关问题(创建、选项、环境变量等)
(1) 概念函数库一般分为两种,静态链接库(static linking lib)和动态链接库(dynamic linking lib),无论是windows还是linux,都是如此,当然,其组织形式和调用方式可能会有所不同,这里只针对Linux来说明。那么,动态链接库和静态链接库都是编译得到的,所以,编译器得到静态链接库的链接过程就是静态链接,动态链接同理。
动态链接库一般是.so为后缀,静态链接库以.a为后缀。
为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,但由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。如下:
ln -s libtest.so.1.0 libtest.so
(2) 静态链接库和动态链接库的使用区别
首先,回顾一点,一个程序,从源代码到运行,包括:编译(compile)、链接(link)、加载(load)、运行(execute),对应的GNU工具一般为:编译器compiler(gcc)、链接器linker(ld)、加载器loader(其中动态链接库加载器为ld.so(ld-linux.version.so),在/lib目录中,如 /lib/ld-linux.so.2,所以不能直接在命令行下运行ld-linux.so,需要完整路径,加载器一般不需要我们直接运行,在运行可执行程序的加载过程中包含有动态加载的过程)。经常会将编译和链接统称为编译,期间为编译时(compile time);而加载和运行统称为运行,期间为运行时或执行时(runtime/execution time)。
静态链接库:编译时(compile time)被使用(更详细的是链接的时候)。在链接静态库的时候,链接器会在其中找到所需要链接的函数,然后将它们拷贝到执行文件,这种拷贝是完整的拷贝,所以在链接成功后,程序运行不需要静态库的参与。
动态链接库:编译时和运行时都被使用。在编译时,链接器在其中找到所需要的函数(或其他对象文件),生成地址/位置无关代码(Position Independent Code (PIC)),并没有真正的实现拷贝;在运行时(runtime/execution-time),某个程序在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了,如果有,则让其共享那一个拷贝;只有没有才链接载入。
说明:Linux下进行链接的缺省操作是先考虑动态链接库,即如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
(3) 如何生成静态库和动态库和nm命令了解
代码如下(这里test1和test2都是foo函数,打印的内容不一样,下面的内容会使用这两个链接库来学习其他内容):
// File: test1.cpp
#include <stdio.h>
void foo()
{
printf("This is foo in test1\n");
}
// File: test1.h
#ifndef TEST1_H
#define TEST1_H
void foo();
#endif
// File: test2.cpp
#include <stdio.h>
void foo()
{
printf("This is foo in test2\n");
}
// File: test2.h
#ifndef TEST2_H
#define TEST2_H
void foo();
#endif
1. 静态链接.a:
首先,先编译得到中间文件.o: