问题描述:
S32DS IDE工程使用math.h库的exp、pow函数,如: int i=2,y=4;int a = pow(i,y);然后再printf,编译之后就还是出现如下错误。
undefined reference to `pow’
但是使用int a = pow(2,4);然后printf(“%d”,a)这样打印出来是没问题的,
原因分析:
math.h中声明的库函数有一些特殊之处,最基本,最常用的C标准库函数和系统函数在libc.a中,有些做数学计算的C程序依赖于libm.so。在gcc中使用libc.a中的库函数编译时不需要加-Ic选项,因为这个选项是gcc默认选项。在使用libm.a的时候是需要加-Im的选项。在IDE中Libraries选项默认是没有-Im参数的,所以编译报错。
gcc -o test test.c -lm
gcc test.c -lm -o test
gcc test.c -o test -lm
gcc命令的常用选项
选项 | 解释 |
---|---|
-lLIBRARY | 连接时搜索指定的函数库LIBRARY。 |
解决方案:
右键工程 -> Properties -> C/C++ Build -> Settings -> Standard S32DS C Linker -> Libraries
将-I改为-Im即可
gcc的-l、-L、-I参数详解
标准库的大部分函数通常放在文件 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
-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,它的库名是m,它的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。
[root@bogon demo]# gcc main.c -o main.out -lm
-L参数
该参数表示选择链接库的目录。
通常,GCC 会自动在标准库目录中搜索文件,例如 /usr/lib,如果想链接其它目录中的库,就得特别指明。
有三种方式可以链接在 GCC 搜索标准路径以外的链接库,下面我们分别讲解:
- 直接指定该链接库的完整路径与文件名。
例如,如果链接库名为 libm.a,并且位于 /usr/lib 目录,那么下面的命令会让 GCC 编译 main.c,然后将 libm.a 链接到 main.o:
[root@bogon demo]# gcc main.c -o main.out /usr/lib/libm.a
- 使用-L选项,为 GCC 增加另一个搜索链接库的目录,然后再链接so文件
[root@bogon demo]# gcc main.c -o main.out -L /usr/lib -lm
- 把包括所需链接库的目录加到环境变量 LIBRARYPATH 中。
-I参数(大写的i)
-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I(大写的i)参数指定了。比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错误。
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数学库)。