首页 > 解决方案 > 具有不同源类型的 Makefile 不会注意到 make.depend

问题描述

我希望我的 Makefile 接受不同的源文件类型。确实如此,但是当我更改包含文件时它不会重新编译。这是生成文件:

C_SOURCES       := $(wildcard *.c)          
CPP_SOURCES     := $(wildcard *.cpp)
CC_SOURCES      := $(wildcard *.cc)
ALL_SOURCES     := $(notdir $(C_SOURCES) $(CPP_SOURCES) $(CC_SOURCES))

C_OBJECTS       := ${C_SOURCES:.c=.o}
CPP_OBJECTS     := ${CPP_SOURCES:.cpp=.o}
CC_OBJECTS      := ${CC_SOURCES:.cc=.o}
ALL_OBJECTS     := $(notdir $(C_OBJECTS) $(CPP_OBJECTS) $(CC_OBJECTS))

#############################################################

all: a.out

a.out: $(ALL_OBJECTS)
    g++ -o $@ -g $^

%.o:    %.cpp
        g++ -c $@ -g $^

%.o:    %.cc
        g++ -c $@ -g $^

%.o:    %.c
        g++ -c $@ -g $^

clean:
    rm -f a.out
    rm -f *.o

make.depend: $(ALL_SOURCES) 
        g++ -MM $^ > $@ 

-include make.depend

以 *.o: 开头的行是最近添加的——我想知道它是否有帮助。没有效果。

make.depend 正在完成它的工作:我检查了它,它的依赖关系是正确的。(对于我的 MCVE,我有一个包含 date.h 的源文件 main.cpp。)

main.o: main.cpp date.h

的输出$(info $(ALL_OBJECTS))main.o

那么:我怎样才能让它识别包含的更改?

标签: makefile

解决方案


在提问时,显示运行命令的示例和打印的内容会很有帮助。鉴于您提供的 makefile,除了生成依赖文件之外,我会对 make 实际上运行任何命令感到惊讶。

那是因为:

C_OBJECTS       := ${C_SOURCES:     .c  =.o}

是无效的语法。或者更准确地说,它不会做你想做的事。它替换了每个单词末尾的文字字符串_____.c__(其中_是空格......所以不会让我只使用空格)C_SOURCESwith .o。当然你没有这些,所以基本上你的ALL_OBJECTS变量只包含你的源文件(因为替换没有改变)。

您可以使用:

$(info $(ALL_OBJECTS))

看看这里发生了什么。

这需要写:

C_OBJECTS       := ${C_SOURCES:.c=.o}
CPP_OBJECTS     := ${CPP_SOURCES:.cpp=.o}
CC_OBJECTS      := ${CC_SOURCES:.cc=.o}

makefile 中的空白非常棘手。你一定要小心你把它放在哪里,你不能在任何你喜欢的地方添加它。

我也不知道你为什么要使用notdir,因为你所有的文件都在当前目录中。

从技术上讲,使用编译器前端编译.c文件是不正确的。g++

ETA你的模式规则也不正确:你缺少-o编译器的选项;它们都应该相当于:

%.o:    %.c
        g++ -c -o $@ -g $^

更好的是使用标准的 make 变量,然后您可以自定义行为而无需重写所有规则:

CFLAGS = -g

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

推荐阅读