【C语言】嵌入式C语言项目管理利器:深入理解Makefile的应用与实践
目录
一、makefile的概述
1、案例引入
gcc a.c b.c c.c ‐o main
如果只修改了b.c 使用gcc编译 需要对所有文件重新编译。makefile可避免此问题.
2、makefile
make 是个命令,是个可执行程序,用来解析 Makefile 文件的命令。
makefile 是个文件,这个文件中描述了程序的编译规则。
3、Makefile优点
(1)简化编译程序的时候输入得命令,编译的时候只需要敲 make 命令就可以了
(2)可以节省第二次编译时间,提高编译效率
二、makefile的语法规则
1、语法规则
目标文件名:依赖文件(建立关系)
<Tab>命令列表
目标文件:就是需要生成的文件(可执行文件、其他obj文件或动作名称)
依赖文件:通过依赖文件 生成 目标文件(通常有几个依赖文件)
命令列表:实现 将依赖文件 生成 目标文件(多个命令时,每个命令占一行)
以gcc a.c b.c c.c -o main编译三个文件为例:
语法实例:
main:a.c b.c c.c
gcc a.c b.c c.c ‐o main
2、简单实战
(1)创建并编写test.c文件
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("hello worldn");
return 0;
}
(2)创建并编写makefile文件
main:test.c
gcc test.c ‐o main
(3)最后在linux终端输入命令make即可编译test.c文件
make 默认在工作目录中寻找名为 GNUmakefile、makefile、Makefile 的文件作为输入文件
make -f 自定义makefle文件名将自定义文件名的文件作为输入文件
make 默认会实现 makefile 文件内的第一个目标。 make 目标文件名 ----->选择目标执行。
多个目标时,命令make 目标文件名:另一目标文件名 ----->选择多个目标执行。
3、较复杂实战
(1)创建并编写fun.c
int my_add(int x, int y)
{
return x+y;
}
int my_sub(int x, int y)
{
return x-y;
}
int my_mul(int x, int y)
{
return x*y;
}
int my_div(int x, int y)
{
return x/y;
}
(2)创建并编写fun.h
#ifndef __FUN_H__
#define __FUN_H__
extern int my_add(int x, int y);
extern int my_sub(int x, int y);
extern int my_mul(int x, int y);
extern int my_div(int x, int y);
#endif
(2)创建并编写main.c
#include <stdio.h>
#include "fun.h"
int main(int argc, char const *argv[])
{
printf("%dn", my_add(10, 20));
printf("%dn", my_sub(10, 20));
printf("%dn", my_mul(10, 20));
printf("%dn", my_div(10, 20));
return 0;
}
(3)创建并编写makefile
main:main.o fun.o
gcc main.o fun.o -o main
main.o:main.c
gcc -c main.c -o main.o
fun.o:fun.c
gcc -c fun.c -o fun.o
clean:
rm *.o main
程序流程:当要执行第一个目标时没有找到main.o和fun.o,会往下寻找生成main.o和fun.o的指令,执行完生成main.o和fun.o的指令后才返回执行第一个指令。
问题:.o过多时相应的指令变多,可以利用makefile的变量优化
三、makefile的变量
1、自定义变量
makefile变量类似于C语言中的宏,变量名可以数字开头,大小写敏感,一般在头部定义。
变量名=变量值
取变量值:$(变量名)或${变量s
以二中较复杂实战为例做自定义修改:
//自定义变量
cc=gcc
exec=main
obj=main.o fun.o
//用自定义变量做部分修改
$(exec):$(obj)
$(cc) $(obj) ‐o $(exec)
main.o:main.c
$(cc) ‐c main.c ‐o main.o
fun.o:fun.c
$(cc) ‐c fun.c ‐o fun.o
clean:
rm *.o $(exec)
2、系统环境变量
make工具解析makefile前,读取系统环境变量并设置为makefile的变量。
linux下查看环境变量命令:env
linux下添加系统环境变量命令:export 要添加的变量名=变量值,举例:export cc=gcc.
3、预定义变量
4、高级makefile
以优化二中较复杂实战为例:
//自定义变量
cc=gcc
exec=main
obj=main.o fun.o
flags=‐Wall
//用自定义变量和预定义变量修改优化
$(exec):$(obj)
$(cc) $^ ‐o $@ $(flags)
%.o:%.c//此时只需一条语句即可完成多条编译语句
$(cc) ‐c $< ‐o $@ $(flags)
clean:
rm $(obj) $(exec)