30

我正在尝试创建一个 Makefile,它将我的.o文件放在与源文件不同的目录中。我正在尝试使用模式规则,因此我不必为每个源文件和目标文件创建相同的规则。

我的项目结构类似于:

project/
 + Makefile
 + src/
   + main.cpp
   + video.cpp
 + Debug/
   + src/       [contents built via Makefile:]
     + main.o
     + video.o

我的 Makefile 看起来像:

OBJDIR_DEBUG = Debug
OBJ_DEBUG = $(OBJDIR_DEBUG)/src/main.o $(OBJDIR_DEBUG)/src/video.o

all: $(OBJ_DEBUG)

$(OBJ_DEBUG): %.o: %.cpp
    $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@

这不起作用,因为它在Debug/src/*.cpp.

我尝试了以下方法:

# Broken: make: *** No rule to make target `Debug/src/main.cpp', needed by `Debug/src/main.o'.  Stop.
# As a test, works if I change "%.cpp" to "Debug/src/main.cpp", though it obv. builds the wrong thing

# Strip OBJDIR_DEBUG from the start of source files
$(OBJ_DEBUG): %.o: $(patsubst $(OBJDIR_DEBUG)/%,%,%.cpp)
    $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@

# Broken:
#   Makefile:70: target `src/main.o' doesn't match the target pattern
#   Makefile:70: target `src/video.o' doesn't match the target pattern

# Add OBJDIR_DEBUG in target rule
OBJ = src/main.o src/video.o

$(OBJ): $(OBJDIR_DEBUG)/%.o: %.cpp
    $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@
4

3 回答 3

28

在重新阅读有关静态模式规则的文档后,我得出了以下似乎有效的模式规则。

$(OBJ_DEBUG): $(OBJDIR_DEBUG)/%.o: %.cpp
    $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c $< -o $@

我不确定这是最好的方法,我愿意接受建议。

于 2012-11-25T15:45:47.447 回答
4

您可以尝试从另一个目录中的源代码构建对象,而不是在另一个目录中构建对象:将您的 makefile 放在对象将要存在的目录中,并告诉 make 使用 VPATH 在其他地方查找源代码。如果所有目标文件都应该在同一个目录中结束,这将最有效。

于 2015-01-09T15:44:53.387 回答
0

通过在每个源上运行 GCC,在单独的构建目录中“复制”源树的 Makefile - https://stackoverflow.com/a/41924169/4224163

于 2017-02-06T14:48:07.893 回答