一、基础知识

标准库的大部分函数通常放在文件 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

参考:

GCC -l选项:手动添加链接库

gcc -I -L -l区别_一路奔跑94的博客-CSDN博客_-i gcc

gcc的-l参数和-L参数和-include(转载) - 长缨在手_521 - 博客园

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