Skip to content

Makefile附录

为每个源文件分别生成可执行程序

makefile
# 指定目标平台的编译器和链接器
CC = gcc
CXX = g++

# 定义编译选项
CFLAGS = -Wall -std=c11
CXXFLAGS = -Wall -std=c++11

# 定义链接选项
LDFLAGS =

# 定义源文件列表
SRCS = $(wildcard *.c *.cpp)

# 定义可执行程序列表
EXES = $(SRCS:.c=) $(SRCS:.cpp=) $(SRCS:.cc=) $(SRCS.cxx=)

# 定义依赖关系
.PHONY: all clean

all: $(EXES)

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

%.o: %.cpp
    $(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS)
%.o: %.cc
    $(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS)
%.o: %.cxx
    $(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS)

# 查找当前目录下的所有可执行程序并进行删除
clean:
    find . -maxdepth 1 -type f -executable -exec rm -f {} \;

这里有个坑就是EXES是包含可执行程序和源文件的,所以删除的时间并没有使用rm -rf $(EXES)

目录中所有源文件编译成一个可执行程序

makefile
# 定义最终的目标
TARGET = main

# 指定目标平台的编译器和链接器
CC = gcc
CXX = g++

# 定义编译选项
CFLAGS = -Wall -std=c11 -g
CXXFLAGS = -Wall -std=c++11 -g

# 定义链接选项
LDFLAGS = -I ./

# 定义源文件列表
SRC = $(wildcard *.c*)

# 定义可重定向二进制文件列表
# 第一遍匹配.c文件 .c文件会替换为.o文件,.cpp文件还是.cpp文件 并且存在于OBJC中
# 如 源文件为 main.cpp test.c 替换后OBJC中为 main.cpp test.o
OBJC = $(patsubst %.c, %.o, $(SRC))
# 第二遍匹配.cpp文件 将OBJC(main.cpp test.o)中的文件名替换成如下模样 main.o test.o
OBJS = $(patsubst %.cpp, %.o, $(OBJC))

$(TARGET):$(OBJS)
    $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
    rm -rf *.o

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

%.o: %.cpp
    $(CXX) $@ -c $< $(CXXFLAGS) $(LDFLAGS)

.PHONY:clean
clean:
    rm -rf $(TARGET)

或者不编译成.o文件,直接从.c/.cpp源文件编译成可执行程序

makefile
# 定义最终的目标
TARGET = main

# 指定目标平台的编译器和链接器
CXX = g++

# 定义编译选项
CXXFLAGS = -Wall -std=c++11 -g

# 定义链接选项
LDFLAGS = -I ./

# 定义源文件列表
SRC = $(wildcard *.c*)

$(TARGET):$(SRC)
    $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS)

.PHONY:clean
clean:
    rm -rf $(TARGET)

直接复制Makefile文件内容可能出现的问题

当你在Makefile中看到这样的错误:“Makefile:26: *** 缺失分隔符。 停止。”,这通常意味着在Makefile的第26行缺少了必要的制表符(tab)或其他分隔符。

为了解决这个问题,请检查以下几点:

  1. 制表符与空格:确保你在命令行前面使用的是制表符而不是空格。许多文本编辑器默认使用空格代替制表符,你可能需要在编辑器的设置中更改这一行为,或者使用能够显示制表符和空格的编辑器来检查。
  2. 空行:有时候,在Makefile中的空行也可能导致这个错误。确保空行不会干扰你的规则。
  3. 续行:如果你的命令太长,需要分成多行来书写,确保续行的缩进是正确的。续行通常也需要以制表符开头。
  4. 隐式规则:确保你没有意外地创建了一个Makefile的隐式规则,这可能需要你在该行之前添加一个明确的规则来避免混淆。
  5. 编辑器问题:如果你从一个系统复制Makefile到另一个系统,或者使用了不兼容的文本编辑器,可能会引入不可见的特殊字符,这些字符可能会干扰Makefile的解析。

为了解决这个问题,你可以:

  • 打开你的Makefile在一个能够显示制表符和空格的文本编辑器中(比如Notepad++、Visual Studio Code、Vim等),并检查第26行附近是否有任何不规则的空格或制表符。
  • 尝试删除第26行附近的空行或不必要的空白字符。
  • 如果可能,重新键入第26行附近的代码,确保使用正确的制表符进行缩进。
  • 在Linux或Unix系统上,你可以使用cat -e Makefile命令来查看文件中的制表符和换行符。
  • 如果你确定问题是由于复制粘贴导致的,尝试在一个新的、干净的文件中重新输入Makefile的内容。