使用vc2010和msbuild的多个构建规则

时间:2010-12-03 02:05:29

标签: c++ visual-studio-2010 visual-c++ msbuild

我在VS2010中管理一个C ++项目,并希望在转到C ++编译器之前让所有.cpp文件通过外部工具运行。所有迹象似乎都表明这是可能的。例如,请参阅here

由于这将在多个项目中发生,因此将此功能放在属性表中然后只是在任何地方导入此属性表是有意义的。在我触及属性表之前,它看起来像是完整的:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
    <ExtensionsToDeleteOnClean>...</ExtensionsToDeleteOnClean>
    <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <AdditionalIncludeDirectories>...</AdditionalIncludeDirectories>
      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
    </ClCompile>
    <Link>
      <AdditionalDependencies>...</AdditionalDependencies>
    </Link>
      <Outputs>...</Outputs>
    </CustomBuildStep>
  </ItemDefinitionGroup>
</Project>

根据上述链接文件,我添加了以下内容:

<Project>
  <PropertyGroup>
    ...
    <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
  </PropertyGroup>
  ...
  <ItemGroup>
    <CustomBuild Include="*.cpp">
      <Message>Running Custom Build Step</Message>
      <Command>dummy</Command>
      <Outputs>dummy</Outputs>
    </CustomBuild>
  </ItemGroup>
</Project>

这似乎没有任何效果,我的自定义构建工具永远不会在ClCompile之前运行。我已经尝试了各种移动方式和重命名标记的方法(例如,Xml编辑器抱怨CustomBuild根据模式甚至不是有效的),但没有任何作用。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

虽然这是一个非常古老的问题,但我会尝试回答它。

Include 属性希望在Project目录中找到* .cpp 文件。如果Project目录中没有.cpp文件,则此CustomBuild“Task”将永远不会启动。

OP可以做的是

<CustomBuild Include="**\*.cpp">
    <Message>Custombuild kicking in</Message>
    <Command>echo %(Identity)</Command>
    <Outputs>dummy</Outputs>
</CustomBuild>

而不是

<CustomBuild Include="*.cpp">
...

并且他将对项目目录的所有子目录中的所有.cpp文件执行CustomBuild操作,而不仅仅是等待编译的.cpp文件。

如果.cpp文件在Project目录下不可用(可能在使用这样的项目目录结构时发生),那么OP必须明确指向正确的“root”目录。

答案 1 :(得分:0)

或者,您可以通过在每个包含的ClCompile上运行Exec任务来节省您的通配符使用。

<Target Name="ProcessClCompileFiles" BeforeTargets="ClCompile" Condition="'@(ClCompile)'!=''">
  <Message Text="== Starting processing cpp files ==" Importance="High"/>
  <Exec Command="echo processing %(ClCompile.filename)%(ClCompile.extension) &amp; ////YOUR COMMAND HERE////" />
</Target>
  

作为一个说明。这需要在此目标之前初始化ClCompile项目组。如果您要创建一个动态添加ClCompile的目标,那么您必须确保在强调此目标之前发生这种情况。

     

另一个注意事项是,如果ClCompile项目组中有任何项目,这些Exec任务将始终运行。如果您有条件跳过它们(例如,已经处理过),请使用条件=&#34; A = B&#34;

为了便于参考,以下是如何验证它还没有创建文件以及是否创建了文件;如果文件已过期:

Condition="!Exists('$(OutDir)%(Filename)%(Extension)') OR ($([System.DateTime]::Parse('%(ClCompile.ModifiedTime)').Ticks) > $([System.IO.File]::GetLastWriteTime('$(OutDir)%(Filename)%(Extension)').Ticks))"