Makefile工程管理初探

     Makefile是一种用于工程管理的规则,一个工程中的源文件不计其数,如何通过一定的规范来指定哪些源文件需要编译,哪些源文件需要忽略,这一点很重要,Makefile提供了一种很好的工程管理的规则来实现对整个项目的编译和配置,试想而知,当一个工程包含几千个源文件和头文件的时候,你仅仅通过单条的命令一个一个的进行编译将是非常大的工程。

用户只需要通过简单的一句make指令就能实现对这个工程文件的类似一个脚本文件的实现,其基本语法是:

Target:prerequisite

        command

Target正如英文的意思指的是目标,prerequisite指的是依赖,command表示的是命令(注意:command前面必须用TAB键分隔,不然将不会成功),Target:prerequisite指定了两者的关系,说明要生成这些目标需要依赖某些文件,所有两者是有联系的。

比如,在开发中,我们会有一些文件,比如main.c、add.c、sub.c ,同时提供其对于的头文件为common.h 、add.h、sub.h

其对应的文件编写如下:

参考代码:https://download.csdn.net/download/qq_40793742/10406919

//---------main.c--------------- 

#include <stdio.h>

#include "add.h"

#include "sub.h"

void main()
{
int a = 1;
int b = 2;

printf("add is %d\n", add(a,b));
printf("sub is %d\n", sub(a,b));

}

//------------add.c-----------------

#include "add.h"

int add(int x, int y)
{
return x+y;
}

//------------sub.c-----------------

#include "sub.h"

int sub(int x, int y)
{
return x-y;
}
 

//------------add.h-----------------

#ifndef _ADD_H_
#define _ADD_H_

#include <stdio.h>
int add(int x, int y);
 

#endif /*_ADD_H_*/

//------------sub.h-----------------

#ifndef _SUB_H_
#define _SUB_H_

#include <stdio.h>
int sub(int x, int y);
 

#endif /*_SUB_H_*/

生成上述这些文件的TARGET文件,可以通过

方式一:直接生成目标文件

gcc -o TARGET main.c add.c sub.c  最终生成ELF文件 x86

方式二:有时候我们还需要产生中间的.o文件以便我们进行分析和链接

在linux下面我们知道,要编译这些文件我们可以分别将这些文件先只编译不链接,生成各自的.o文件

通过gcc -c xxx.c

arm-linux-gcc -c *.c           (这里的*.c表示任意的.c文件,分开写sub.c main.c add.c)

gcc -o TARGET *.o                (这里*.表示所有的.o文件 分开写 sub.o main.o add.o)

方式三:同时也可以创建一个脚本文件来实现上述功能

#vi genbash

编写下面的内容

#!/bin/bash

arm-linux-gcc -c *.c   

gcc -o TARGET *.o    

保存后,

通过终端运行

#bash genbash 来生成代码

那么运用Makefile会有什么好处呢?

下面分三种情况来说明Makefile的优势

#vi Makefile

下面探讨一下下面三个Makefile程序,实现的功能是一样的,你会选择哪个?

//------------------------

TARGET:main.c sub.c add.c
gcc -o TARGET main.c sub.c add.c
clean:

rm -f  TARGET

//------------------------

TARGET:main.o sub.o add.o
gcc -o TARGET main.o sub.o add.o

main.o:main.c
gcc -c main.c

add.o:add.c
gcc -c add.c

sub.o:sub.c
gcc -c sub.c

clean:

rm -f *.o TARGET

//------------------------

CC := gcc
TARGET:main.o sub.o add.o

$(CC) -o $@ $^

%.o:%.c
$(CC) -c $^
clean:
rm -f *.o TARGET

//------------------------

CC := gcc
OBJS := main.o sub.o add.o
TARGET:$(OBJS)
$(CC) -o $@ $^

%.o:%.c
$(CC) -c $^

clean:

rm -f *.o TARGET

//------------------------

编写Makefile,通过终端输出make即可实现对所有文件的编译工作,是不是很强大

上面引入的伪目标和

伪目标的格式

.PHONY : NAME

NAME :

        Command

可见伪目标和Makefile的规则相似,通过 .PHONY声明它是伪目标,不过现在的编译器做的已经不错了,现在也可以不要加入

.PHONY : NAME也能识别是伪目标。通过伪目标可以方便的实现清除,下载等工作,比如

make clean   (清除工作)

make write2sd ( 迅速将文件写到SD卡)

伪目标和Makefile的规则不要的是它不需要依赖关系,这是它俩的区别所在

在第三个Makefile和第四个Makefile中引入的一些变量,其概念如下:

# $@: 目标集合
# $<: 依赖中的第一个
# $^: 所有依赖文件集合
#        %.o: 所有的.o

#  %.c:所有的.c文件

参考:https://blog.csdn.net/haoel/article/details/2886/  陈皓 跟我一起写Makefile

猜你喜欢

转载自blog.csdn.net/qq_40793742/article/details/80261454