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
:用于清理所有生成的文件,恢复到最初状态。