zxc-cppnb

导航

 

目标

目标的语法非常简单

targets: prerequisites
    recipes
    ...
或者
targets: prerequisites ; recipes
    recipes
    ...

当执行目标时,make会检测prerequisites中的所有文件是否存在,如果都存在则执行targets后的recipes
recipes必须用制表符缩进。
例如:

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

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

当你执行make main指令之后,make会查看main目标,发现需要一个main.o文件,如果当前目录有main.o则执行
gcc main.o -o main命令,否则会寻找main.o的目标,而main.o目标需要main.c文件,如果当前目录下有main.c
则执行gcc -c main.c -o main.o,这样生成main.o后进而执行main目标,当然main.c文件一般都是程序员编写的。
此外如果你在编译成功后再次,修改main.c文件,由于main.c文件比main.o新,再次执行make main时,会重新生成
main.o和main文件。
再看一个稍微复杂的例子:
现在有3个文件:main.c,tool.c,tool.h,它们都在同一目录下。

// main.c
#include <stdio.h>
#include "tool.h"

int main(){
    print_hello();
    return 0;
}
// tool.c
#include <stdio.h>
#include "tool.h"

void print_hello(){
    printf("hello world\n");
}
//tool.h
#ifndef TOOL_H
#define TOOL_H

void print_hello();

#endif
#makefile
tool.o: tool.c
	gcc -c tool.c -o tool.o

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

main: main.o tool.o
	gcc main.o tool.o -o main

如果成功编译以后,又修改了main.c但是没有修改tool.c,那么下次编译时只会执行main.o和main目标,这样就提高了编译效率
但是会发现这样的makefile写起来太麻烦了,比如tool.o目标需要tool.c接下来执行的代码大概率也会和tool.c相关,这样写了太多次
tool.c,通用性也不好,并且生成的目标也多写了一次。好在makefile有一些特殊变量可以解决这个问题:

$^ 当前目标的所有所需文件名
$@ 当前目标的目标名
$< 当前目标的所需文件中的第一个文件名

接下来,我们能把makefile写成这样:

#makefile
tool.o: tool.c
	gcc -c $^ -o $@

main.o: main.c
	gcc -c $^ -o $@

main: main.o tool.o
	gcc $^ -o $@

makefile脚本的解析过程

makefile是一个脚本语言但是它的解析过程有些不同,当执行make指令时,make会把makefile文件整体先替换一遍,变量的赋值和多目标生成在此步完成
第二次解析的时候才会执行脚本,这也是为什么编写目标的时候可以打乱顺序。

posted on 2025-09-19 17:19  Cpp_Nb  阅读(9)  评论(0)    收藏  举报