linux下解决c语言undefined reference to 'sin', 'cos'等数学库函数


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

#define PI 3.1415926
#define EARTH_RADIUS 6371393

double deg_to_rad(double deg) {
	return deg / 180 * PI;
}

double hav(double theta) {
    double s = sin(theta / 2);
    return s * s;
}

double get_distance(double lat0, double lng0, double lat1, double lng1) {
	lat0 = deg_to_rad(lat0);
	lng0 = deg_to_rad(lng0);
	lat1 = deg_to_rad(lat1);
	lng1 = deg_to_rad(lng1);

	double dlng = fabs(lng0 - lng1);
    double dlat = fabs(lat0 - lat1);

    double h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng);
    double distance = 2 * EARTH_RADIUS * asin(sqrt(h));

    return distance;
}


int main() {
	printf("%lf\n", deg_to_rad(180));
	int* mem = calloc(1, sizeof(int));
	*mem = 0;

	int* mem2 = calloc(1, sizeof(int));
	*mem2 = 2;	
	double lat0 = 50.985408;	
	double lng0 = 11.044170;
	double lat1 = 50.985524;	
	double lng1 = 11.044168;	

	//printf("deg0: %lf\n", deg0);
	//printf("deg1: %lf\n", deg1);
	printf("distance: %lf\n", get_distance(lat0, lng0, lat1, lng1));

	///get_distance();
	free(mem);
	free(mem2);
	return 0;
}

当使用gcc编译器编译含数学函数的C程序时,会出现undefined reference to `sin'等错误.这种错误一般是由于缺少库造成的.

(base) xiao@xiao-Inspiron-7590:~/Desktop/SDK_2.4.1/test/test0$ gcc get_distance.c -o get_distance
/usr/bin/ld: /tmp/ccP8GXmr.o: in function `hav':
get_distance.c:(.text+0x47): undefined reference to `sin'
/usr/bin/ld: /tmp/ccP8GXmr.o: in function `get_distance':
get_distance.c:(.text+0x143): undefined reference to `cos'
/usr/bin/ld: get_distance.c:(.text+0x15a): undefined reference to `cos'
/usr/bin/ld: get_distance.c:(.text+0x19b): undefined reference to `sqrt'
/usr/bin/ld: get_distance.c:(.text+0x1a0): undefined reference to `asin'
collect2: error: ld returned 1 exit status

使用gcc编译时使用下列命令即可解决问题:

gcc get_distance.c -lm -o get_distance

其实,通过这个小问题,我们可以学习更多的知识。

思考如下:

明明是包含了math.h头文件的,怎么还显示sin没有定义呢?

原来,gcc的sin函数是定义在libm.so里面了。

用-l选项定义指定的路径。不填写的话默认是/lib和/usr/lib内。而数学库不在默认路径下。

在Ubuntu20.04, gcc 7.5.0 的情况下,

数学库所在位置:

/usr/lib/x86_64-linux-gnu/libm.a

因为linux下所有的函数库都是以lib开头的。所以除去头和尾,那么m就是代表libm.so

(m是库名,libm.so是库文件名)
在使用“ -l”参数时,通常的习惯是除去“lib”函数库头和后面的版本号,使用库名和参数“-l”连接,形成“-lm”。于是,我们需要在gcc找不到库时,可以使用“-l”直接给定库名。

对于使用cmake进行编译,需要添加命令:

target_link_libraries(get_distance m)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM