我有一个使用Makefile构建的C++库.直到最近,所有的源都在一个目录中,Makefile做了这样的事情
SOURCES = $(wildcard *.cpp)
工作得很好.
现在我添加了一些子目录中的源代码subdir.我知道我能做到这一点
SOURCES = $(wildcard *.cpp) $(wildcard subdir/*.cpp)
但我正在寻找一种避免subdir手动指定的方法,即wildcard查看子目录,或以某种方式生成子目录列表并使用多个wildcard函数扩展它.此时,具有非递归解决方案(即,仅扩展第一级)将没有问题.
我没有找到任何东西 - 我最好的猜测是find -type d用来列出子目录,但感觉就像一个黑客.有没有内置的方法来做到这一点?
Bet*_*eta 74
这应该这样做:
SOURCES = $(wildcard *.cpp) $(wildcard */*.cpp)
Run Code Online (Sandbox Code Playgroud)
如果你改变主意并想要一个递归解决方案(即任何深度),它可以完成,但它涉及一些更强大的Make函数.你知道,那些允许你做你真的不应该做的事情.
编辑:
杰克·凯利指出,$(wildcard **/*.cpp)工程的任何深度,至少在某些平台上,使用gnumake的3.81.(他怎么想出来的,我不知道.)
Lig*_*ruk 20
递归通配符可以完全在Make中完成,无需调用shell或find命令.仅使用Make进行搜索意味着此解决方案也适用于Windows,而不仅仅是*nix.
# Make does not offer a recursive wildcard function, so here's one:
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
# How to recursively find all files with the same name in a given folder
ALL_INDEX_HTMLS := $(call rwildcard,foo/,index.html)
# How to recursively find all files that match a pattern
ALL_HTMLS := $(call rwildcard,foo/,*.html)
Run Code Online (Sandbox Code Playgroud)
文件夹名称中的尾部斜杠是必需的.这个rwildcard函数不像Make的内置通配符函数那样支持多个通配符,但是通过foreach的更多用法添加该支持将是直截了当的.
Chr*_*oph 16
如果您不想使用递归makefile,这可能会给您一些想法:
subdirs := $(wildcard */)
sources := $(wildcard $(addsuffix *.cpp,$(subdirs)))
objects := $(patsubst %.cpp,%.o,$(sources))
$(objects) : %.o : %.cpp
Run Code Online (Sandbox Code Playgroud)
通常的做法是Makefile在每个子目录中放入一个源代码
all: recursive
$(MAKE) -C componentX
# stuff for current dir
Run Code Online (Sandbox Code Playgroud)
要么
all: recursive
cd componentX && $(MAKE)
# stuff for current dir
recursive: true
Run Code Online (Sandbox Code Playgroud)
这可能是明智的,把设置每Makefile一个Makefile.inc根源目录.该recursive目标部队make进入子目录.确保它不会重新编译需要的目标中的任何内容recursive.
这是一个附注,并没有回答你的问题,但有一篇论文"Recursive Make Considered Harmful".值得一读.
链接在这里.http://aegis.sourceforge.net/auug97.pdf
您可以在 中使用多个规则wildcard:
SOURCES := $(wildcard *.cpp */*.cpp)
Run Code Online (Sandbox Code Playgroud)
如果您需要更多深度:
SOURCES := $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
Run Code Online (Sandbox Code Playgroud)
不幸的是,与我们有时读到的不同**,makefile 不支持glob ( ) 并且将被解释为普通的通配符 ( *)。
例如**/*.cpp匹配dir/file.cpp但既不是file.cpp也不是dir/sub/file.cpp。
如果您需要无限深度,请使用shell:
SOURCES := $(shell find . -name "*.cpp")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
62853 次 |
| 最近记录: |