一、基础知识
标准库的大部分函数通常放在文件 libc.a 中(文件名后缀.a
代表“achieve”,译为“获取”),或者放在用于共享的动态链接文件 libc.so 中(文件名后缀.so
代表“share object”,译为“共享对象”)。这些链接库一般位于 /lib/ 或 /usr/lib/,或者位于 GCC 默认搜索的其他目录。
当使用 GCC 编译和链接程序时,GCC 默认会链接 libc.a 或者 libc.so,但是对于其他的库(例如非标准库、第三方库等),就需要手动添加。
二、-l参数(小写的 L)
GCC 的-l
选项(小写的 L)可以让我们手动添加链接库。
令人惊讶的是,在Linux中,标准头文件 <math.h> 对应的数学库默认也不会被链接,如果没有手动将它添加进来,就会发生函数未定义错误。 下面我们编写一个数学程序 main.c,并使用到了 cos() 函数,它位于 <math.h> 头文件。
//main.c
#include <stdio.h> /* printf */
#include <math.h> /* cos */
#define PI 3.14159265
int main ()
{
double param, result;
param = 60.0;
result = cos ( param * PI / 180.0 );
printf ("The cosine of %f degrees is %f.\n", param, result );
return 0;
}
如果我们不使用 -l 选项:
[root@bogon demo]# gcc main.c
/tmp/ccYfkZJk.o: In function `main':
main.c:(.text+0x34): undefined reference to `cos'
collect2: ld returned 1 exit status
现在我们输入以下命令。
[root@bogon demo]# gcc main.c -o main.out -lm
-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,它的库名是m,它的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。
三、-L参数
该参数表示选择链接库的目录。
通常,GCC 会自动在标准库目录中搜索文件,例如 /usr/lib,如果想链接其它目录中的库,就得特别指明。
有三种方式可以链接在 GCC 搜索标准路径以外的链接库,下面我们分别讲解:
1) 直接指定该链接库的完整路径与文件名。
例如,如果链接库名为 libm.a,并且位于 /usr/lib 目录,那么下面的命令会让 GCC 编译 main.c,然后将 libm.a 链接到 main.o:
[root@bogon demo]# gcc main.c -o main.out /usr/lib/libm.a
2) 使用-L
选项,为 GCC 增加另一个搜索链接库的目录,然后再链接so文件:
[root@bogon demo]# gcc main.c -o main.out -L /usr/lib -lm
可以使用多个-L
选项,或者在一个-L
选项内使用冒号分割的路径列表。
3) 把包括所需链接库的目录加到环境变量 LIBRARYPATH 中。
四、-I参数(大写的i)
-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I(大写的i)参数指定了。比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错误。
4.1 例1
gcc -o example1 example1.c -I /usr/local/include/freetype2 -lfreetype -lm
上面这句话在编译example1.c 时,-I /usr/local/include/freetype2 表示将/usr/local/include/freetype2作为第一个寻找头文件的目录,参数-l (大写的i)。
-lfreetype ,-l (小写的L)参数用来指定程序要链接的库,-l参数紧接着就是库名。指定程序链接的库名是freetype。
-lm 表示程序指定的链接库名是m (math数学库)。
4.2 例2
gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld
上面这句表示在编译hello.c时:
-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
-L /home/hello/lib表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib
-lworld表示在上面的lib的路径中寻找libworld.so动态库文件(如果gcc编译选项中加入了“-static”表示寻找libworld.a静态库文件),程序链接的库名是world
参考: