我需要编写一个预构建 makefile,该文件与主构建文件分开调用。该 make 文件应该在调用它的目录中进行遍历。另一个名为“sources.mk”的 make 文件中有一个目录列表,其中包含一个描述该目录的变量:
SUBDIRS := \
. \
directory1 \
directory2 \
现在,我需要通过这个列表运行一个循环,在这个循环中我需要调用一个实用程序来处理所有带有“h”扩展名的文件。我写的是:
include Default/sources.mk
find_files:
for prefix in $(SUBDIRS); do \
for file in *.h; do \
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $$prefix/$$file; \
done \
done
运行命令:make -f premake.mk
我没有描述错误,有很多错误,我尝试了不同的 makefile,但我是新手,这些尝试失败了。请检查我的代码和/或建议其他方法。
最佳答案
您的问题可能只是一件简单的事情:您正在寻找 file
在*.h
在当前目录中,而不是在子目录中。试试这个:
for prefix in $(SUBDIRS); do \
for file in $$prefix/*.h; do \
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $$file; \
done \
done
话虽如此,更好的方法是使用 make
来处理所有文件(并决定是否所有文件都需要重新处理!),而不是在规则中使用显式循环。您将从头文件列表开始,正如 Eldar Abusalimov 的回答所建议的那样:
moc_headers := $(wildcard $(SUBDIRS:%=%/*.h))
其内部部分将 SUBDIRS 列表操作为 directory1/*.h
形式, directory2/*.h
,依此类推,然后是 wildcard
功能扩展了所有 *.h
模式。
然后,您可以从中生成输出文件列表:
moc_mocfiles := $(patsubst %.h, %_moc.cpp, $(moc_headers))
这需要扩展的头文件列表 directory1/header1.h
, directory1/header2.h
,依此类推,并替换 %.h
模式与 %_moc.cpp
。 (请注意,由于这些名称都将目录名称作为名称的一部分,因此您无法轻松使用更常见的 moc_%.h
名称模式,因为您会得到 moc_directory1/header1.cpp
,而不是所需的 directory1/moc_header1.cpp
。有一些方法可以解决这个问题,但更容易避免这个问题。)无论如何,这都会为您提供输出文件列表:directory1/header1_moc.cpp
, directory1/header2_moc.cpp
,等等。
现在您已经有了输出文件列表,Make 知道如何轻松地迭代这些文件。您只需将该列表声明为您正在制定的其他目标的先决条件,例如:
find_files: $(moc_mocfiles)
最后,你给出了一个创建 *_moc.cpp
的通用规则。文件来自 *.h
文件:
%_moc.cpp: %.h
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $< -o $@
其中,第一行表示“如果您有一个适合 %_moc.cpp
模式的文件来制作它,那么这就是创建适合 %.h
模式的文件的方法”。在第二行中,$<
成为输入文件(%.h
文件),并且 $@
成为输出文件。在这里,您明确告诉 moc.exe
与 -o
选项以 %_moc.cpp
吐出文件名称而不是默认使用的名称。
因此,将所有这些放在一起,当您制作 find_files
时目标,make 会意识到它需要制作所有这些 %_moc.cpp
文件在 moc_mocfiles
列表,对于每一个,它都会看到它有一个可能适合的规则,它会看到该规则适用,因为相应的 %.h
文件存在,它将应用该规则。
这还有一个优点,如果 %_moc.cpp
文件已存在且比 %.h
新文件,表明它已经是最新的,下次运行 make 时不会费心重新生成它。它只会重新生成%.h
对应的文件。您编辑过的文件。
(哦,最后一件事:从这个答案中剪切并粘贴所有这些内容时,请确保将选项卡放在正确的位置!)
关于c++ - 如何在目录中查找并查找具有特定扩展名的所有文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9047407/