编译链接知识记录


在这里插入图片描述

预编译干了什么

gcc -E hello.c -o hello.i

(1)将所有的“#define”删除,并展开所有的宏定义
(2)处理所有条件预编译指令,如 #if、 #ifdef ……
(3)处理“#include”预编译指令,此过程是递归解析的
(4)删除所有注释
(5)添加行号和文件名标识,比如#2 “hello.c”2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译报错或警告时能显示行号
(6)保留所有的#pragma编译器指令,因为编译器需要使用它们 

链接干了什么

简单说就是对符号和地址进行调整,比如找函数的地址,然后把用到该函数的地方都更新成新地址。

extern "C"是什么

这是一个关键字,是C++中的关键字。
作用:
extern "C"
{
	int func(int a);
}
C++编译器会将在extern "C"大括号中的代码当做C语言代码处理,即使用C语言的名称修饰机制。
比如C里名称是__func__,C++里名称可能会是__int_func_int__
通常和一个宏一起使用:__cplusplus。C++编译器会在编译的时候默认定义这个宏。
示例:
	#ifdef __cplusplus
	extern "C"
	{
	#endif
		...something ...
	#ifdef __cplusplus
	}
	#endif

linux gcc编译时头文件怎么搜索的

1.最先会在编译选项 -I(大写 i ) 指定的路径下找。(如果有指定的话)
2.然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
3.再找内定目录/usr/include、/usr/local/include

linux gcc编译时库文件怎么搜索的

1.最先会去找编译选项 -L 指定的路径。-l(小写L)指定需要的库名字,例如-labc,意思要找的是libabc.so这个库文件
2.然后找环境变量LIBRARY_PATH
3.再找内定目录 /lib、 /usr/lib 、/usr/local/lib 这是当初编译 gcc时写在程序内的

运行时所需库怎么搜索的

1.编译选项-wl,-rpath 指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径,
	修改完这个文件后要运行 ldconfig命令,用于更新/etc/ld.so.cache。
	还有个目录/etc/ld.so.conf.d/,这个目录用法:
		比如你在部署软件时,有些动态库安装在/a/b/c目录下,可以通过如下方法实现,
		1)配置123.conf文件,里面加一行/a/b/c,然后将该文件放到/etc/ld.so.conf.d目录下;
		2)在/etc/ld.so.conf文件中增加一行include ld.so.conf.d/123.conf
		3)执行 ldconfig命令
		之后程序运行时,会自动增加在/a/b/c目录中搜索动态库
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib.

undefined reference怎么排查

未定义的引用,那就是找不到定义呗
1、报错的那个确实是没有实现
2、源文件忘记一起编译了
3、报错函数在库中,编译的时候没有加上库,加上就行:-L库路经 -l库名称
4、加上库后还不对,有可能是加库的顺序不对,调整一下试试(被依赖库放后面)。不同编译器可能不一样。
5、库的版本不对
5、库有问题,重新把库编译一下
6、C++代码中使用C函数,记得把C函数的声明用extern ‘C’ 包含起来
发布了38 篇原创文章 · 获赞 17 · 访问量 4293

猜你喜欢

转载自blog.csdn.net/qq_14877637/article/details/89294102