views:

1341

answers:

6

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 questions similar to this:

http://stackoverflow.com/questions/1293320/t4-transformation-and-build-order-in-visual-studio (unanswered)

http://stackoverflow.com/questions/405560/how-to-get-t4-files-to-build-in-visual-studio (answers are not detailed enough [while still being plenty complicated] and don't even make total sense)

There has got to be a simpler way to do this!

+1  A: 

Check out C:\Program Files (x86)\Common Files\Microsoft Shared\TextTemplating there is a command line transformation exe in there. Alternatively write a MSBuild task with a custom host and do the transform yourself.

MarkGr
Oh, although you can do stuff like "devenv /Command TextTransformation.TransformAllTemplates /Command File.Exit MySolution.sln" on 2010 it tends to break on build servers occasionally. Your best bet is to write a MSBuild task with a custom host.
MarkGr
For desktop builds, just make a macro that does a TransformAllTemplates, and then a build.
MarkGr
+6  A: 

I used MarkGr's answer and developed this solution. First, create a batch file called RunTemplate.bat in a separate tools folder above the main solution folder. The batch file just has the line:

"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt

This batch file takes 2 parameters... %1 is the path to the .tt file without the .tt extension. %2 is the path to any DLLs referred to by Assembly directives in the template.

Next, go into the Project Properties of the project containing the T4 template. Go into Build Events and add the following Pre-build event command line:

$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)

replacing MyTemplate with filename of your .tt file (i.e. MyTemplate.tt) without the .tt extension. This will have the result of expanding the template to produce MyTemplate.cs before building the project. Then the actual build will compile MyTemplate.cs

JoelFan
although I still have the problem: http://stackoverflow.com/questions/1669893/texttransform-exe-seems-to-only-accept-an-older-version-of-c
JoelFan
Don't forget the quotes around $(SolutionDir)..\..\tools\RunTemplate.bat
Ewald Hofman
+2  A: 

If you're using Visual Studio 2010, you can use the Visual Studio Modeling and Visualization SDK: http://code.msdn.microsoft.com/vsvmsdk

This contains msbuild tasks for executing T4 templates at build time.

Have a look at Oleg's blog for more explanation: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration

GarethJ
+4  A: 

I used JoelFan's answer to come up w/ this. I like it better because you don't have to remember to modify the pre-build event every time you add a new .tt file to the project.

  • add TextTransform.exe to your %PATH%
  • created a batch file named transform_all.bat (see below)
  • create a pre-build event "transform_all ..\.."

transform_all.bat

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

:: set the working dir (default to current dir)
set wdir=%cd%
if not (%1)==() set wdir=%1

echo executing transform_all from %wdir%
:: create a list of all the T4 templates in the working dir
dir %wdir%\*.tt /b /s > t4list.txt

echo the following T4 templates will be transformed:
type t4list.txt

:: transform all the templates
for /f %%d in (t4list.txt) do (
    set vbfile=%%d
    set vbfile=!vbfile:~0,-3!.vb
    echo:  \--^> !vbfile!
    TextTransform.exe -out !vbfile! %%d
)

echo transformation complete
Seth Reno
+3  A: 

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" />
Cheburek
+2  A: 

Recently found this great VS plugin, Chirpy.

Not only does it generate your T4 on a build, but it allows T4-based approach to minification of javascript, CSS, and even lets you use LESS syntax for your CSS!

Mark