Makefile

Makefile是一个特殊的文件,它告诉make工具如何编译和链接程序。用人话来说,你可以把Makefile看作是一份“食谱”,指导电脑如何一步步地“烹饪”出最终的软件“大餐”。下面是Makefile的一些基本概念,用通俗易懂的方式来解释:

  1. 目标(Targets)

    • 就像食谱中的菜名,目标是Makefile中的最终产物,比如一个可执行文件或一个库文件。
  2. 依赖(Dependencies)

    • 每个目标都有一些依赖,就像做菜需要各种原料。在Makefile中,依赖通常是源代码文件或其他中间产物。
  3. 规则(Rules)

    • 规则告诉make如何从依赖生成目标。就像食谱中的烹饪步骤,规则定义了编译和链接的具体命令。
  4. 自动变量

    • Makefile中有一系列自动变量,比如$@代表目标文件,$<代表第一个依赖文件。这些变量类似于食谱中的通用成分,如“盐少许”或“油适量”。
  5. 伪目标

    • 有些目标前面会加一个点(比如.PHONY),这表示它们不是实际的文件,而是一些特殊的规则或命令。就像食谱中的“准备工作”或“清理工作”。
  6. 继承

    • 在Makefile中,你可以定义一些通用的规则,然后让其他目标继承这些规则。这有点像食谱中的“基础酱料”,可以用于多种不同的菜。
  7. 条件判断

    • Makefile允许使用条件语句来决定是否执行某些规则,类似于食谱中根据不同的口味或食材选择不同的烹饪方法。
  8. 参数传递

    • 你可以在Makefile中定义变量,然后在规则中使用这些变量。这就像在食谱中列出所需的调料和原料,然后在烹饪步骤中使用它们。
  9. 清理

    • Makefile通常包含一个清理规则(如clean),用于删除所有编译生成的文件,以便从头开始。就像做完饭后清洗厨房。
  10. 并行执行

    • make可以并行执行多个规则,以加快编译速度。这有点像在厨房里同时用多个炉灶烹饪不同的菜。
变量赋值和预定义变量
Makefile 中的变量赋值运算符有四种,分别是 = := ?= += $ 符号表示取变量的值,当变量名多于一
个字符时,使用 "( )"
= 表示延迟展开赋值,即变量的值是在使用时才确定,可能会受到后面的赋值影响。例如, VAR_A = A
VAR_B = $(VAR_A) B VAR_A = AA ,那么最后 VAR_B 的值是 AA B ,而不是 A B
:= 表示直接赋值,即变量的值是在定义时就确定,不会受到后面的赋值影响。例如, VAR_A := A
VAR_B := $(VAR_A) B VAR_A := AA ,那么最后 VAR_B 的值是 A B ,而不是 AA B
?= 表示条件赋值,即只有当变量没有被赋值时,才使用等号后面的值作为变量的值。例如, VAR ?=
new_value ,如果 VAR 在之前没有被赋值,那么 VAR 的值就为 new_value ,否则保持原来的值不变。 += 表示追加赋值,即将等号后面的值追加到变量原来的值之后,形成一个新的值。例如, VAR +=
new_value ,如果 VAR 在之前没有被赋值,那么 VAR 的值就为 new_value ,如果 VAR 在之前被赋值为
old_value ,那么 VAR 的值就为 old_value new_value
$ 符的其他用法:
$^ 表示所有的依赖文件
$@ 表示生成的目标文件
$< 代表第一个依赖文件

注释和换行符
采用 # 进行一行注释
采用 \ 作为续行符

举个例子,一个简单的Makefile可能看起来像这样:

# 定义一个变量,相当于食谱中的原料列表
 CC=gcc 
CFLAGS=-Wall -g 
# 定义目标和依赖 
hello: main.o 
hello.o $(CC) $^ -o $@ 
# 定义如何生成main.o 
main.o: main.c 
$(CC) $(CFLAGS) -c $< 
# 清理规则 
clean: 
rm -f hello *.o

这个Makefile包含了几个基本的部分,下面是每个句子的详细解释:

1. **定义编译器变量**:
   ```makefile
   CC=gcc
   ```


   - 这里定义了一个名为`CC`的变量,它的值被设置为`gcc`,表示使用GCC编译器。在Makefile中,你可以在规则中引用这个变量来指定编译器。

2. **定义编译选项变量**:

   ```makefile
   CFLAGS=-Wall -g
   ```


   - `CFLAGS`变量被定义为包含编译选项`-Wall`和`-g`。`-Wall`选项告诉编译器打开所有警告信息,而`-g`选项用于生成调试信息。

3. **定义目标和依赖(规则)**:

   ```makefile
   hello: main.o hello.o
   ```


   - 这是一个规则,定义了名为`hello`的目标和它的依赖项`main.o`与`hello.o`。在Makefile中,冒号后面是目标,冒号前面是依赖。这个规则的含义是:如果要生成目标`hello`(通常是可执行文件),则需要先构建依赖项。

4. **定义链接命令**:

   ```makefile
   $(CC) $^ -o $@
   ```


   - 这是上面定义的`hello`规则的命令部分。`$(CC)`代表之前定义的编译器变量`CC`,`$^`代表所有的依赖项(这里是`main.o`和`hello.o`),`-o $@`指定了输出文件的名称,其中`$@`代表规则中定义的目标(这里是`hello`)。

5. **定义如何生成`main.o`**:

   ```makefile
   main.o: main.c
   ```


   - 这是另一个规则,定义了如何生成`main.o`目标文件。它依赖于`main.c`源文件。这个规则说明,要生成`main.o`,需要`main.c`源文件的存在。

6. **定义编译命令**:

   ```makefile
   $(CC) $(CFLAGS) -c $<
   ```


   - 这是上面`main.o`规则的命令部分。这里使用了`$(CC)`编译器变量和`$(CFLAGS)`编译选项变量。`-c`选项告诉编译器只进行编译操作,不进行链接。`$<`代表第一个依赖项,这里是`main.c`。

7. **定义清理规则**:

   ```makefile
   clean:
   ```


   - 这是清理规则的开始,`clean`是规则的名称,用于执行清理操作。在Makefile中,冒号后面通常跟着依赖项,但清理规则不需要依赖项。

8. **定义清理命令**:

   ```makefile
   rm -f hello *.o
   ```


   - 这是清理规则的命令部分,使用`rm`命令来强制删除(`-f`)名为`hello`的可执行文件和所有`.o`文件。

这个Makefile展示了如何使用变量、规则、自动变量和伪目标来构建简单的C程序,并提供了清理构建产物的方法。通过运行`make`命令,可以自动编译源代码并生成可执行文件;运行`make clean`可以清理这些构建产物。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值