GNU makefile 规则和依赖项
GNU makefile rules and dependencies
我一直在阅读大量有关如何编写 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)
以下规则成功地将每个源文件编译成一个 object 文件,然后创建一个存档:
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 $@ $<
有人可以解释为什么它不起作用以及哪种方法最好吗?
第一个选项将 header 文件列为依赖项,但第二个选项没有。这就是我选择第三个选项的动机。
如何使用选项 2 或 3 将 header 列为依赖项?
TIA
您在尝试 #2 和尝试 #3 中使用的功能是 static pattern rules,语法如下所示:
<targets...> : <target-pattern> : <prerequisites...>
只能有两个冒号,不能有三个。您应该将上面的尝试 #3 写为:
$(OBJECTS) : %.o : src/%.cpp %.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
请注意一件重要的事情:如果您创建任何 .cpp
文件但 没有 具有关联的 .h
文件,则此规则将失败。就说吧。
我一直在阅读大量有关如何编写 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)
以下规则成功地将每个源文件编译成一个 object 文件,然后创建一个存档:
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 $@ $<
有人可以解释为什么它不起作用以及哪种方法最好吗?
第一个选项将 header 文件列为依赖项,但第二个选项没有。这就是我选择第三个选项的动机。
如何使用选项 2 或 3 将 header 列为依赖项?
TIA
您在尝试 #2 和尝试 #3 中使用的功能是 static pattern rules,语法如下所示:
<targets...> : <target-pattern> : <prerequisites...>
只能有两个冒号,不能有三个。您应该将上面的尝试 #3 写为:
$(OBJECTS) : %.o : src/%.cpp %.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
请注意一件重要的事情:如果您创建任何 .cpp
文件但 没有 具有关联的 .h
文件,则此规则将失败。就说吧。