我需要编写一个预构建的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 :(得分:2)
您的问题可能只是一件简单的事情:您在当前目录中的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
{1}}。有办法解决这个问题,但更容易避免这个问题。)无论如何,这会为您提供输出文件列表: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
文件更新,表明它已经是最新的,那么下一步就不会重新生成它你跑的时间。它只会重新生成与您编辑过的%.h
文件对应的文件。
(哦,还有最后一件事:当从这个答案中剪切并粘贴所有这些东西时,请确保你的标签在正确的位置!)
答案 1 :(得分:1)
只需使用GNU Make的原生wildcard
function:
HEADERS := $(wildcard $(SUBDIRS:%=%/*.h))