如何在目录中散步并找到具有特定扩展名的所有文件

问题描述:

我需要编写一个预编译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,但我在它和这些尝试是新手失败。请检阅我的代码和/或建议其他方法。

+0

会有可能吗? 'find $(SUBDIRS)-name“* .h”-exec C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe \ {\} \;' – Borealid 2012-01-28 17:43:54

你的问题很可能是仅此一件简单的事情:你在*.h在当前目录中寻找file,而不是在子目录中。试试这个:

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来处理所有的文件处理(并决定是否或不是所有的人都需要进行再处理!) ,而不是在规则中使用显式循环。你会用的头文件列表开始,因为埃尔达尔Abusalimov的回答提示:

moc_headers := $(wildcard $(SUBDIRS:%=%/*.h)) 

的是,内部件操纵SUBDIRS列表到表单directory1/*.hdirectory2/*.h,等等,然后wildcard功能扩展所有*.h模式。

然后,你从他们生成的输出文件的列表:

moc_mocfiles := $(patsubst %.h, %_moc.cpp, $(moc_headers)) 

该命令将头文件directory1/header1.hdirectory1/header2.h等展开列表,并替换%.h图案%_moc.cpp。 (请注意,因为这些名称都有目录名称作为名称的一部分,所以不能轻松使用更常用的moc_%.h名称模式,因为您会得到moc_directory1/header1.cpp,而不是所需的directory1/moc_header1.cpp。有办法避开,但避免这个问题更容易)。无论如何,这会给你一个输出文件列表:directory1/header1_moc.cpp,directory1/header2_moc.cpp等等。

既然你有一个输出文件的列表,知道如何很容易地迭代这些输出文件。你刚才声明列表,你正在做一些其他目标的先决条件,例如:

find_files: $(moc_mocfiles) 

最后,你给做一个通用的规则,用于从*.h文件制作*_moc.cpp文件:

%_moc.cpp: %.h 
    C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $< -o [email protected] 

在那里,第一行指出“这是如何制作适合%_moc.cpp图案的文件,如果您有适合%.h图案的文件”。在第二行中,$<成为输入文件(%.h文件),并且[email protected]成为输出文件。在这里,您明确地告知moc.exe使用-o选项来输出名称为%_moc.cpp的文件,而不是默认情况下使用的文件。

因此,把所有这些组合起来,当你做出find_files目标,使会认识到它需要做的moc_mocfiles列表中的所有这些%_moc.cpp文件,并为每一个它会看到它有一个可能的规则适合它会看到该规则适用,因为相应的%.h文件存在,并且它将应用该规则。

这也有一个好处,即如果%_moc.cpp文件已经存在并且比%.h文件更新,表明它已经是最新的,那么下次运行make时就不会再次重新生成它。它只会重新生成对应于您编辑的%.h文件的文件。

(哦,还有最后一件事:当从这样的回答切割与粘贴所有这些事情,一定要得到你的标签在正确的地方!)使用Unix/Cygwin的`find`实用

只需使用GNU的本地wildcard function品牌:

HEADERS := $(wildcard $(SUBDIRS:%=%/*.h))