前言
这段时间所有的开发都是在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规则。这种嵌套规则的方式有助于管理多个目标的依赖关系和构建过程。
随想
其实吧,不管是哪种编译方式,按照更高效的来。知识太多忘了不要紧,记住个大概,等到用的时候再去搜一下,那时候不用深入了解,一下子就知道怎么用了。最重要的是提升自身的能力,多经历,多思考,对问题的了解才能更深入。