菜鸟科技网

Cygwin make命令怎么用?

make 是一个自动化构建工具,它根据一个名为 Makefile 的文件来决定如何编译和链接程序,这在 C/C++ 等语言的项目开发中非常常见。

Cygwin make命令怎么用?-图1
(图片来源网络,侵删)

确认已安装 make

在 Cygwin 的安装过程中,make 包含在 "Devel" (开发) 类别的软件包中。

  1. 打开 Cygwin 的安装程序 (setup-x86_64.exesetup-x86.exe)。
  2. 确保你处于 "Install" 或 "Update" 模式。
  3. 在包列表中,展开 "Devel" 类别。
  4. 找到 make 包,确保它的状态是 "Default"(默认安装)或 "Skip"(跳过),如果不是,点击它将其设置为 "Default" 或 "Install"。
  5. 点击 "Next" 完成安装。

安装完成后,你可以通过以下命令验证 make 是否已正确安装:

make --version

如果安装成功,你会看到类似以下的输出,表明你正在使用 GNU Make:

GNU Make 4.4.1
Built for x86_64-pc-cygwin
Copyright (C) 1988-2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

make 的基本工作原理

make 的核心是 Makefile,Makefile 文件定义了一系列的 规则,每个规则都包含:

Cygwin make命令怎么用?-图2
(图片来源网络,侵删)
  • 目标: 一个文件名,通常是程序、目标文件(.o 文件)或可执行文件。
  • 依赖: 生成目标所需要的文件,如果依赖比目标文件新,make 就会执行规则中的命令来重新生成目标。
  • 命令: 一系列 Shell 命令,用于从依赖文件生成目标文件。

基本语法:

target: dependencies
    command

执行流程:

  1. make 首先在当前目录下寻找名为 Makefilemakefile 的文件。
  2. 它读取 Makefile,找到第一个 目标(也称为 入口目标)。
  3. 检查该目标的 依赖 文件是否存在。
    • 如果依赖文件不存在,make 会尝试在 Makefile 中找到生成该依赖文件的规则,并执行它。
    • 如果依赖文件比目标文件新,或者目标文件不存在,make 就会执行该规则下的 命令 来更新目标文件。
  4. 这个过程是递归的,直到所有需要的依赖都满足,最终生成最初的目标。

创建一个简单的 C 语言项目示例

让我们通过一个经典的 "Hello, World!" C 项目来演示 make 的用法。

项目结构

假设你的项目目录如下:

Cygwin make命令怎么用?-图3
(图片来源网络,侵删)
my_project/
├── hello.c
└── Makefile

hello.c 源代码

这是一个简单的 C 程序。

// hello.c
#include <stdio.h>
int main() {
    printf("Hello from Cygwin!\n");
    return 0;
}

Makefile 文件

这是 make 的核心,我们将创建一个简单的 Makefile 来编译 hello.c

# 定义变量,方便维护
CC = gcc
CFLAGS = -Wall -g
TARGET = hello
# 默认目标(第一个目标)
# 当你直接输入 make 时,make 会尝试构建这个目标
all: $(TARGET)
# 定义如何生成可执行文件 hello
# 它依赖于 hello.o 文件
hello: hello.o
    $(CC) $(CFLAGS) -o $@ $<
# 定义如何生成目标文件 hello.o
# 它依赖于 hello.c 文件
hello.o: hello.c
    $(CC) $(CFLAGS) -c -o $@ $<
# 清理生成的文件
clean:
    rm -f $(TARGET) hello.o
# 这是一个伪目标,防止目录下有名为 clean 的文件导致冲突
.PHONY: clean

Makefile 详解:

  • CC = gcc: 定义一个变量 CC,值为编译器 gcc
  • CFLAGS = -Wall -g: 定义一个变量 CFLAGS,值为编译选项(-Wall 显示所有警告,-g 包含调试信息)。
  • TARGET = hello: 定义变量 TARGET,值为最终可执行文件名。
  • all: $(TARGET): all 是一个常用的默认目标,它依赖于 $(TARGET)(即 hello),这意味着当你运行 makemake all 时,make 会去构建 hello 这个目标。
  • hello: hello.o: 定义 hello 的规则,它依赖于 hello.o 文件。
    • $(CC) $(CFLAGS) -o $@ $<: 这是命令。
      • 是一个自动化变量,代表 目标,这里是 hello
      • $< 是一个自动化变量,代表 第一个依赖,这里是 hello.o
  • hello.o: hello.c: 定义 hello.o 的规则,它依赖于 hello.c 文件。
    • $(CC) $(CFLAGS) -c -o $@ $<: 这是命令。
      • -c 选项告诉 gcc 只编译,不链接,生成 .o 文件。
      • 是目标 hello.o
      • $< 是依赖 hello.c
  • clean: ...: 定义一个 clean 目标,用于清理编译过程中产生的中间文件。
  • .PHONY: clean: 声明 clean 是一个 伪目标,伪目标不代表一个实际的文件,这可以防止当前目录下存在一个名为 clean 的文件时,make 认为它已经是最新的而不会执行清理命令。

