Makefile学习笔记
一、gcc编译基础
1、基于单个源文件编译过程详细分解及分析
GCC编译命令gcc xxx.c
该命令实际上是包含了4个过程
1.预编译
首先需要明确一点,gcc不会保存预编译处理阶段的输出文件,如果要看到预编译过程,需要使用-E参数,-E只会启动预编译
gcc -E xxx.c (该命令只会打印预编译结果到屏幕)假如想将其输入到文件中方便查看和分析,需要使用-o将打印到屏幕的内容输出到文本文件中,文件名一般约定熟成为.i当然你也可以使用别的比如a.都是OK的
gcc -E xxx.c -o xxx.i 或者 gcc -E -o xxx.i xxx.c
2.编译
编译为汇编语言的过程也是不会打印出来,因此如果要查看编译成汇编文件的过程需要使用参数-S,该参数只会启动预编译与编译,将源文件或者预编译过的文件编译为汇编文件,成成的文件为.s
1.gcc -S xxx.c -o xxx.s 或者 gcc -S -o xxx.s xxx.c 或者 gcc -S xxx.c (该方式会自动根据源文件来命名汇编文件名称)
2.gcc -S xxx.i -o xxx.s 或者 gcc -S -o xxx.s xxx.i 或者 gcc -S xxx.i (同上)
3.汇编
-c参数是将源文件或者预编译文件.i或者汇编文件.s编译成二进制目标文件.obj
1.gcc -c xxx.c -o xxx.o 或者 gcc -c -o xxx.o xxx.c 或者 gcc -c xxx.c (包含预编译、编译和汇编3步,最终自动命名为xxx.o文件)
2.gcc -c xxx.i -o xxx.o 或者 gcc -c -o xxx.o xxx.i 或者 gcc -c xxx.i (包含编译、汇编)
3.gcc -c xxx.s -o xxx.o 或者 gcc -c -o xxx.o xxx.s 或者 gcc -c xxx.s (包含汇编)
4.链接
不带参数时,将源文件或者.i或者汇编文件或者二进制目标文件链接为可执行文件(此时生成的名称为a.out,但是我们想要改为我们自己想要的文件名称的话,我们需要使用-o输出到自定义的文件名中)
1.gcc xxx.c -o xxx 或者 gcc -o xxx xxx.c 或者 gcc -o xxx xxx.c 或者 gcc xxx.c (包含了汇编、编译、汇编和链接4个过程)
2.gcc xxx.i -o xxx 或者 gcc -o xxx xxx.i 或者 gcc xxx.i (包含了编译、汇编、链接3个过程)
3.gcc xxx.s -o xxx 或者 gcc -o xxx xxx.s 或者 gcc xxx.s (包含了汇编、链接2个过程)
3.gcc xxx.o -o xxx 或者 gcc -o xxx xxx.o 或者 gcc xxx.o (只是链接过程)
2、基于多个源文件编译过程
由于gcc不能将多个文件使用-E、-S或者-c通过-o输出到单个文件中,所以对于多文件编译,我们只需要使用第4个过程的命令即可。
gcc a.i b.i -o xxx 或者 gcc a.i b.i 或者 gcc -o xxx a.i b.i
gcc a.s b.s -o xxx 或者 gcc a.s b.s 或者 gcc -o xxx a.s b.s
gcc a.o b.o -o xxx 或者 gcc a.o b.o 或者 gcc -o xxx a.o b.o
gcc a.c b.c -o xxx 或者 gcc a.c b.c 或者 gcc -o xxx a.c b.c
注:文中的xxx为可执行目标文件
二、Makefile初探
1、Makefile的基础语法
为什么需要Makefile?相信许多同学在看linux内核源码、u-boot源码时,我们需要从Makefile这个文件入手,因为它是编译过程的管理脚本,假如没有Makefile,程序员的工作会很复杂。
因为Makefile实际上就说多个gcc命令的集合,如果我们每编译一个源文件都去gcc一下的话,会很麻烦正对源文件很多的工程而言。因此Makefile就应运而生。
Makefile的最简单的语句结构如下:
target …:Dependent files …
command
…
…
target:target是我们的目标,就是我们最终需要得到的东西或者我们想要运行的某个伪目标。至于后面的…也就是我们的目前可以有多个(上代码就可以看到了)。
Dependent files:是生成目标文件所需要的依赖文件,因此我叫它叫做dependent,当然假如是伪目标时,是没有Dependent files的。
command:command是执行的shell命令,gcc命令等。可以是实现生成目标文件的gcc命令,可以是执行的shell命令,比如rm,ls等.需要注意的是command前面的空格是tab键打出来的
eg:
test : a.o b.o
gcc -o test a.o b.o
a.o b.o : a.c b.c
gcc -c -o a.o a.c
gcc -c -o b.o b.c
clean :
rm *.o