如何使Qt自动查找要MOC的文件



我正在修改一些使用QT(版本5.10(的现有项目。我正在更新它们,以便在windows上使用更好、更简洁的msbuild语法(目标Visual Studio 2015(。

一个项目有大约170个头文件,其中大约135个头文件需要通过MOC.exe运行。因此,我编写了一个自定义目标,将135个文件发送到moc.exe。但告诉moc要处理哪些文件的msbuild语法相当长。即

<QtMocs Include="A.h;
B.h;
C.h;
D.h;
etc...

我尝试将所有的头文件发送到moc.exe。但如果头文件没有Q_OBJECT,那么moc.exe会发出不需要对头文件进行moc的警告。雪上加霜的是,它仍然会发出一个cpp文件,即使不需要moc'd。

所以我想写一个很好的简短(一行?(的简洁方式,告诉QT只需要moc所需的标题。

这可能吗?

因此,在两天没有回应之后,我决定编写自己的解决方案,它运行得非常好。我为MSBuild编写了一个自定义任务。它采用一个ProjectItem数组,该数组应该指向项目中的所有头文件。然后,对于数组中的每个文件,它打开文件,搜索Q_OBJECT,如果找到,则将Item保存到输出数组中。该输出数组随后被查询并发送到moc.exe。

<!-- Task to automatically discover header files that need to be run through QT's MOC.exe compiler.
It does this by examing each file and checking if 'Q_OBJECT' is in the file. -->
<UsingTask TaskName="FindFilesForQtMoc" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<Files    ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<MocFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Diagnostics" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var result = new List<Microsoft.Build.Framework.ITaskItem>();
foreach(var item in Files)
{
String filePath = item.GetMetadata("FullPath");
var content = File.ReadAllText(filePath);
if (content.Contains("Q_OBJECT"))
{
result.Add(item);
}
}
MocFiles = result.ToArray();
]]>
</Code>
</Task>
</UsingTask>

我这样称呼任务:

<FindFilesForQtMoc Files="@(ClInclude)" >
<Output ItemName="FileForMoc" TaskParameter="MocFiles" />
</FindFilesForQtMoc>
<Message Text="Moc: %(FileForMoc.Identity)" />

因此,我只需要在.vcxproj中声明我的所有头文件,如下所示:

<ClInclude Include="*.h" />

这比显式声明每个需要moc.exe.的文件要好得多

最新更新