Get Visual Studio to run a T4 Template on every build

后端 未结 22 2408
余生分开走
余生分开走 2020-11-22 08:29

How do I get a T4 template to generate its output on every build? As it is now, it only regenerates it when I make a change to the template.

I have found other ques

相关标签:
22条回答
  • 2020-11-22 08:56

    I agree with GarethJ - in VS2010 it is much easier to regenerate tt templates on each build. Oleg Sych's blog describes how to do it. In short:

    1. Install Visual Studio SDK
    2. Install Visual Studio 2010 Modeling and Visualization SDK
    3. Open in text editor project file and add to the end of file but before </Project>

    That's it. Open your project. On each build all *.tt templates will be reprocessed

    <!-- This line could already present in file. If it is so just skip it  -->
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    <!-- process *.tt templates on each build  -->
    <PropertyGroup>
        <TransformOnBuild>true</TransformOnBuild>
    </PropertyGroup>
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
    
    0 讨论(0)
  • 2020-11-22 08:56

    Here is how I tacked it. Link. Basically building on top of a great blog( blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ can't post more that 2 links :( ) I came up with This .targets file for use with visual studio proj files.

    It's useful when you are using other dll-s inside of your .tt and you want the result to change as the dll-s are changing.

    How it works:

    1. Create the tt, add the assembly name="$(SolutionDir)path\to\other\project\output\foo.dll and set up the transformation and result to be as expected
    2. Remove the assembly references from .tt

    3. Inside the proj file use this code to set up transform on build:

      <PropertyGroup>
        <!-- Initial default value -->
        <_TransformExe>$(CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe</_TransformExe>
        <!-- If explicit VS version, override default -->
        <_TransformExe Condition="'$(VisualStudioVersion)' != ''">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe</_TransformExe>
        <!-- Cascading probing if file not found -->
        <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe</_TransformExe>
        <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\11.0\TextTransform.exe</_TransformExe>
        <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\12.0\TextTransform.exe</_TransformExe>
        <!-- Future proof 'til VS2013+2 -->
        <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\13.0\TextTransform.exe</_TransformExe>
        <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\14.0\TextTransform.exe</_TransformExe>
        <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\15.0\TextTransform.exe</_TransformExe>
      
        <IncludeForTransform>@(DllsToInclude, '&amp;quot; -r &amp;quot;')</IncludeForTransform>
      </PropertyGroup>
      
      • First part Locates TextTransform.exe

      • $(IncludeForTransform) will be equal to c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll because that's the way to add references for the TextTransform on the command line

         <Target Name="TransformOnBuild" BeforeTargets="BeforeBuild">
           <!--<Message Text="$(IncludeForTransform)" />-->
           <Error Text="Failed to find TextTransform.exe tool at '$(_TransformExe)." Condition="!Exists('$(_TransformExe)')" />
           <ItemGroup>
             <_TextTransform Include="$(ProjectDir)**\*.tt" />
           </ItemGroup>
           <!-- Perform task batching for each file -->
           <Exec Command="&quot;$(_TransformExe)&quot; &quot;@(_TextTransform)&quot; -r &quot;$(IncludeForTransform)&quot;" Condition="'%(Identity)' != ''" />
         </Target>
        
      • <_TextTransform Include="$(ProjectDir)**\*.tt" />this creates a list of all tt files inside the project and subdirectories

      • <Exec Command="... produces a line for each of the found .tt files that looks like "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.dll"

    4. The only thing left to do is add the paths to the dlls inside of:

          <ItemGroup>
            <DllsToInclude Include="$(ProjectDir)path\to\foo.dll">
              <InProject>False</InProject>
            </DllsToInclude>
            <DllsToInclude Include="$(ProjectDir)path\to\bar.dll">
              <InProject>False</InProject>
            </DllsToInclude>
          </ItemGroup>
      

      Here <InProject>False</InProject> hides these items from the Solution View

    So now you should be able to generate your code on build and on change of dll-s.

    You can remove the custom tool (from properties inside of Visual Studio) so the VS does not try to transform and fail miserably every time. Because we removed the assembly references in step 2

    0 讨论(0)
  • 2020-11-22 08:56

    You just install NuGet Package: Clarius.TransformOnBuild

    Then, every time you click Rebuild project (or Solution), your .tt files will run

    0 讨论(0)
  • 2020-11-22 08:58

    In visual studio 2013, right click the T4 template and set the transform on build property to true.

    0 讨论(0)
  • 2020-11-22 09:01

    There is a great NuGet package that does just this:

    PM> Install-Package Clarius.TransformOnBuild
    

    Details about the package can be found here

    0 讨论(0)
  • 2020-11-22 09:01

    The pre-build can be reduced to a single line:

    forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
    

    This transforms all .tt files in the project and lists them to the build output.

    If you don't want the build output then you have to work around some "interesting behaviour":

    forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
    

    Of course, you can pull this out into a batch file to which you pass the project directory path if you wish.

    NB The path may require some tweaking. The path above is where VS 2008 installed it on my machine; but you might find that the version number between TextTemplating and TextTransform.exe is different.

    0 讨论(0)
提交回复
热议问题