1.make
make执行的是当前目录下的Makefile,默认情况下
什么是make?
make是一个命令,是一个可执行文件,用来解析makefile文件的命令
什么是makefile?
makefile是一个文件,该文件描述了我们程序的编译规则
在执行make的时候,会在当前目录下寻找makefile
根据makefile的文件的规则进行文件的编译
使用makefile的好处
简化编译程序的时间,
简化编译程序要输入的命令,只需要输入make即可
make主要解决的问题
1. 大量代码的维护
把代码的维护命令即编译命令,放在makefile中,
2. 减少编译时间
改动其中一个文件的时候,能够判断那些文件被修改过,可以之对修改过的文件进行重新编译,然后链接所有的目标文件
makefile语法规则
makefile语法规则
目标:依赖文件列表
<tab>命令列表
目标:最终要生成的文件
依赖文件:(可以没有)
一个目标通常需要几个依赖文件
命令: 有多个命令的时候,占用一行 (命令可以没有)
例子1
main.c
#include <stdio.h>
#include "main.h"
int main(int argc, char *argv[])
{
printf("hello make world\n");
printf("PI = %lf\n",PI);
return 0;
}
main.h
#define PI 3.14
makefile
main
目标 依赖文件
main:main.c main.h
命令 gcc main.c -o main
clean:
rm main
使用 make clean 进行清除操作
例子2
.o文件是汇编文件
clean使用的是假象目标
main:main.o sum.o sub.o
gcc main.o sum.o sub.o -o main
main.o:main.c
gcc -c main.c -o main.o
sub.o:sub.c
gcc -c sub.c -o sub.o
sum.o:sum.c
gcc -c sum.c -o sum.o
clean:
rm *.o main a.out -rf
make clean的结果
makefile中的变量
注释使用#号
定义变量
变量名=变量值
引用变量
$(变量名)
注意:
1.变量对大小是敏感的
2.变量一般定义在文件头
3.变量几乎可以在任何地方使用
cc=gcc
#cc=arm-linux-gnueabihf-gcc
obj=main
obj1=sub
obj2=sum
OBJ=main.o sub.o sum.o
$(obj):$(OBJ)
$(cc) $(OBJ) -o $(obj)
$(obj).o:$(obj).c
$(cc) -c $(obj).c -o $(obj).o
$(obj1).o:$(obj1).c
$(cc) -c $(obj1).c -o $(obj1).o
$(obj2).o:$(obj2).c
$(cc) -c $(obj2).c -o $(obj2).o
clean:
rm -rf *.o $(obj) a.out
执行结果和第一次的相同
不过使用了变量进行更换
makefile的预定义变量
/*使用的比较多的*/
$< 第一个依赖文件的名称。
$@ 目标的完整名称。
$^ 所有的依赖文件,以空格分开,不包含重复的依赖文件。
CC C 编译器的名称,默认值为 cc。
CFLAGS C 编译器的选项。
$* 不包含扩展名的目标文件名称。
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
$? 所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
$% 如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为
test.so(test.o),则 $@ 为 test.so,而 $% 为 test.o。
AR 归档维护程序的名称,默认值为 ar。
ARFLAGS 归档维护程序的选项。
AS 汇编程序的名称,默认值为 as。
ASFLAGS 汇编程序的选项。
CPP C 预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS C 预编译的选项。
CXX C++ 编译器的名称,默认值为 g++。
CXXFLAGS C++ 编译器的选项。
里面的$^ 表示的是OBJ里面的文件
里面的$< 表示的是obj.c文件
cc=gcc
#cc=arm-linux-gnueabihf-gcc
obj=main
obj1=sub
obj2=sum
OBJ=main.o sub.o sum.o
#目标:依赖文件
$(obj):$(OBJ)
$(cc) $^ -o $@ # $@表示的是main
# $^ 表示的是所有的依赖文件,通过空格隔开
$(obj).o:$(obj).c
$(cc) -c $< -o $@ # $@表示的是main.o
# $<表示的是第一个依赖文件的名称 这里是obj.c
$(obj1).o:$(obj1).c
$(cc) -c $< -o $@
$(obj2).o:$(obj2).c
$(cc) -c $< -o $@
clean:
rm -rf *.o $(obj) a.out
最精简
cc=gcc
#cc=arm-linux-gnueabihf-gcc
obj=main
obj1=sub
obj2=sum
OBJ=main.o sub.o sum.o
$(obj):$(OBJ)
$(cc) $^ -o $@
%*.o:%*.c
$(cc) $< -o $@
clean:
rm -rf *.o $(obj) a.out