欢迎访问我的网站,希望内容对您有用,感兴趣的可以加入我们的社群。

Makefile基础

C/C++ 迷途小书童 1年前 (2023-09-15) 673次浏览 0个评论

引言

下面这个 C 语言的代码非常简单

#include <stdio.h>

int main()
{
    printf("Hello World!.\n");
    return 0;
}

Linux 下面,我们使用下面的命令编译就可以

gcc hello.c -o hello

但是随着项目的变大,势必会有越来越多的 .c 文件和 .h 头文件,再直接使用编译器指令就非常麻烦了,光输入文件名都会影响心情,而且还非常容易出错,比如下面的例子

gcc hello.c aaa.c bbb.c -lpthread -ltest1 -ltest2 -o hello

而且哪怕你只是修改一个文件,也需要重新编译所有的文件,白白浪费了很多的开发时间。要解决这个问题,最好的方式就是把工程的编译规则写下来,让编译器自动加载规则去进行编译。

要实现上述目标,需要2个工具,makeMakefile,它们是搭配使用的,各司其职

  • make:它可以帮助我们找出项目里面修改变更过的文件,并根据依赖关系,找出受修改影响的其他相关文件,然后对这些文件按照规则进行单独的编译,这样一来,就能避免重新编译项目的所有的文件。

  • Makefile:定义编译的规则、依赖关系,make 工具就能精准地进行编译工作

Makefile是什么

Makefile 是用于指定软件编译、链接的构建过程的文件,一般位于软件源代码的根目录下。通过定义一系列的规则,Makefile 告诉 make 工具应该如何编译和链接代码生成最终的可执行文件或库文件。

Makefile基本语法

Makefile 由一系列 rule 组成,rule 的基本格式是

target:prerequisites
command

这里,target 是所要生成的文件,prerequisites 是生成该 target 所依赖的文件或目标,command 是实际执行的命令。

Makefile示例

下面是一个简单的示例

app: main.o add.o
    gcc main.o add.o -o app

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

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

这段 Makefile 包含了3个 rule,它指定了 app 依赖 main.oadd.o,后两个又依赖各自的源码文件。make 将自动根据依赖关系完成编译。

所以,这时候的编译命令就变的非常简单,直接输入 make 即可生成可执行文件 app

Makefile常用知识点

Makefile 中可以定义变量,例如

objects = main.o kbd.o command.o display.o

prog: $(objects)
    cc $(objects) -o prog

使用 objects 变量表示多个目标文件,这样可以使语法更加简洁。

使用通配符可以批量指定一类目标,例如

.PHONY: clean
clean:
    rm *.o

这里使用 *.o 指定了所有 .o 文件为 clean 目标的依赖,这样 clean 时可以删除所有的 .o 文件。这里使用 .PHONY 声明伪目标,这些目标不对应实际文件。

一个规则也可以指定多个目标,例如

bigoutput littleoutput : text.g
    generate text.g -o bigoutput
    generate text.g -o littleoutput

上述例子中同时生成了 bigoutputlittleoutput

使用静态模式可以在规则中引用目标名,例如

%.o : %.c
    $(CC) -c $< -o $@

这个模式规则可以匹配所有的 .c.o 的转换。

支持自定义函数,例如

upcase = $(subst a,A,$(1))

a.o : a.c 
    $(CC) -c $(call upcase,$<) -o $@

这里使用 upcase 函数将参数转换为大写。

喜欢 (0)

您必须 登录 才能发表评论!