多文件编程
主文件(main函数所在的文件)往往只包含一些函数的调用。结构体的定义,函数的实现通常在不同的文件中,这时就需要主文件包含一些头文件,标准c库的头文件不用多说,如果是自己定义了头文件,函数的实现过程放到对应的.c文件中,这时候想要编译生成可执行文件,必须和对应头文件的.c文件一起编译。后期如果修改某些文件,还要全部编译,不利于维护。
通常来说,一个工程中的源文件有很多。而往往按类型、功能、模块分别放在对应的目录中,Makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile就像一个Shell脚本一样,也可以执行操作系统的命令。
2.优点(1)工程中大量代码的关系维护
大的工程中源代码比较多,手工维护、编译时间长而且编译命令复杂,难以记忆及维护。把代码维护命令及编译命令写在Makefile文件中,然后用make工具解析此文件自动执行相应命令,实现代码的合理编译。
(2)减少重复编译时间
使用make编译过一次程序后,会记录每一个文件的时间戳,当修改某些文件后,再次使用make工具编译时,只会编译修改过时间戳的文件,相比较于gcc编译节省了大量的时间,另外,make可以有选择性的对指定的文件进行编译。
(1)格式语法
目标:依赖文件列表
命令列表
main:mian.c fun.c
gcc main.c fun.c -o main
clean:
rm main -rf
4.Makefile变量语法
(1)变量概述
Makefile 变量类似于 C 语言中的宏,当 Makefile 被 make 工具解析时,其中的变量会被展开。
变量的作用:
保存文件名列表
保存文件目录列表
保存编译器名
保存编译参数
保存编译的输出 …
1、自定义变量
在 makefile 文件中定义的变量。
make 工具传给 makefile 的变量。
2、系统环境变量
make 工具解析 makefile 前,读取系统环境变量并设置为 makefile 的变量。
3、预定义变量(自动变量)
在 makefile 文件中定义的变量
定义: 变量名=变量值
应用变量: $(变量名) / ${变量名}
CC=gcc
TARGET=main
OBJ=main.o fun.o
CFLAGES=-Wall -std=c99
$(TARGET):$(OBJ)
$(CC) main.o fun.o -o main $(CFLAGES)
main.o:main.c
$(CC) -c main.c -o main.o $(CFLAGES)
fun.o:fun.c
$(CC) -c fun.c -o fun.o $(CFLAGES)
clean:
rm $(TARGET) $(OBJ)
注意:
变量是区分大小写的
变量名一般在头部定义
变量几乎可在任何地方使用
变量名可以以数字开头
变量名一般按照功能起名
make 工具传给 makefile 的变量
cc=gcc
执行 make 命令时,make 的参数 options 也可以给 makefile 设置变量。例如:make cc=arm-linux-gcc
(4)系统环境变量make 工具会拷贝系统的环境变量并将其设置为 makefile 的变量,在 makefile 中可直接读取或修改拷贝后的变量。
clean:
echo $(PWD)
echo $(SHELL)
(5) 预定义变量
makefile 中有许多预定义变量,这些变量具有特殊的含义,可在 makefile 中直接使用。
$@ 目标名
$< 依赖文件列表中的第一个文件
$^ 依赖文件列表中除去重复文件的部分
$% 如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为(image.o), $% 为 image.o。
AR 归档维护程序的程序名,默认值为 ar
ARFLAGS 归档维护程序的选项
AS 汇编程序的名称,默认值为 as
ASFLAGS 汇编程序的选项
CC C 编译器的名称,默认值为 cc
CFLAGSC 编译器的选项
CPP C 预编译器的名称,默认值为$(CC) -E CPPFLAGS C 预编译的选项
CXX C++编译器的名称,默认值为 g++ CXXFLAGS C++编译器的选项
…
注意事项:
make指令 默认寻找makefile 或 Makefile
如果make 需要指定 makefile文件名 + -f
make 默认执行第一个目标文件 其他目标文件 需要指定