下面是我按照 here 教程中的步骤生成的 makefile
我只有两个 mutexVsAtomics.c 和 mutexVsAtomics.h,它们生成 mutexVsAtomics.o 和 runMutexVsAtomic(可执行文件)。
在教程中解释了以 %o:
开头的规则应该涵盖我更改 .h 文件然后编译 c 文件的情况。经过更多阅读和查看示例后,我注意到规则的 :
部分之后的任何内容都是“依赖项”列表,并将导致规则执行。
所以我只是在 $(DEPS)
规则中添加了 .h (即 $(TARGET):
)文件,如果我修改标题,现在也可以编译。所以我对一些事情感到困惑。
这是我完成教程后的代码/makefile....似乎一切正常:
# Target binary filename
TARGET = runMutexVsAtomic
# Compiler
CC = g++
# Compiler Flags
CFLAGS = -std=c++11
# Include paths
PATHS = -I.
# Libraries
LIBS = -lpthread
# Include files
DEPS = mutexVsAtomics.h
#Object files
OBJ = mutexVsAtomics.o
### WHAT DOES THIS REALLY DO?... WHAT IS `$<`?###
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(PATHS) $(CFLAGS)
# Build rule - if any OBJ file or DEPS file is newer then target, then run the command line
$(TARGET): $(OBJ) #### WHY NOT JUST ADD `$(DEPS)` HERE? ###
$(CC) -o $@ $^ $(LIBS) $(PATHS) $(CFLAGS)
clean:
rm -f ./*.o $(TARGET)
我在我的问题所在的地方添加了评论,但这里是明确的:
$(TARGET): $(OBJ)
规则中,为什么我应该/不应该只执行 $(TARGET): $(OBJ) $(DEPS)
? %.o:
吗?例如为什么 %.c
在那里?为什么那里有 -c 标志?什么是 $<
?为什么我们不指定 $(LIBS)
? 最佳答案
runMutexVsAtomic
不会立即依赖于 mutexVsAtomics.h
的内容,mutexVsAtomics.o
会,除非您是一步制作图像,而您不在这里是因为您明确创建了一个中间目标文件。
以 %
开头的规则是 pattern rules 将匹配指定的模式。 %
中的 %.c
将替换目标中 .o
之前出现的任何内容(旁注:此规则看起来应该是 %.cpp
或 %.cc
,因为您使用的是 g++
和 -std=c++11
)。-c
是一个 compiler 标志,它告诉编译器只编译而不链接最终图像,即制作目标文件。$<
是用第一个先决条件替换的 make automatic variable。
您在创建对象时不指定 LIBS
,因为您没有在此步骤中进行链接。
记住 make 已经有你正在做的事情的食谱,所以通过一些小的调整你的 makefile 可以缩短如下:
TARGET := mutexVsAtomics
OBJS := mutexVsAtomics.o
CC := g++
CPPFLAGS := -MMD
CXXFLAGS := -std=c++11
LDLIBS := -lpthread
$(TARGET): $(OBJS)
.PHONY: clean
clean: ; $(RM) $(OBJS) $(OBJS:.o=.d) $(TARGET)
-include $(OBJS:.o=.d)
关于c++ - 我不明白我使用教程创建的这个 makefile 的某些部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36470017/