Linux项目自动化构建工具-make/Makefile

背景

●  会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力

●  一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作

●   makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

●  make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。

●  make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。(makefile的首字母大小写都可以)

理解

●  依赖例子

实例代码

c代码

#include<stdio.h>
  
#define column 10
int main()
{
       int n = column;
       while(n--)
       {
            printf("Hello Linux!%d\n",n);                            
       }
           return 0;

}

makefile文件

test:test.o

     gcc -o test test.o
test.o:test.s
     gcc -c test.c -o test.o
 test.i:test.c                                                     
      gcc -E test.c -o test.i 
  test.s:test.i
      gcc -S test.i -o test.s
  
 .PHONY:clean  (后面讲解)
 clean:
      rm -f test.i test.s test.o test

依赖关系

●   上面的文件 test ,它依赖 tets.o

●   test.o , 它依赖 test.s

     test.s , 它依赖 test.i

●   test.i  , 它依赖test.c

依赖方法

●   gcc test.* -option test.* ,就是与之对应的依赖关系

原理

●  make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,

1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件, 并把这个文件作为最终的目标文件。

3. 如果test文件不存在,或是test所依赖的后面的test.o文件的文件修改时间要比test这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成test这个文件。

4. 如果test所依赖的test.o文件不存在,那么make会在当前文件中找目标为hello.o文件的依赖性,如果找到则再根据那一个规则生成hello.o文件。(这有点像一个堆栈的过程)

5. 当然,你的C文件和H文件是存在的啦,于是make会生成 test.o 文件,然后再用 test.o 文件声明 make的终极任务,也就是执行文件hello了。

6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错, 而对于所定义的命令的错误,或是编译不成功,make根本不理。

8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦。

项目清理

●  工程是需要被清理的

●   像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

●  但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
●  可以将我们的 test 目标文件声明成伪目标,测试一下。

.PHONY伪目标

".PHONY"是Makefile的一个特殊目标。它用于声明一个伪目标,告诉make不要去查找同名的文件或目录,而是执行该目标下的命令。这通常用于定义一些不产生任何文件的命令,如"clean"、"all"等。在Makefile中,".PHONY"通常被用于声明伪目标,以方便使用make命令执行相应的操作,而不必判断是否存在同名的文件或目录。例如:

```
.PHONY: all clean

all: main.o func.o
        gcc -o main main.o func.o

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

func.o: func.c
        gcc -c func.c

clean:
        rm -f *.o main
```

在上述Makefile中,".PHONY"被用于声明"all"和"clean"是伪目标。这样做的优势在于,即使已经存在名为"all"或"clean"的文件或目录,make仍然能够执行相应的操作。

实际操作中的问题和技巧

1.技巧

1.1依赖方法中:

$@:代表依赖关系中冒号左边
$^:代表依赖关系中冒号右边

1.2gcc前加@执行时不会回显

2.使用make

1.为什么?        

提供编译效率
2.可以执行的条件         

一定是源文件形成可执行,现有源文件,才有可执行,一般而言, 源文件的最近修改时间比可执行文件要早的!如果我们更改了源文件,历史上曾经还有可执行,那么源文件的最近修改时间,一定要比可执行程序要新!

3.怎么做到的?

只需要比较,可执行程序的最近修改时间和源文件的最近修改时间

.exe新于.c源文件是老的,不需要重新编译


.exe老于.c源文件是老的,需要重新编译
而在Linux比较的最好的方法就是比较时间戳的大小。

3.那么要比较哪个时间呢?

stat是一个命令使用程序,用于显示给定文件或文件系统的详细信息。

由于本地Linux虚拟机使用的是中文,可能跟大家不同,这里说明一下

Access   - 最近访问  :access更新策略,根据modify和change一定的更新次数才能更新,每个操作系统的更新策略不同

Modify    - 最近更改  :修改文件内容时连同Change的时间一起修改,make比较的就是这个时间。

Change  - 最近改动  :修改文件信息时,更新时间,如名字,路径等。

4.手动更新文件时间-touch

4.1更新Access和Change时间

touch -m test.c

4.2更新Modify和change时间

touch -a test.c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值