【C++编译】gcc的-l参数和-L参数

今天在编译服务的时候,出现了一个错误:

/usr/bin/ld: cannot find -lxxx

于是查了一下,这个错误是因为链接程序ld在指定目录里找不到libxxx.so这个库。

那么,上面所说的“指定目录”是哪些目录,以及 -l的作用是什么呢?

-l参数:用来指定程序要链接的库,-l参数紧接着就是库名。这里的库名并非真正的库文件名。以库名为math的库为例,他的库文件名是libmath.so或者libmath.a(Linux下的库文件都要以lib开头,其中.so是动态库,.a是静态库)。可见,把库文件名的头lib和尾.so去掉就是库名了。

现在,如果我们自已要用到一个第三方提供的库libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,就能用上libtest.so库了。

实际上,以下两个命令是等价的:

gcc -o mytest mytest.c /usr/lib/libtest.so
gcc -o mytest mytest.c -ltest

放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了(如果是标准C语言库,我们可以不指定其库路径和库名称)。

如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:

/usr/bin/ld: cannot find -lxxx

也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest。

另外,其实大部分libxxxx.so只是一个链接,比如libm.so链接到/lib/libm.so.6,/lib/libm.so.6又链接到/lib/libm-2.3.2.so,

如果没有这样的链接,则会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,则做一个链接就可以了:

ln -s libxxxx-x.x.x.so libxxxx.so

当我们需要链接一个库时,手工来写链接参数总是很麻烦的,还好大多数库开发包提供了生成链接参数的程序,名字一般叫xxxx-config,一般放在/usr/bin目录下,比如:

gtk1.2的链接参数生成程序是gtk-config,执行:

gtk-config --libs

就能得到以下输出:

-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic
-lgmodule -lglib -ldl -lXi -lXext -lX11 -lm

这就是编译一个gtk1.2程序所需的gtk链接参数,xxx-config除了–libs参数外还有一个参数是–cflags,用来生成头文件包含目录的,也就是-I参数。

要使用输出的结果,我们可以复制粘贴或者照抄,不过更好的办法是在编译命令行里加入:

`xxxx-config --libs --cflags`

比如编译一个gtk程序:

gcc gtktest.c `gtk-config --libs --cflags`

注意`不是单引号,而是1键左边那个键。

-include用来包含头文件,但一般情况下包含头文件都在源码里用#include xxxxxx实现,因此-include参数很少用。

-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了,如果不加,你会得到一个”xxxx.h: No such file or directory”的错误。-I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。

在了解以上内容之后,我们再回过头来看看最开始遇到的问题:

/usr/bin/ld: cannot find -lxxx

发生这种错误的原因有以下三种情形:

1. 系统没有安装相对应的lib

2. 相对应的lib版本不对

3. lib(.so档)的symbolic link 不正确,没有连结到正确的函式库文件(.so)

解决方法:

1. 先判断在/usr/lib 下的相对应的函式库文件(.so) 的symbolic link 是否正确,若不正确改成正确的连结目标即可解决问题。

  1. 若不是symbolic link 的问题引起,而是系统缺少相对应的lib安装lib即可解决。

下面补充下如何生成库文件:

假设有test_a.cpp test_b.cpp两个源文件。

生成so文件的命令:

g++ test_a.cpp test_b.cpp -fPIC -shared -o libtest.so

生成.a文件的命令:

gcc -c test_a.cpp
gcc -c test_b.cpp
ar -r libtest.a test_a.o test_b.o
时间: 2024-10-09 14:27:30

【C++编译】gcc的-l参数和-L参数的相关文章

GCC 命令行详解 -L 指定库的路径 -l 指定需连接的库名

为什么会出现undefined reference to 'xxxxx'错误?首先这是链接错误,不是编译错误,也就是说如果只有这个错误,说明你的程序源码本身没有问题,是你用编译器编译时参数用得不对,没有指定链接程序要用到得库,比如你的程序里用到了一些数学函数,那么你就要在编译参数里指定程序要链接数学库,方法是在编译命令行里加入-lm. -l参数和-L参数-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是l

gcc -l参数和-L参数

-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了 好了现在我们知道怎么得到库名,当我们自已要用到一个第三方提供的库名字libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.

gcc “-I”(大写i),“-L”(大写l),“-l”(小写l)的区别

我们用gcc编译程序时,可能会用到“-I”(大写i),“-L”(大写l),“-l”(小写l)等参数,下面做个记录: 例: 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/inclu

链表中LinkList L与LinkList *L 借鉴

链表中LinkList L与LinkList *L的区别以及(*L).elem,L.elem L->next,(*L)->next的区别typedef struct Node{int elem;struct node * next;}node,*LinkList; 对于LinkList L: L是指向定义的node结构体的指针,可以用->运算符来访问结构体成员,即L->elem,而(*L)就是个Node型的结构体了,可以用点运算符访问该结构体成员,即(*L).elem; 对于Lin

转——链表中LinkList L与LinkList *L的区别

typedef struct Node{ int elem; struct node * next; }node,*LinkList; 对于LinkList L: L是指向定义的node结构体的指针,可以用->运算符来访问结构体成员,即L->elem,而(*L)就是个Node型的结构体了,可以用点运算符访问该结构体成员,即(*L).elem; 对于LinkList *L:L是指向定义的Node结构体指针的指针,所以(*L)是指向Node结构体的指针,可以用->运算符来访问结构体成员,即(

SqList *L 和 SqList * &L的区别/学习数据结构突然发现不太懂 小祥我查找总结了一下

小祥在学习李春葆的数据结构教程时发现一个小问题,建立顺序表和输出线性表,这两个函数的形参是不一样的. 代码在这里↓↓↓ 1 //定义顺序表L的结构体 2 typedef struct 3 { 4 Elemtype data[MaxSize]: 5 int length; 6 }SqList; 7 8 //建立顺序表 9 void CreateList(SqList * &L,ElemType a[ ],int n) 10 { 11 int i; 12 L = (SqList * )malloc(

在ubuntu14.04环境下编译gcc

到GNU开源网址下载gcc源码,并查看编译教程 GNU/GCC网址:http://www.gnu.org/software/gcc/ 2.根据官网教程,编译gcc的所需环境依赖m4,gmp,mfpr,mpc GNU Multiple Precision Library (GMP) version 4.3.2 (or later) Necessary to build GCC.  If a GMP source distribution is found in a subdirectory of

解决编译GCC内存不足的错误

近期在使用阿里和腾讯的云服务器,由于只是测试用所以只租用了廉价512的内存,在编译gcc时遇到错误,表面上看只是编译错误,并且原因不明,纠结了几次之后猜测应该是由于系统资源不足导致的,所以尝试增加系统的swap分区,这里需要检查两个地方 一.修改swappiness 1.查看你的系统里面的swappiness$ cat /proc/sys/vm/swappiness不出意外的话,你应该看到是 60,在阿里云看到的可能是0,那么就需要修改2.修改swappiness值$ sudo sysctl v

编译gcc

下载源码 自GNU FTP站下载GCC. 自Infrastructure页面下载四个库的源代码,即GMP.MPFR.MPC以及ISL(ISL非必需). 也可以不手工下载,执行源码中的./contrib/download_prerequisites 可将GRAPHITE_LOOP_OPT改为no,不下载ISL 编译安装 具体步骤如下: 编译GMP $ ./configure --prefix=$HOME $ make $ make check $ make install 编译MPFR $ ./c