【发布时间】:2018-01-02 22:37:42
【问题描述】:
我有一个有点复杂的源目录,并编写了一个makefile来编译它:
├── include
│ ├── subinc
│ │ ├── test_y.h
│ │ └── test_z.h
│ ├── test_w.h
│ └── test_x.h
├── makefile
├── src
│ ├── test_w.cpp
│ └── test_x.cpp
├── src2
│ ├── test_y.cpp
│ └── test_z.cpp
└── test.cpp
如下所示的 makefile 正在运行。但是,我有点困惑为什么。它似乎没有使用$(DEPS),因为当我在规则中回显它时,它会给出类似./include/./include/subinc/test_y.h 的路径。这很明显,因为 patsubst 行,但是将其更改为 patsubst %,%,$(INCLUDES) 也会破坏它......(也许这是整个问题的根源!)
但是,当我从规则 %.o 的依赖项列表中删除该常量时,会发生一些奇怪的事情,因此规则就是 %.o: $(SOURCES)。运行 make 时,它使用$(SOURCES) 中的第一项作为每次调用 g++ 创建目标文件的目标:
$ make
g++ -c -o test.o test.cpp -I./include -I./include/subinc
g++ -c -o src/test_x.o test.cpp -I./include -I./include/subinc
g++ -c -o src/test_w.o test.cpp -I./include -I./include/subinc
g++ -c -o src2/test_z.o test.cpp -I./include -I./include/subinc
g++ -c -o src2/test_y.o test.cpp -I./include -I./include/subinc
我认为这是有道理的,因为使用了$<。
但是当我从列表中取出第二个常量(头文件——有些甚至格式不正确)时,为什么只打印依赖列表中的第一个呢?
我的想法是 make 以某种方式智能地将列表中的 .cpp 文件与列表中相应的 .h 文件匹配,然后在每次运行规则时将它们从列表中删除......
谢谢
Makefile(工作版本,可能充满了不良做法...)
INCDIR=./include
SRCDIR=./src
CXX=g++
CXXFLAGS=-I$(INCDIR) -I$(INCDIR)/subinc
INCLUDES=$(shell find . -name "*.h" -o -name "*.hpp")
DEPS = $(patsubst %,$(INCDIR)/%,$(INCLUDES))
EXE=testexe
SOURCES=$(wildcard *.cpp) $(wildcard **/*.cpp)
OBJ=$(SOURCES:.cpp=.o)
####RULES
%.o: $(SOURCES) $(DEPS)
$(CXX) -c -o $@ $< $(CXXFLAGS)
$(EXE): $(OBJ)
g++ -o $@ $^ $(CXXFLAGS)
rm $(OBJ)
编辑
如果你想要一个 MCVE,每个 test_*.h 定义一个空类,如
class T*{
T*(); //defined in test_*.cpp to print "T* created"
~T*(); //defined in test_*.cpp to print "T* destroyed"
};
主要的test.cpp 文件只是创建一个指向每个类的指针,然后将其删除。
【问题讨论】:
标签: c++ unix makefile gnu-make gnu