下面是我按照 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/

    10-13 07:39