如何使用Makefile规则将.o文件放入单独的目录中

时间:2010-07-11 10:35:47

标签: c++ makefile

我有以下Makefile规则:

DIR = src
SOURCES = $(shell find $(DIR) -name "*.cpp")
OBJS := $(SOURCES:.cpp=.o)

使用此定义,我的所有.o文件都与它们的.cpp对应文件位于相同的目录(和子目录)中。这样的分配原则很快就会使项目目录变得混乱(有50多个文件)。我想为.o文件创建一个新的特定文件夹并将它们放在那里。我需要编写一个make规则来转换每个.o文件名,如下所示:

foo/bar/test.o —> objects/foo-bar-test.o

如何在Makefile中创建此类规则?提前谢谢!

4 个答案:

答案 0 :(得分:5)

我使用这样的规则:

$(ODIR)/%.o: $(SDIR)/%.cpp 
    $(CC) -c $(INC) -o $@ $< $(CFLAGS) 

其中

ODIR = object file output directory
SDIR = .cpp source file directory
INC = list of -I flags
CFLAGS = the usual

答案 1 :(得分:2)

你可以尝试从这样的事情开始:

DIR = src
SOURCES = $(shell find $(DIR) -name "*.cpp")
OBJS := $(SOURCES:%.cpp=obj/%.o)

obj/%.o: %.cpp
    $(CC) -c -o $@ $^

如果您不想搞乱默认构建规则(参考Michael Aaron Safyan的建议),您可以尝试按照以下方式:

DIR = src
SOURCES = $(shell find $(DIR) -name "*.cpp")
ODIR=obj
OBJS:= $(SOURCES:%.cpp=obj/%.o)
CP=cp
MKDIR=mkdir -p

$(ODIR)/%.cpp : %.cpp
    $(MKDIR) $(DIR $@)
    $(CP) $< $@

在将cpp文件编译到obj目录之前,会将其复制到obj目录中(请注意,如果依赖于包含文件驻留在源文件的同一目录中,这可能会导致一些问题)

答案 2 :(得分:2)

覆盖默认的构建规则通常不是一个好主意,因为使用默认值会带来更大的可移植性,更改它们可能会非常脆弱(相信我,我已经尝试过你之前提出过的问题。它可能适用于一个平台,但随后尝试交叉编译库或在不同的系统上构建它并且你敬酒)。我有两个建议,希望你能找到合意的。

  1. 定义一个“干净”的目标,清除“.o”文件的混乱,或者更好:
  2. 使用C++ Project Template(使用CMake),将“.o”文件放在“build”目录中。

答案 3 :(得分:2)

我不确定你是否可以直接使用这些修改来指定模式,但是你总是可以使用宏(至少在GNU make中)。一个例子可能是这样的:

define export_rule
objects/$(patsubst %.cpp,%.o,$(subst /,-,$(1))) : $(1)
    <<your rules here>>
endef


SOURCES = $(shell find $(DIR) -name "*.cpp")

$(foreach s,$(SOURCES), $(eval $(call export_rule,$(s))))

这定义了您想要的确切规则,避免(如上面提出的一些解决方案)名称冲突,以防两个具有相同名称的文件驻留在不同的目录中。