24 / 07 / 08
创建 Makefile 并写入以下内容。
CFLAGS=-Wall -g clean: rm -f ex1
$ make clean不能移除生成的文件
废话孩子……你写的是 helloworld 不是 ex1。
make 报错
*** missing separator. Stop.
复制粘贴一时爽,空格 TAB 火葬场……让我去看看怎么把 nano 改成四空格(万能的 man 啊)。
创建目标
all:ex1,可以以单个命令make构建ex1。
CFLAGS=-Wall -g all:helloworld clean: rm -f helloworld
阅读
man make来了解关于如何执行它的更多信息。
make 是一个读取Makefile 文件控制编译和构建程序的程序。
**目标 (Target)**:要生成的文件或执行的动作。
**依赖 (Dependency)**:目标所依赖的文件。
**规则 (Rule)**:定义如何根据依赖生成目标。
**命令 (Command)**:实现规则的具体命令。
基本结构:
target: dependencies
command
执行 make 时,工具会根据规则检查目标和依赖的时间戳,决定是否需要重新构建目标。
阅读
man cc来了解关于-Wall和-g行为的更多信息。
-Wall:启用所有常见的警告,帮助发现潜在的问题和错误。它是 “Warning all”的缩写,非常有用,尤其是在开发阶段。
-g:生成调试信息,使生成的可执行文件包含调试符号。
在互联网上搜索Makefile文件,看看你是否能改进你的文件。
CFLAGS = -Wall -g #定义编译器标志。-Wall 启用所有常见的警告,-g 生成调试信息。 LDFLAGS = #定义链接器标志。此处为空,但可以用来指定库路径和库文件。 TARGET = helloworld #定义要生成的目标可执行文件名称。 SRCS = helloworld.c #定义源文件。 OBJS = $(SRCS:.c=.o) #将源文件扩展名从 .c 转换为 .o 以得到目标文件。 all: $(TARGET) #默认目标,生成目标可执行文件。 $(TARGET): $(OBJS) #定义如何链接目标文件生成可执行文件。 $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) %.o: %.c #定义通用规则,编译 .c 文件生成 .o 文件。 $(CC) $(CFLAGS) -c $< -o $@ clean: #定义清理规则,删除目标文件和可执行文件。 $(RM) $(OBJS) $(TARGET) .PHONY: all clean #声明伪目标,避免与文件名冲突。
变量使用:将源文件和目标文件定义为变量,便于管理和修改。
通用规则:使用通配符规则编译 .c 文件到 .o 文件。
依赖文件:明确定义目标和依赖关系。
$(RM) 变量:使用 $(RM) 变量,更加通用和可移植。
.PHONY 目标:声明伪目标,避免与文件名冲突。
在另一个C语言项目中找到
Makefile文件,并且尝试理解它做了什么。
verilator 的 Makefile 为例(我为什么要折磨自己……):
项目版本和路径:
VERSION, VLVERNUM:定义了 Verilator 的版本信息。
TOPDIR:定义了项目的顶级目录。
构建工具:
CXX, CC:定义了 C++ 和 C 编译器。
CXXFLAGS, CFLAGS:定义了编译器选项。
依赖库和路径:
LDFLAGS, LDLIBS:定义了链接器选项和库。默认目标:
all:默认目标,构建所有需要的文件。构建目标:
bin/verilator, bin/verilator_bin_dbg 等:定义了具体可执行文件的构建规则。安装目标:
install:用于安装 Verilator 到指定目录。清理目标:
clean:用于清理构建过程中生成的中间文件。
distclean:用于清理所有生成的文件,恢复到最初状态。