简单Makefile教程:多文件编译/跨平台/删除生成/定义批量操作/处理一类文件

Makefile 是一种用来自动化编译、构建和管理软件项目的工具,它有很多好处,利用好Makefile可以让日常的工作流程更加简化和高效,以下是根据我日常使用习惯总结的一些Makefile的技巧

 简单Makefile教程:多文件编译/跨平台/删除生成/定义批量操作/处理一类文件_第1张图片

 1.实现多文件编译

假设有三个源文件:main.cutils.c 和对应的头文件 utils.h

CC = gcc
CFLAGS = -Wall -g  # 编译选项 -Wall 用于显示所有警告,-g 用于添加调试信息。
TARGET = myprogram  # 目标可执行文件名

# 指定编译规则
$(TARGET): main.o utils.o
    $(CC) $(CFLAGS) -o $(TARGET) main.o utils.o

main.o: main.c utils.h
    $(CC) $(CFLAGS) -c main.c

utils.o: utils.c utils.h
    $(CC) $(CFLAGS) -c utils.c

在Makefile中,头部可以定义变量和她对应的值,例如上面的CC,CFLAG,TARGET,而在下面就可以以$(变量名)的方式来调用

$(TARGET): main.o utils.o 表示 myprogram 的依赖文件是 main.o 和 utils.o,通过这两个文件来生成最终的可执行文件。main.o 和 utils.o 的规则定义了如何生成对应的 .o 文件。例如,main.o 依赖于 main.c 和 utils.h,当这两个文件有改动时,通过指定的编译器和编译选项生成 main.o,最终执行make命令即可完成这几个文件的编译操作。

Makefile的依赖关系:当你执行 make 命令时,Makefile 将会检查文件的依赖关系,如果某些源文件或头文件发生了改变,它会自动重新编译相关的部分,而不是重新编译整个项目。

2.跨平台使用 

在不同的平台其实编译的语句和方式都基本不差,差别只是在一些系统命令的调用

CC = gcc
CFLAGS = -Wall -g
RM = rm -f # linux平台下的删除
EXE = # linux平台下的生成文件
SPACE = echo "" # linux平台下的换行

ifeq ($(OS),Windows_NT)
	RM = del /Q
	EXE = .exe
	SPACE = @echo.
endif

 例如上面的一些删除换行和生成文件的后缀等,不同的平台有所区分,可以用一个if判断来识别当前的系统状态如何改变变量

3.删除生成文件

其实每次的编译和链接都会产生很多不必要的产出,如中间文件和可执行文件,我们可以通过定义简单的删除命令来删除他们

# 清理生成的文件
clean:
    rm -f $(TARGET) *.o

# 根据系统环境执行删除生成的可执行文件命令
$(RM) $@$(EXE)

 4.定义批量操作

可以使用.PHONY来自定义命令实现批量执行多个操作

.PHONY: build clean docs test

build: compile docs test

compile: main.c utils.c
    gcc -o myprogram main.c utils.c

docs:
    doxygen Doxyfile

test:
    ./run_tests.sh

clean:
    rm -f myprogram
    # 还可以添加其他清理操作,比如删除文档文件等

build 是一个伪目标,它依赖于 compile、docs 和 test 三个操作;compile 是编译的操作,它依赖于 main.c 和 utils.c;docs 是生成文档的操作,使用 doxygen 工具根据配置文件 Doxyfile 来生成文档;test 是运行测试的操作,假设有一个脚本 run_tests.sh 用来执行测试;clean 是用来清理生成的可执行文件和其他可能生成的文件;通过执行 make build,Makefile 将按照定义的顺序执行 compile、docs 和 test 操作

5.操作一类文件

可以用%来表示对应的文件名,%.c表示任意文件名的.c文件,都会依据CC指定的编译器在CFLAG这个附加参数下编译产生文件,@可以作为局部的变量指代生成文件

%: %.c # 编译所有.c文件
	$(CC) $(CFLAGS) $< -o $@ # 生成文件为@
	./$@$(EXE) # 执行生成文件
	$(RM) $@$(EXE) # 删除生成文件

你可能感兴趣的:(linux,服务器,c语言)