如何使用 make 命令

打开 Cygwin 终端,进入到你的项目目录 (my_project)。

1 首次编译

hellohello.o 文件都不存在。

cd /path/to/my_project
make

输出:

gcc -Wall -g -c -o hello.o hello.c
gcc -Wall -g -o hello hello.o

make 会发现 hello.o 不存在,于是先执行 hello.o 的规则来编译 hello.c,然后发现 hello 不存在,于是执行 hello 的规则来链接 hello.o,最终生成 hello 可执行文件。

2 重新编译

hello 文件已经存在,我们修改一下 hello.c,比如在 printf 后面加一行注释,然后再次运行 make

// hello.c
#include <stdio.h>
int main() {
    printf("Hello from Cygwin!\n");
    // This is a new line.
    return 0;
}

再次运行 make

make

输出:

gcc -Wall -g -c -o hello.o hello.c
gcc -Wall -g -o hello hello.o

你会发现 make 重新执行了两个命令,这是因为 make 检查到 hello.c 文件比 hello.o 新,所以需要重新编译 hello.o,然后又检查到 hello.o 比最终的 hello 新,所以需要重新链接。

3 只编译修改过的文件

我们再次修改 hello.c,然后运行 make

make

输出:

gcc -Wall -g -c -o hello.o hello.c
gcc -Wall -g -o hello hello.o

和上次一样,但如果我们只是修改了一个不相关的文件,README.md,然后运行 makemake 会检查所有依赖,发现 hello.c 没有变化,hello.ohello 都比 hello.c 新,所以什么都不会做。

echo "some text" >> README.md
make

输出:

make: 'hello' is up to date.

这正是 make 的优势所在:它只重新构建那些需要被重新构建的部分,极大地提高了构建效率。

4 执行特定目标

如果你想清理编译文件,可以执行 clean 目标:

make clean

输出:

rm -f hello hello.o

hellohello.o 文件都被删除了,如果你想再次编译,可以再次运行 make

你也可以显式指定构建 all 目标:

make all

这和直接运行 make 效果一样。


常见问题与解决

问题1:make 不是内部或外部命令...

原因: 这通常意味着你没有在 Cygwin 的终端中运行命令,而是在 Windows 的 CMD 或 PowerShell 中运行,或者 Cygwin 的 bin 目录没有被添加到系统的 PATH 环境变量中。

解决:

  1. 确保使用正确的终端: 打开 Cygwin Terminal (cygwin64-terminal.execygwin-terminal.exe),它应该以 user@hostname ~ 开头。
  2. 检查 PATH: 在 Cygwin 终端中运行 echo $PATH,确保其中包含类似 /usr/bin 的路径,Cygwin 安装正确,这通常是自动配置的。

问题2:Makefile:1: *** missing separator. Stop.

原因: 这是最常见的 Makefile 语法错误,它表示在规则的目标和命令之间,必须使用 Tab 字符缩进,而不是空格。

解决:

  • 检查你的 Makefile 文件。
  • 确保 hello.o: hello.c 这一行下面的 gcc ... 命令行开头是一个 Tab 键,而不是用空格键缩进。
  • 很多文本编辑器(如记事本)默认用空格缩进,这会导致错误,推荐使用支持显示制表符的编辑器,如 VS Code、Notepad++、Vim 等。

问题3:make: *** No rule to make target 'xxx'. Stop.

原因: 你在命令行中指定了一个 make 目标(make build),但在 Makefile 中没有找到名为 build 的规则。

解决:

  • 检查 Makefile 中的目标名称是否拼写正确。
  • 如果你只想执行默认的构建规则,直接使用 makemake all 即可。

在 Cygwin 中使用 make 非常直接,与在 Linux 或 macOS 上的使用方式完全一致,关键点在于:

  1. 安装: 确保 make 包在 Cygwin 的 "Devel" 类别中被安装。
  2. 编写 Makefile: 核心工作,定义好目标、依赖和命令,特别注意使用 Tab 缩进
  3. 运行命令:
    • make: 构建默认目标。
    • make clean: 清理编译产物。
    • make all: 显式构建默认目标。

掌握 make 是进行 C/C++ 等项目开发的必备技能,它能极大地简化你的编译流程。

分享:
扫描分享到社交APP
上一篇
下一篇