下面是我按照教程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)
?答案 0 :(得分:2)
在$(TARGET):$(OBJ)规则中为什么我应该/不应该做$(目标):$(OBJ)$(DEPS)?
runMutexVsAtomic
并不会立即依赖mutexVsAtomics.h
,mutexVsAtomics.o
的内容,除非您只需一步制作图片,但您不在此处因为你显式创建了一个中间目标文件。
你能解释一下规则%.o:更多细节吗?例如为什么%.c在那里?为什么那里有-c标志?什么是$
以%
开头的规则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)