GNU makefile 中过滤器的必要性
Necessity of filter in GNU makefile
我有以下目录结构。
/home/user/
├── Makefile
│
├── easy/
│ └── a.cpp
├── medium/
│ └── b.cpp
└── build/
我的目标是编译 easy
和 medium
中的所有 .cpp
文件,并在 build
中创建单独的可执行文件。下面的 Makefile 实现了我想要的(省略了与我的问题无关的部分)。我不明白的部分是第 6 行调用 filter
的必要性。
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 pattern,replacement,text)
Finds whitespace-separated words in text that match pattern and replaces them with replacement.
例如,我希望以下 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
?
patsubst
不删除与模式不匹配的词。
$(patsubst easy/%.cpp,build/%.out,easy/a.cpp medium/b.cpp)
不是 build/a.out
,而是 build/a.out medium/b.cpp
我有以下目录结构。
/home/user/
├── Makefile
│
├── easy/
│ └── a.cpp
├── medium/
│ └── b.cpp
└── build/
我的目标是编译 easy
和 medium
中的所有 .cpp
文件,并在 build
中创建单独的可执行文件。下面的 Makefile 实现了我想要的(省略了与我的问题无关的部分)。我不明白的部分是第 6 行调用 filter
的必要性。
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 pattern,replacement,text)
Finds whitespace-separated words in text that match pattern and replaces them with replacement.
例如,我希望以下 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
?
patsubst
不删除与模式不匹配的词。
$(patsubst easy/%.cpp,build/%.out,easy/a.cpp medium/b.cpp)
不是 build/a.out
,而是 build/a.out medium/b.cpp