仅当文件被修改时 MSBuild 上的 TextTransform? (或这样做的替代途径)
TextTransform on MSBuild only when file modified? (or an alternate route of doing this)
我有一个将 TextTransform 与 MSBuild 集成的项目,但我现在遇到的问题是文件太多,这会减慢开发时间。
我的流程是,我有一个POCO.cs;我使用 Roslyn 解析 .cs 文件以收集一些元数据;将元数据传递给 .tt 文件,然后生成 [Implementation].cs
这是与我的问题相关的 .csproj 文件的一部分:
<PropertyGroup>
<_CommonProgramFiles>$([System.Environment]::GetEnvironmentVariable('CommonProgramFiles(x86)'))</_CommonProgramFiles>
<_CommonProgramFiles Condition=" '$(_CommonProgramFiles)' == '' ">$(CommonProgramFiles)</_CommonProgramFiles>
<TextTransformPath Condition="'$(TextTransformPath)' == ''">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating$(VisualStudioVersion)\TextTransform.exe</TextTransformPath>
<!-- Initial default value -->
<_TransformExe>$(TextTransformPath)</_TransformExe>
<_RoslynDllPath>$(ProjectDir)Lib\RoslynWrapper.dll</_RoslynDllPath>
<!-- Cascading probing if file not found -->
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<!-- Future proof 'til VS2013+2 -->
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
</PropertyGroup>
<ItemGroup>
<Compile Include="SomePoco.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SomePocoMetadata.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>SomePocoMetadata.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="SomePocoMetadata.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>SomePocoMetadata.cs</LastGenOutput>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="TransformOnBuild" AfterTargets="BeforeBuild">
<Error Text="Failed to find TextTransform.exe tool at '$(_TransformExe)." Condition="!Exists('$(_TransformExe)')" />
<ItemGroup>
<_TextTransform Include="@(None)" Condition="'%(None.Generator)' == 'TextTemplatingFileGenerator'" />
</ItemGroup>
<!-- Perform task batching for each file -->
<Exec Command=""$(_TransformExe)" "%(_TextTransform.FullPath)" -r "$(_RoslynDllPath)"" Condition="'%(_TextTransform.Identity)' != ''" />
</Target>
有了上面的内容,.tt 文件总是在转换,编译 DLL 需要几分钟时间。有没有一种方法可以在 MSBuild 中执行此操作,以便仅在 SomePoco.cs 文件被修改时进行转换?
我是否应该研究另一种方法来实现我想要的目标?
确保为目标指定 Inputs
和 Outputs
属性。
在您的特定情况下,您似乎获得了目标内输入之一的名称,因此您不能在封闭的目标的 Input 属性中使用它。解决方法是将 _TextTransform 项目组的定义移到目标之外。
我最后做的是使用 ITaskItem[] 作为输入参数之一,我在那里使用 C# 找出文件的最后修改并确定我是否需要以这种方式生成。
我有一个将 TextTransform 与 MSBuild 集成的项目,但我现在遇到的问题是文件太多,这会减慢开发时间。
我的流程是,我有一个POCO.cs;我使用 Roslyn 解析 .cs 文件以收集一些元数据;将元数据传递给 .tt 文件,然后生成 [Implementation].cs
这是与我的问题相关的 .csproj 文件的一部分:
<PropertyGroup>
<_CommonProgramFiles>$([System.Environment]::GetEnvironmentVariable('CommonProgramFiles(x86)'))</_CommonProgramFiles>
<_CommonProgramFiles Condition=" '$(_CommonProgramFiles)' == '' ">$(CommonProgramFiles)</_CommonProgramFiles>
<TextTransformPath Condition="'$(TextTransformPath)' == ''">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating$(VisualStudioVersion)\TextTransform.exe</TextTransformPath>
<!-- Initial default value -->
<_TransformExe>$(TextTransformPath)</_TransformExe>
<_RoslynDllPath>$(ProjectDir)Lib\RoslynWrapper.dll</_RoslynDllPath>
<!-- Cascading probing if file not found -->
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<!-- Future proof 'til VS2013+2 -->
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe"</_TransformExe>
</PropertyGroup>
<ItemGroup>
<Compile Include="SomePoco.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SomePocoMetadata.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>SomePocoMetadata.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="SomePocoMetadata.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>SomePocoMetadata.cs</LastGenOutput>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="TransformOnBuild" AfterTargets="BeforeBuild">
<Error Text="Failed to find TextTransform.exe tool at '$(_TransformExe)." Condition="!Exists('$(_TransformExe)')" />
<ItemGroup>
<_TextTransform Include="@(None)" Condition="'%(None.Generator)' == 'TextTemplatingFileGenerator'" />
</ItemGroup>
<!-- Perform task batching for each file -->
<Exec Command=""$(_TransformExe)" "%(_TextTransform.FullPath)" -r "$(_RoslynDllPath)"" Condition="'%(_TextTransform.Identity)' != ''" />
</Target>
有了上面的内容,.tt 文件总是在转换,编译 DLL 需要几分钟时间。有没有一种方法可以在 MSBuild 中执行此操作,以便仅在 SomePoco.cs 文件被修改时进行转换?
我是否应该研究另一种方法来实现我想要的目标?
确保为目标指定 Inputs
和 Outputs
属性。
在您的特定情况下,您似乎获得了目标内输入之一的名称,因此您不能在封闭的目标的 Input 属性中使用它。解决方法是将 _TextTransform 项目组的定义移到目标之外。
我最后做的是使用 ITaskItem[] 作为输入参数之一,我在那里使用 C# 找出文件的最后修改并确定我是否需要以这种方式生成。