首页 > 解决方案 > GNU makefile 中过滤器的必要性

问题描述

我有以下目录结构。

/home/user/
          ├── Makefile
          │ 
          ├── easy/
          │     └── a.cpp
          ├── medium/
          │       └── b.cpp
          └──  build/

我的目标是编译所有.cpp文件,easymediumbuild. 下面的 Makefile 实现了我想要的(省略与我的问题无关的部分)。我不明白的部分是第filter6 行调用的必要性。

  1 SOURCEDIRS = easy medium
  2 TARGETDIR = build
  3 
  4 SOURCES = $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.cpp))
  5 $(info $(SOURCES))
  6 TARGETS = $(foreach dir,$(SOURCEDIRS),$(patsubst $(dir)/%.cpp,$(TARGETDIR)/%.out,$(filter $(dir)/%,$(SOURCES))))
  7 $(info $(TARGETS))

输出:

# content of SOURCES
easy/a.cpp medium/b.cpp
# content of TARGETS
build/a.out build/b.out

具体来说,根据手册patsubst,我希望调用filter是多余的。

$(patsubst 模式,替换,文本)

在文本中查找与模式匹配的空格分隔的单词并将它们替换为替换。

来源

例如,我希望以下 Makefile 能够实现我的目标,

  1 SOURCEDIRS = easy medium
  2 TARGETDIR = build
  3 
  4 SOURCES = $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.cpp))
  5 $(info $(SOURCES))
  6 TARGETS = $(foreach dir,$(SOURCEDIRS),$(patsubst $(dir)/%.cpp,$(TARGETDIR)/%.out,$(SOURCES)))
  7 $(info $(TARGETS))

虽然内容TARGETS

# content of SOURCES
easy/a.cpp medium/b.cpp
# content of TARGETS
build/a.out medium/b.cpp easy/a.cpp build/b.out

我有什么误解?为什么我们需要filter在这种情况下?

标签: c++makefilegnu-makegnu

解决方案


patsubst不会删除与模式不匹配的单词。

$(patsubst easy/%.cpp,build/%.out,easy/a.cpp medium/b.cpp)不是build/a.out,是build/a.out medium/b.cpp


推荐阅读