我有以下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
中创建此类规则?提前谢谢!
答案 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)
覆盖默认的构建规则通常不是一个好主意,因为使用默认值会带来更大的可移植性,更改它们可能会非常脆弱(相信我,我已经尝试过你之前提出过的问题。它可能适用于一个平台,但随后尝试交叉编译库或在不同的系统上构建它并且你敬酒)。我有两个建议,希望你能找到合意的。
答案 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))))
这定义了您想要的确切规则,避免(如上面提出的一些解决方案)名称冲突,以防两个具有相同名称的文件驻留在不同的目录中。