X86/Debian GNU/Linux/gcc。《Linux C编程一站式学习》PartII练习之一,对我陌生信息较多,摘抄较多。个人觉得编写Makefile时涉及蓝色标题较多,红色标题能够帮助我们省去部分体力或者眼力劳动。
1 Makefile的出现
以目前功力示例一个由三个文件组成的简单的程序:
/* Filename: main.h * Brife: Define some data * Author: One fish * Date: 2014.8.4 Monday */ #ifndef MAIN_H #define MAIN_H #define MAX_GIRLS 2 #define MAX_BOYS 2 #endif /* Filename: main.c * Brife: Supporting to wirte makefile file * Author: One fish * Date: 2014.8.4 Monday */ #include <stdio.h> #include "girls.h" #include "boys.h" int main(void) { int girl_num = 0; int boy_num = 0; girl_num = girls_number( 1 ); boy_num = boys_number( 2 ); printf("girl's number is: %d, boy's number is:%d\n", girl_num, boy_num); return 0; } /* Filename: girls.h * Brife: Declare functions * Author: One fish * Date: 2014.8.4 Monday */ #ifndef GIRLS_H #define GIRLS_H #include "main.h" extern int girls_number(int n); #endif /* Filename: girls.c * Brife: Define functions * Author: One fish * Date: 2014.8.4 Monday */ #include <stdio.h> #include "girls.h" int girls_number(int n) { return MAX_GIRLS - n; } /* Filename: Boys.h * Brife: Declare boys.c's function * Author: One fish * Date: 2014.8.4 Monday */ #ifndef BOYS_H #define BOYS_H #include "main.h" extern int boys_number(int n); #endif /* Filename: Boys.c * Brife: Define function * Author: One fish * Date: 2014.8.4 Monday */ #include "boys.h" int boys_number(int n) { return MAX_BOYS - n; }
讯享网
所有的文件都在同一目录下。对以上这段程序可以用gcc来完成程序的编译与链接:
| gcc main.c girls.c boys.c main |
只要其中有一个文件被修改时,就要把所有的源文件重新编译一遍(一方面,在源文件较多时,VS或者MDK-Keil中全部重新编译和只重新编译修改部分的时间差异还是有的)。可以用gcc分别编译各个文件,然后再用gcc来链接:
| gcc -c main.c gcc -c girls.c gcc -c boys.c gcc main.o girls.o boys.o |
这样,如果只有其中一个文件被修改(如boys.c),重新编译时只需要:
| gcc -c boys.c gcc main.o girls.o boys.o |
2 Makefile编写规则基础
一般的程序都是由多个源文件编译链接而成的。这些源文件的处理步骤通常用Makefile来管理。
(1) Makefile组成
Makefile由一组规则组成,每条规则的格式是:
| target … : prerequisite … comand1 comand2 …… |
如:
| girls.o:girls.c girls.h main.h |
girls.o是这条规则的目标(target),girls.c 、girls.h、main.h是这条规则的条件(prerequisite)。目标和条件的关系是:欲更新目标,必须首先更新条件;所有条件中只有一个条件被更新了,目标也必须随之被更新。所谓“更新”就是执行一遍规则中的命令列表(command),命令列表中的每条命令必须以一个Tab开头,且不能是空格,对于Makefile中的每个以Tab开头的命令,make会创建一个Shell进程去执行它。
一个目标依赖的所有条件不一定非得写在一条规则中,也可以拆开写,但其中只有一条规则允许有命令。
(2) 编写一个Makefile
按照Makefile组成,对1中的程序编写一个Makefile:
| main: main.o girls.o boys.o gcc main.o girls.o boys.o -o main main.o: main.c girls.h boys.h gcc -c main.c girls.o: girls.c girls.h main.h gcc -c girls.c boys.o boys.c boys.h main.h gcc -c boys.c |
然后在与源程序同一个目录下运行make编译:
| lly@debian:~/mydir/lly_books/linux_c_programming_osl/makefile$make gcc -c main.c gcc -c girls.c gcc -c boys.c gcc main.o girls.o boys.o -o main |
(3) Makefile的约定俗成(clean)规则
Makefile的clean规则用来清除编译过程产生的二进制文件,保留源文件。
| clean: -rm main *.o |
如果make执行的命令前面加了@字符,则不显示命令本身就显示命令对应的结果。通常make执行的命令如果出错就立刻终止,不再执行后续命令,但如果命令前加了-号,即使这条命令出错,make也会继续执行后续命令。
如果在make的命令中指定一个目标,则更新这个目标。如果不指定目标则更新Makefile中第一条规则的目标。如果要想更新clean这个目标得运行make clean。如果存在clean这个条件,而clean这个目标又不依赖任何条件,make就认为它不需要更新了。可以将clean声明为一个伪目标:.PHONY: clean。这样,不管clean存在更新与否都将更新clean这个目标。
clean是一个约定俗成的名字,在Makefile中类似这样的约定俗成的名字有:
- all,执行主要的编译工作,通常用作缺省目标。
- install,执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。
- clean,删除生成的二进制文件。
- distclean,不仅删除编译生成的二进制文件,也删除其它生成的文件,例如配置文件和格式转换后的文档,执行make distclean之后应该清除所有这些文件,只留下源文件。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/11471.html