来自 Makefile 子目录的源代码
我有一个使用 Makefile 构建的 C++ 库。直到最近,所有源代码都位于一个目录中,并且 Makefile 执行了类似
SOURCES = $(wildcard *.cpp)
的
操作,效果很好。
现在我添加了一些位于子目录中的源,例如 subdir
。我知道我可以这样做
SOURCES = $(wildcard *.cpp) $(wildcard subdir/*.cpp)
但我正在寻找一种方法来避免指定 subdir
手动,也就是说,让 wildcard
查看子目录,或者以某种方式生成子目录列表并使用多个 wildcard
函数扩展它。此时,有一个非递归解决方案(即仅扩展第一层)就可以了。
我没有找到任何东西 - 我最好的猜测是使用 find -type d 列出子目录,但这感觉就像黑客。有没有内置的方法可以做到这一点?
I have a C++ library built using a Makefile. Until recently, all the sources were in a single directory, and the Makefile did something like this
SOURCES = $(wildcard *.cpp)
which worked fine.
Now I've added some sources that are in a subdirectory, say subdir
. I know I can do this
SOURCES = $(wildcard *.cpp) $(wildcard subdir/*.cpp)
but I'm looking for a way to avoid specifying subdir
manually, that is, make wildcard
look into subdirectories, or generating a list of subdirectories somehow and expanding it with several wildcard
functions. At this point, having a non-recursive solution (that is, expanding only the first level) would be fine.
I haven't found anything - my best guess is using find -type d
to list the subdirectories, but it feels like a hack. Is there any built-in way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这应该可以做到:
如果您改变主意并想要一个递归解决方案(即任何深度),它可以完成,但它涉及一些更强大的 Make 函数。你知道,那些允许你做你不应该做的事情的人。
编辑:
Jack Kelly 指出,
$(wildcard **/*.cpp)
使用 GNUMake 3.81 可在任何深度工作,至少在某些平台上如此。 (他是怎么想出来的,我不知道。)This should do it:
If you change you mind and want a recursive solution (i.e. to any depth), it can be done but it involves some of the more powerful Make functions. You know, the ones that allow you to do things you really shouldn't.
EDIT:
Jack Kelly points out that
$(wildcard **/*.cpp)
works to any depth, at least on some platforms, using GNUMake 3.81. (How he figured that out, I have no idea.)递归通配符可以纯粹在 Make 中完成,无需调用 shell 或 find 命令。仅使用 Make 进行搜索意味着该解决方案也适用于 Windows,而不仅仅是 *nix。
文件夹名称中的尾部斜杠是必需的。这个 rwildcard 函数不像 Make 的内置通配符函数那样支持多个通配符,但是通过使用 foreach 来添加该支持将很简单。
Recursive wildcards can be done purely in Make, without calling the shell or the find command. Doing the search using only Make means that this solution works on Windows as well, not just *nix.
The trailing slash in the folder name is required. This rwildcard function does not support multiple wildcards the way that Make's built-in wildcard function does, but adding that support would be straightforward with a couple more uses of foreach.
如果您不想使用递归 makefile,这可能会给您一些想法:
If you don't want to use recursive makefiles, this might give you some ideas:
您可以在
wildcard
中使用多个规则:如果您需要更多深度:
不幸的是,与我们有时读到的不同,glob (
**
) 不受 makefile 支持,并且将被解释为普通通配符 (*
)。例如,
**/*.cpp
匹配dir/file.cpp
,但既不匹配file.cpp
也不匹配dir/sub/file。 cpp
.如果您需要无限深度,请使用
shell
和find
:You can use several rules in
wildcard
:if you need more depth:
Unfortunately, and unlike what we sometimes read, glob (
**
) is not supported by makefile and will be interpreted as normal wildcard (*
).For example
**/*.cpp
matchdir/file.cpp
but neitherfile.cpp
nordir/sub/file.cpp
.If you need infinite depth use
shell
andfind
:常见做法是放置一个
Makefile
位于每个带有源代码的子目录中,然后或者
将每个
Makefile
的设置放在根源目录的Makefile.inc
中可能是明智的。recursive
目标强制make
进入子目录。确保它不会重新编译需要递归的目标中的任何内容。Common practice is to put a
Makefile
in each subdir with sources, thenor
It may be wise to put settings for each
Makefile
in aMakefile.inc
in the root source directory. Therecursive
target forcesmake
to go into the subdirectories. Make sure that it doesn't recompile anything in a target requiringrecursive
.如果您可以使用
find
shell 命令,您可以定义一个函数来使用它。If you can use
find
shell command, you may define a function to use it.