Makefile动态规则,没有GNU-make模式

9

我有一组.cpp文件需要编译。这些.cpp文件位于一个分层目录结构中。我希望相应的.o文件都放在一个构建文件夹中。

以下是如何让GNU make列举文件:

SRCS = \
    $(wildcard $(CODE)/**/*.cpp) \
    $(wildcard $(CODE)/AlgebraLibraries/**/*.cpp) \
    $(wildcard $(CODE)/Calculator/Environments/**/*.cpp)

BARE_SRCS = $(notdir $(SRCS))
BARE_OBJS = $(BARE_SRCS:.cpp=.o)
OBJS = $(addprefix $(BUILD)/, $(BARE_OBJS))

做到这一步后,我不知道如何创建规则以从.cpp文件创建.o文件。 直觉上,我想做的是以下伪代码:

for i=0, N do  # <-- a for-loop!
  $(OBJS)[i]: $(SRCS)[i]   # <-- the rule!
    $(CPP) -c $(SRCS)[i] -o $(OBJS)[i] # <-- the recipe
end

当然,这不是有效的GNU make代码,但我相信你理解我在此尝试做什么。以下方法无效。
%.o: %.cpp
    $(CPP) -c $< -o $@

这行不通,因为GNU make会匹配百分号,假定.o文件与.cpp文件放在一起。

另一种方法是手动枚举所有规则作为显式规则,虽然我知道这种方法能够奏效,但会非常繁琐。肯定有更好的办法!

我一直在研究GNU make生成规则的能力,但似乎没有办法避开内置逻辑进行生成。如果能利用一些流程控制语句来生成所需规则就太好了,难道这对GNU make来说也太困难了吗?

总之,有没有办法使用GNU make实现我的目标呢?如果有,具体怎么做呢?

2个回答

18

这看起来需要用到一些高级的Make技巧:

all: $(OBJS)

define ruletemp
$(patsubst %.cpp, $(BUILD)/%.o, $(notdir $(1))): $(1)
    $$(CPP) -c $$< -o $$@
endef

$(foreach src,$(SRCS),$(eval $(call ruletemp, $(src))))

еҰӮжһңgccиҜ•еӣҫдёәdir1/dir2/file.cеҲӣе»ә$(BUILD)/dir1/dir2/file.oпјҢеӣ дёәзӣ®еҪ•з»“жһ„$(BUILD)/dir1/dir2дёҚеӯҳеңЁпјҢйӮЈд№ҲgccдјҡжҠұжҖЁеҗ—пјҹ - Tuxdude
2
谢谢,谢谢!我会继续阅读并看看是否可以使用它。我认为这就是我正在寻找的...一种抽象makefile语法的方法。顺便说一句,即使在我的情况下不应该尝试做我想做的事情,我确信在其他情况下尝试做的那种事情至少是合法的。我还开始考虑使用jam,但我不喜欢没有人再支持它的事实。 - user2125275
这个有效,顺便说一下。再次感谢!我的 makefile 看起来相当晦涩,但至少它作为一些可以在make中完成的示例。 - user2125275
@Tuxdude:试试看发生了什么。 - Beta
@user2125275:是的,抱歉这么晦涩,但Make不能很好地处理通配符,并且使用wildcard构建文件列表会留下许多松散的尾巴。 - Beta

2
如果$(BUILD)是常量,你可以直接执行以下操作:
$(BUILD)/%.o: %.cpp
    $(CPP) -c $< -o $@

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接