在gcc中-lm是什么意思?

时间:2017-05-25 07:49:20

标签: gcc

当我使用gcc编译一些c代码时,它会添加-lm。 例如,当我想在我的程序中使用fmax时,必须使用以下命令:

gcc myprogram.c -lm

通过添加-lm,我不明白我的计划会发生什么? -lm是什么意思?

感谢。

2 个答案:

答案 0 :(得分:4)

假设您拥有main.c文件:

#include <math.h>
#include <stdio.h>

float my_foo(float a, float b)
{
    return fmax(a, b);
}

int main()
{
    printf("%f\n", my_foo(4.5, 3.1));
    return 0;
 }

如果您尝试编译时没有-lm标记,则会收到undefined reference error

main.o: In function `my_foo':
main.c:(.text+0x1d): undefined reference to `fmax'
collect2: error: ld returned 1 exit status

这是因为链接器不知道fmax函数的任何实现。你必须提供它。

gcc main中,您可以找到-llibrary标志的以下说明:

  

在链接时搜索名为library的库。(第二种方法是将库作为单独的参数,仅用于POSIX,不建议使用。)

     

在您编写此选项的命令中,它会有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,foo.o -lz bar.o在文件foo.o之后但在bar.o之前搜索库z。如果bar.o引用z中的函数,则可能无法加载这些函数。

     

链接器搜索库的标准目录列表,该库实际上是名为liblibrary.a的文件。然后链接器使用此文件,就好像它已按名称精确指定一样。

     

搜索的目录包括几个标准系统目录以及您使用-L指定的任何目录。

     

通常,以这种方式找到的文件是库文件---存档文件,其成员是目标文件。链接器通过扫描存档文件来处理存档文件,以查找已定义但尚未定义的符号的成员。但是,如果找到的文件是普通的目标文件,则以通常的方式链接。 使用-l选项和指定文件名之间的唯一区别是-l使用lib和.a包围库并搜索多个目录。

看起来我有/usr/lib/x86_64-linux-gnu/libm.a存储的libm.a文件:

$ find /usr/lib -iname libm.a
/usr/lib/x86_64-linux-gnu/libm.a

您可以检查libm.a是否包含fmax的定义:

$ nm /usr/lib/x86_64-linux-gnu/libm.a --defined-only | grep fmax
[...]
s_fmax.o:
0000000000000000 W fmax
[...]

答案 1 :(得分:2)

TLDNR:math.h不是标准C库的一部分,因此您必须链接到它!

-l <​​em>库在链接时搜索库 m 代表 libm ,该库包含。有关更多信息,请参见these couple links

@ luantkow's答案的确不错,但是很长!如果您不想阅读,这是一个简短的版本! ¯\ _(ツ)_ /¯