Makefile 里的预定义变量

在 `Makefile` 中,GNU Make 提供了一组预定义变量,帮助用户方便地管理和控制编译和构建过程。了解这些预定义变量,可以让 `Makefile` 的编写更加简洁和灵活。以下是一些常用的 GNU Make 提供的预定义变量:

### 1. 自动化变量(Automatic Variables)

这些变量在规则(规则的形式是 `target: prerequisites`)的命令部分自动设置,常用于简化规则的编写。

- **$@**: 当前规则的目标文件(target)的名字。
  - 例子:在 `target: prerequisites` 中,`$@` 表示 `target`。
- **$<**: 当前规则的第一个依赖文件(prerequisite)的名字。
  - 例子:在 `target: srcfile1 srcfile2` 中,`$<` 表示 `srcfile1`。
- **$^**: 当前规则的所有依赖文件(prerequisites)的名字列表,以空格分隔,去除重复的依赖项。
  - 例子:在 `target: srcfile1 srcfile2 srcfile1` 中,`$^` 表示 `srcfile1 srcfile2`。
- **$?**: 当前目标比其依赖文件旧的所有依赖文件的名字列表,以空格分隔。
  - 例子:在 `target: srcfile1 srcfile2` 中,如果 `srcfile1` 比 `target` 新,`$?` 表示 `srcfile1`。
- **$%**: 目标文件是归档成员(ar 命令产生的库文件)的名字。例如,在 `lib.a(member.o)` 中,`$%` 表示 `member.o`。
- **$(@D)**: 当前目标文件路径中的目录部分。
  - 例子:对于目标 `dir/target`,`$(@D)` 表示 `dir`。
- **$(@F)**: 当前目标文件路径中的文件名部分。
  - 例子:对于目标 `dir/target`,`$(@F)` 表示 `target`。
- **$(*D)**: 当前第一个依赖文件路径中的目录部分。
  - 例子:对于依赖文件 `dir/source`,`$(*D)` 表示 `dir`。
- **$(*F)**: 当前第一个依赖文件路径中的文件名部分。
  - 例子:对于依赖文件 `dir/source`,`$(*F)` 表示 `source`。

### 2. 伪目标变量(Phony Targets)

这些变量用于标记一些不实际生成文件的目标,常用来表示一些执行动作(如清理、安装等)。

- **.PHONY**: 伪目标声明,用来告诉 `make` 不检查文件系统中是否存在同名文件。
  - 例子:
    ```makefile
    .PHONY: clean
    clean:
        rm -rf *.o
    ```

### 3. 默认变量(Default Variables)

这些变量提供了常见的编译和链接器的默认值,可以被覆盖。

- **CC**: 指定 C 编译器的名字,默认为 `cc`。
  - 例子:
    ```makefile
    CC = gcc
    ```
- **CXX**: 指定 C++ 编译器的名字,默认为 `g++`。
  - 例子:
    ```makefile
    CXX = g++
    ```
- **CFLAGS**: 指定传递给 C 编译器的选项。
  - 例子:
    ```makefile
    CFLAGS = -g -Wall
    ```
- **CXXFLAGS**: 指定传递给 C++ 编译器的选项。
  - 例子:
    ```makefile
    CXXFLAGS = -g -Wall
    ```
- **LDFLAGS**: 指定传递给链接器的选项。
  - 例子:
    ```makefile
    LDFLAGS = -lm
    ```
- **CPPFLAGS**: 指定传递给 C 和 C++ 预处理器的选项,通常用于定义宏或包含路径。
  - 例子:
    ```makefile
    CPPFLAGS = -I/usr/include
    ```
- **LDLIBS**: 指定传递给链接器的库文件,通常以 `-l` 开头。
  - 例子:
    ```makefile
    LDLIBS = -lpthread
    ```

### 4. 环境变量(Environment Variables)

GNU Make 允许在 `Makefile` 中使用环境变量,这些变量可以在命令行或环境中定义,然后被 `Makefile` 使用。

- **MAKEFLAGS**: 提供给 `make` 的标志和选项,例如并行执行的 `-j` 选项。
  - 例子:
    ```makefile
    MAKEFLAGS = -j4
    ```

### 5. 特殊目标(Special Targets)

这些变量和规则允许对 `make` 的行为进行特殊的控制。

- **.SUFFIXES**: 指定用于隐式规则的文件后缀列表。
  - 例子:
    ```makefile
    .SUFFIXES: .c .o .cpp
    ```
- **.DEFAULT**: 定义一个没有明确规则的文件的默认规则。
  - 例子:
    ```makefile
    .DEFAULT:
        @echo "No rule to make target '$@'"
    ```

### 示例 `Makefile`

以下是一个简单的 `Makefile` 示例,展示了如何使用这些预定义变量:

```makefile
# 定义变量
CC = gcc
CFLAGS = -g -Wall
TARGET = myprogram

# 目标和依赖
$(TARGET): main.o util.o
    $(CC) $(CFLAGS) -o $@ $^

# 生成 .o 文件的规则
%.o: %.c
    $(CC) $(CFLAGS) -c -o $@ $<

# 清理规则
.PHONY: clean
clean:
    rm -f *.o $(TARGET)
```

### 总结

GNU Make 的预定义变量简化了 `Makefile` 的编写和维护。了解并熟练使用这些变量,可以大大提高 `Makefile` 的效率和可读性。通过自动化变量、默认变量和特殊目标的结合,可以创建灵活且强大的构建系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值