makefile复习

Posted by Dandan on November 18, 2021

前言

这段时间所有的开发都是在openwrt的框架之内,openwrt的集成度非常高,所开发的功能要引用的库、头文件基本上都差不多,所以开发的工具编译都是写的cmake进行编译的。最近要用别的系统软件包做开发,发现上边已有的功能基本上都是手写makefile,我觉得cmake功能还是挺强大的,就依旧“我行我素”用起了cmake。
后来做完了进行移交给别的组,其他人接着搞,然而他们不知道cmake写的啥,我晕,,,认为应该是makefile才符合作为一个C程序员的风格,都什么年代了。后来各种说,好吧,我甘拜下风,重新写起了makefile。

简介

Makefile是一个文本文件,其中包含了一系列规则,指定了如何编译和链接程序的步骤。

简单的框架

# Makefile示例

# 编译器和编译选项
CC = gcc
CFLAGS = -Wall -Iinclude -g

# 目标文件名
TARGET = my_program

# 目录结构
SRC_DIR = src
OBJ_DIR = obj
INCLUDE_DIR = include
LIB_DIR = lib

# 源文件和对象文件
SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))

# 静态库文件
LIBS = -lm

# 默认目标
all: $(TARGET)

# 目标:依赖文件
$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^ -L$(LIB_DIR) $(LIBS)

# 生成对象文件
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
	@mkdir -p $(OBJ_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

# 清理中间文件和可执行文件
clean:
	rm -rf $(OBJ_DIR) $(TARGET)

变量

变量是Makefile中的一种命名值,它们用于存储文本字符串,您可以在Makefile的不同部分引用这些值。在Makefile中,变量通常使用等号(=)来赋值。例如:

CC = gcc
CFLAGS = -Wall -O2

我们定义了两个变量:CC表示编译器的名称,CFLAGS表示编译选项。您可以在Makefile中的其他地方使用这些变量,如下所示:

$(CC) $(CFLAGS) -o my_program my_program.c

使用gcc作为编译器,并将-Wall -O2作为编译选项来编译my_program.c文件。

函数

Makefile还提供了一些内置函数,可以使用这些函数对变量进行操作和转换。以下是一些常用的内置函数:

  • $(wildcard pattern):匹配文件名模式并返回符合条件的文件列表。
  • $(patsubst pattern,replacement,text):替换文本中的模式。
  • $(notdir names):从文件名中去除目录部分。
  • $(dir names):提取文件名中的目录部分。

例如,您可以使用wildcard函数来查找所有的C源文件:

SRC_FILES := $(wildcard *.c)

伪目标

伪目标是Makefile中的目标,它们不表示要构建的文件,而是表示要执行的操作或任务。伪目标通常用来执行一些常见的操作,如清理文件、生成文档等。定义伪目标时,通常使用特殊的.PHONY声明,以告诉Make,这是伪目标而不是实际的文件名。例如:

.PHONY: clean
clean:
    rm -f *.o my_program

这里,clean是一个伪目标,它定义了一个用于删除中间文件和可执行文件的操作。

嵌套

Makefile允许您在一个规则中嵌套另一个规则,这有助于组织和管理复杂的构建过程。嵌套规则通常使用Tab键缩进来指示。例如:

all: my_program

my_program: main.o util.o
    $(CC) $(CFLAGS) -o $@ $^

main.o: main.c
    $(CC) $(CFLAGS) -c $< -o $@

util.o: util.c
    $(CC) $(CFLAGS) -c $< -o $@

在这个示例中,all规则依赖于my_program规则,而my_program规则又依赖于main.o和util.o规则。这种嵌套规则的方式有助于管理多个目标的依赖关系和构建过程。

随想

其实吧,不管是哪种编译方式,按照更高效的来。知识太多忘了不要紧,记住个大概,等到用的时候再去搜一下,那时候不用深入了解,一下子就知道怎么用了。最重要的是提升自身的能力,多经历,多思考,对问题的了解才能更深入。