c++ - GNU makefile 规则和依赖项

标签 c++ linux makefile gnu-make

我一直在阅读大量有关如何编写 makefile 以在 Linux 上构建应用程序的书籍,但我对显然可以实现相同目标的许多不同方法感到非常困惑。

这是我到目前为止建立文件的想法。

SHELL = /bin/sh

CXX = g++
DEBUG = -g
CXXFLAGS = -std=c++11 -Wall -pedantic #-Wextra
CPPFLAGS =  -I. \
            -I./include

SOURCES =   foo1.cpp \
            foo2.cpp \
            foo3.cpp

OBJECTS = $(SOURCES:.cpp=.o)

以下规则成功地将每个源文件编译成一个目标文件,然后创建一个存档:

libfoo.a: $(OBJECTS)
    ar rvcs $@ $(OBJECTS)

%.o: src/%.cpp ./include/%.h
    $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< 

这也是做同样的事情:

libfoo.a: $(OBJECTS)
    ar rvcs $@ $(OBJECTS)

$(OBJECTS) : %.o:src/%.cpp
    $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< 

但是,这会失败并出现错误,即没有规则来创建目标 'foo1.o:%.h

libfoo.a: $(OBJECTS)
    ar rvcs $@ $(OBJECTS)

$(OBJECTS) : %.o:src/%.cpp %.o:%.h
    $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< 

有人可以解释为什么它不起作用以及哪种方法最好吗?

第一个选项将头文件列为依赖项,但第二个选项没有。这就是我选择第三种选择的动机。

如何使用选项 2 或 3 将 header 列为依赖项?

TIA

最佳答案

您在尝试 #2 和尝试 #3 中使用的功能是 static pattern rules语法如下所示:

<targets...> : <target-pattern> : <prerequisites...>

只能有两个冒号,不能三个。你应该把上面的尝试 #3 写成:

$(OBJECTS) : %.o : src/%.cpp %.h
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< 

请注意一件重要的事情:如果您创建任何 具有关联的 .h 文件的 .cpp 文件,则此规则将失败.只是说说。

关于c++ - GNU makefile 规则和依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29041748/

相关文章:

c - 如何正确识别我的构建平台?

c++ - 如何使用 CMake 链接库?

c++ - 使用反射 google protobuf 获取枚举值

c++ - 使 struct volatile 会使它的所有成员 volatile 吗?

c++ - 从数组中获取第二个字符串

python - SSH 命令立即退出,而不是作为 python 子进程保持事件状态

php - 32 位 Linux 和 PHP < 7 上的 MongoClient,无需重构

makefile - 尝试创建使用 make 连接文件的一般规则

c++ - 使用已在另一个已用库中定义的函数名称的库

linux - 无法通过管道传输 wget HTTP header 以进行 grep 处理