Joymine 2020-01-03
最近需要阅读vim的源代码,但是好好的一个.c文件里满屏的#ifdef、#endif…….让我怀疑自己到底有没有学过C语言,百度了一下,有建议先学一下makefile,粗略了解一下。
make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。
makefile里有什么?
makefile的书写规则:
? 1.如果这个工程没有编译过,那么所有c文件都要编译并被链接
? 2.如果这个工程的某几个c文件被修改,那么只需要编译被修改的c文件,并链接目标程序
? 3.如果这个工程的头文件被修改,那么需要编译引用了这几个头文件的c文件,并链接目标程序
makefile可以使我们只用一个make命令,就可以使其根据当前的文件修改情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。
make是如何工作的?(只输入make命令)
? 1.make会在当前目录下找名字叫“Makefile”或“makefile”的文件
? 2.如果找到,它会找文件中的第一个目标文件(target),并把这个文件作为最终的目标文件
? 3.如果目标文件不存在,或是目标文件所依赖的后面的 .o文件的文件修改时间要比当前这个文件新,那么,他就会执行后面所定义的命令来生成当前这个目标文件
? 4.如果目标所依赖的.o文件也存在,那么make会在当前文件中找目标 为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
? 5.当然,C文件和头文件是存在的,于是make会生成 .o 文件, 然后再用 .o 文件生成make的终极任务,也就是执行目标文件了
? 以上就是整个make的依赖性,make会一层又一层地去找文件的依赖关系, 直到最终编译出第一个目标文件。如果没找到依赖文件,make就会报错退出。
如vim1.14中的规则:
amiga.o: amiga.c $(INCL) amiga.h cc $(CFLAGS) -hi$(INCL) amiga.c
amiga.o是目标,amiga.c和amiga.h是目标所依赖的源文件。如果amiga.c和amiga.h的文件日期比amiga.o文件日期要新,或是amiga.o不存在,那么依赖关系发生。
如果生成(或更新)amiga.o文件,也就是cc命令(C语言编译程序默认命令,CFLAGS为C语言编译器参数)说明了如何生成/更新
GNU的make工作时的执行步骤:
thanks to:
https://blog.csdn.net/haoel/article/details/2886
https://blog.csdn.net/weixin_38391755/article/details/80380786
可以看出vim1.14的源程序中有许多#ifdef、#endif字段,这属于条件编译。源代码中的所有行都参加编译,但有时希望对其中一部分内容在其满足一定条件时才编译。
e.g. #ifdef AMIGA(标识符)
void(程序段1)
#else
int(程序段2)
#endif
即当标识符已经被定义过,则对程序段1进行编译,否则编译程序段2
#ifndef==if not defined:最主要的目的是防止头文件的重复包含和编译。检查预编译常量在前面是否已经被宏定义,如果没有被宏定义,则条件指示符#ifndef为真。
比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。
e.g. #ifndef x //如果没有定义x #define x //定义x #endif //结束如果
#undef取消前面由#define定义的预处理器标识符
read Vim1.14
amiga.c:
ArpBase
IsInteractive()//判断是否为交互窗口
quickfix mode:Quickfix模式的主要思想是保存一个位置列表,然后提供一系列命令,实现在这个位置列表中跳转。在vim启动编译,然后vim会根据编译器输出的错误信息,自动跳到第一个出错的地方,让你进行修改;修改完后,使用一个快捷键,跳到下一个错误处,再进行修改,方便的很。
一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。
ELF文件由4部分组成:ELF header、程序头表、节、节头表
只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
1)可重定向文件:文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件。(目标文件或者静态库文件,即linux通常后缀为.a和.o的文件)
2)可执行文件:文件保存着一个用来执行的程序。(例如bash,gcc等)
3)共享目标文件:共享库。文件保存着代码和合适的数据,用来被下连接编辑器和动态链接器链接。(linux下后缀为.so的文件。)
在文件的开始,保存了路线图,描述了该文件的组织情况。(/usr/include/elf.h 可查看ELF的文件头)