Programming

모든 빌드에서 Visual Studio로 T4 템플릿 실행

procodes 2020. 6. 3. 22:29
반응형

모든 빌드에서 Visual Studio로 T4 템플릿 실행


모든 빌드에서 T4 템플릿으로 출력을 생성하려면 어떻게해야합니까? 지금과 같이 템플릿을 변경할 때만 재생성됩니다.

나는 이와 비슷한 다른 질문을 발견했다.

Visual Studio에서 T4 변환 및 빌드 순서 (답변 없음)

Visual Studio에서 t4 파일을 빌드하는 방법은 무엇입니까? (답변은 충분히 상세하지 않고 (아직 복잡하지만) 완전히 이해되지는 않습니다)

이 작업을 수행하는 더 간단한 방법이 있어야합니다!


나는 JoelFan의 대답을 사용 하여이 /를 올렸습니다. 새 .tt 파일을 프로젝트에 추가 할 때마다 사전 빌드 이벤트를 수정하지 않아도되므로 더 좋습니다.

  • TextTransform.exe를 %PATH%
  • transform_all.bat라는 배치 파일을 만들었습니다 (아래 참조).
  • 사전 빌드 이벤트 " 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

:: set the file extension (default to vb)
set extension=vb
if not (%2)==() set extension=%2

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 file_name=%%d
set file_name=!file_name:~0,-3!.%extension%
echo:  \--^> !file_name!    
TextTransform.exe -out !file_name! %%d
)

echo transformation complete

GarethJ에 동의합니다-VS2010에서는 각 빌드에서 tt 템플릿을 훨씬 쉽게 재생성합니다. Oleg Sych의 블로그는이를 수행하는 방법을 설명합니다. 한마디로 :

  1. Visual Studio SDK 설치
  2. 설치 비주얼 스튜디오 2010 모델링 및 시각화 SDK를
  3. 텍스트 편집기 프로젝트 파일에서 열고 파일 끝에 추가하십시오. </Project>

그게 다야. 프로젝트를여십시오. 각 빌드마다 모든 * .tt 템플릿이 재 처리됩니다.

<!-- 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" />

이 작업을 수행하는 훌륭한 NuGet 패키지가 있습니다.

PM> Install-Package Clarius.TransformOnBuild

패키지에 대한 자세한 내용은 여기를 참조하십시오.


MarkGr의 답변을 사용 하여이 솔루션을 개발했습니다. 먼저 주 솔루션 폴더 위의 별도 도구 폴더에 RunTemplate.bat 라는 배치 파일을 만듭니다 . 배치 파일에는 다음 줄만 있습니다.

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

이 배치 파일은 2 개의 매개 변수를 사용합니다. % 1 은 (는) .tt 확장자가없는 .tt 파일의 경로입니다. % 2템플릿에서 Assembly 지시문이 참조하는 DLL의 경로 입니다.

다음으로 T4 템플릿을 포함하는 프로젝트의 프로젝트 속성으로 이동하십시오. 빌드 이벤트 로 이동 하여 다음 사전 빌드 이벤트 명령 행을 추가하십시오 .

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

MyTemplate 을 .tt 확장자가없는 .tt 파일 (예 : MyTemplate.tt)의 파일 이름으로 바꿉니다 . 이것은 프로젝트를 빌드하기 전에 템플릿을 확장하여 MyTemplate.cs를 생성 한 결과입니다. 그런 다음 실제 빌드는 MyTemplate.cs를 컴파일합니다.


최근에이 훌륭한 VS 플러그인 Chirpy를 발견했습니다 .

빌드에서 T4를 생성 할뿐만 아니라 자바 스크립트, CSS를 최소화하기위한 T4 기반 접근을 허용하며 CSS에 대해 LESS 구문을 사용할 수도 있습니다!


아마도 가장 간단한 방법은 AutoT4 라는 Visual Studio 확장을 설치하는 입니다.

자동으로 빌드시 모든 T4 템플릿을 실행합니다.


사전 빌드는 한 줄로 줄일 수 있습니다.

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

.tt프로젝트의 모든 파일을 변환 하여 빌드 출력에 나열합니다.

빌드 출력을 원하지 않으면 "흥미로운 동작" 을 해결해야합니다 .

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

물론, 원하는 경우 프로젝트 디렉토리 경로를 전달하는 배치 파일로이를 가져올 수 있습니다.

NB 경로를 약간 조정해야 할 수도 있습니다. 위의 경로는 VS 2008이 내 컴퓨터에 설치 한 위치입니다. 그러나 TextTemplating사이의 버전 번호 TextTransform.exe가 다를 수 있습니다.


C : \ Program Files (x86) \ Common Files \ Microsoft Shared \ TextTemplating을 확인하십시오. 명령 줄 변환 exe가 있습니다. 또는 사용자 지정 호스트로 MSBuild 작업을 작성하고 직접 변환하십시오.


Seth RenoJoelFan의 답변을 확장하면서 나는 이것을 생각해 냈습니다. 이 솔루션을 사용하면 새 .tt 파일을 프로젝트에 추가 할 때마다 사전 빌드 이벤트를 수정해야합니다.

구현 절차

  • transform_all.bat라는 배치 파일을 만듭니다 (아래 참조).
  • 빌드 transform_all.bat "$(ProjectDir)" $(ProjectExt)하려는 .tt를 사용하여 각 프로젝트에 대한 사전 빌드 이벤트 작성하십시오.

transform_all.bat

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

:: set the correct path to the the app
if not defined ProgramFiles(x86). (
  echo 32-bit OS detected
  set ttPath=%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\
) else (
  echo 64-bit OS detected
  set ttPath=%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\
)

:: set the working dir (default to current dir)
if not (%1)==() pushd %~dp1

:: set the file extension (default to vb)
set ext=%2
if /i %ext:~1%==vbproj (
  set ext=vb
) else if /i %ext:~1%==csproj (
  set ext=cs
) else if /i [%ext%]==[] (
  set ext=vb
)

:: create a list of all the T4 templates in the working dir
echo Running TextTransform from %cd%
dir *.tt /b /s | findstr /vi obj > t4list.txt

:: transform all the templates
set blank=.
for /f "delims=" %%d in (t4list.txt) do (
  set file_name=%%d
  set file_name=!file_name:~0,-3!.%ext%
  echo:  \--^> !!file_name:%cd%=%blank%!
  "%ttPath%TextTransform.exe" -out "!file_name!" "%%d"
)

:: delete T4 list and return to previous directory
del t4list.txt
popd

echo T4 transformation complete


노트

  1. 텍스트 변환에서는 T4 템플리트의 코드가 프로젝트 유형과 동일한 언어라고 가정합니다. 이 경우가 해당되지 않으면 $(ProjectExt)인수를 코드에서 생성 할 파일의 확장자 로 바꿔야합니다 .

  2. .TT파일은 빌드하지 않을 프로젝트 디렉토리에 있어야합니다. 첫 번째 인수로 다른 경로를 지정하여 프로젝트 디렉토리 외부에 TT 파일을 빌드 할 수 있습니다 ( "$(ProjectDir)" , TT 파일이 포함 된 경로로 대체 ).

  3. transform_all.bat배치 파일 의 올바른 경로를 설정해야 합니다.
    예를 들어, 사전 빌드 이벤트가 다음과 같도록 솔루션 디렉토리에 배치했습니다."$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)


Visual Studio 2010을 사용하는 경우 Visual Studio 모델링 및 시각화 SDK를 사용할 수 있습니다. http://code.msdn.microsoft.com/vsvmsdk

여기에는 빌드시 T4 템플릿을 실행하기위한 msbuild 작업이 포함됩니다.

자세한 설명은 Oleg의 블로그를 참조 하십시오 : http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration


이봐, 내 스크립트는 출력 확장을 구문 분석 할 수 있습니다

for /r %1 %%f in (*.tt) do (
 for /f "tokens=3,4 delims==, " %%a in (%%f) do (
  if %%~a==extension "%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %%~pnf.%%~b -P %%~pf -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %%f
 )
)
echo Exit Code = %ERRORLEVEL%

transform_all.bat $(SolutionDir)사전 빌드 이벤트를 작성하기 만하면 솔루션의 모든 * .tt 파일이 자동으로 변환됩니다.


Dynamo.AutoTT가 필요한 작업을 수행합니다. 정규식을 통해 파일을 보거나 빌드시 생성하도록 구성 할 수 있습니다. 또한 트리거 할 T4 템플릿을 지정할 수도 있습니다.

https://github.com/MartinF/Dynamo.AutoTT 에서 다운로드 할 수 있습니다.

그냥 빌드하고 dll 및 AddIn 파일을

C : \ Users \ Documents \ Visual Studio 2012 \ Addins \

그리고 당신은 간다.

VS2012에서 작업하려면 Dynamo.AutoTT.AddIn 파일을 수정하고 AddIn 파일에서 버전을 11.0으로 설정해야합니다.


여기 내 해결책이 있습니다-허용 된 답변과 비슷합니다. 소스 컨트롤에 문제가있었습니다. 대상 .cs 파일이 읽기 전용이며 T4가 실패했습니다. 다음은 temp 폴더에서 T4를 실행하고 대상 파일을 비교하고 동일한 변경이있는 경우에만 복사하는 코드입니다. read.only 파일의 문제점을 수정하지는 않지만 최소한 자주 발생하지는 않습니다.

Transform.bat

ECHO Transforming T4 templates
SET CurrentDirBackup=%CD%
CD %1
ECHO %1
FOR /r %%f IN (*.tt) DO call :Transform %%f
CD %CurrentDirBackup%
ECHO T4 templates transformed
goto End

:Transform
set ttFile=%1
set csFile=%1

ECHO Transforming %ttFile%:
SET csFile=%ttFile:~0,-2%cs
For %%A in ("%ttFile%") do Set tempTT=%TEMP%\%%~nxA
For %%A in ("%csFile%") do Set tempCS=%TEMP%\%%~nxA

copy "%ttFile%" "%tempTT%
"%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe"  "%tempTT%"

fc %tempCS% %csFile% > nul
if errorlevel 1 (
 :: You can try to insert you check-out command here.
 "%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe"  "%ttFile%"
) ELSE (
 ECHO  no change in %csFile%
)

del %tempTT%
del %tempCS%
goto :eof

:End

체크 아웃 명령을 줄에 추가 할 수 있습니다 (:: 시도해보십시오 ....)

프로젝트에서이를 사전 빌드 조치로 설정하십시오.

Path-To-Transform.bat "$(ProjectDir)"

프로젝트의 사전 빌드 이벤트에이 명령을 추가하기 만하면됩니다.

if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe  /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets"  $(ProjectPath) /t:TransformAll 

구성 확인 = 디버그는 예를 들어 TFS 빌드 서버에서 빌드를 수행 할 때 릴리스 모드에서 코드를 재생성하지 않도록합니다.


Visual Studio 2013에서 T4 템플릿을 마우스 오른쪽 단추로 클릭하고 빌드시 변환 속성을 true로 설정하십시오.


여기 내가 어떻게 알아 냈는지입니다. 링크 . 기본적으로 훌륭한 블로그 위에 구축 (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-with-out-installing-a-visual-studio-sdk/) links :() Visual Studio proj 파일과 함께 사용할 .targets 파일을 생각해 냈습니다 .

.tt 내부에 다른 dll을 사용하고 dll이 변경됨에 따라 결과를 변경하려는 경우에 유용합니다.

작동 방식 :

  1. tt를 만들고 어셈블리 이름 = "$ (SolutionDir) path \ to \ other \ project \ output \ foo.dll을 추가하고 변환 및 결과를 예상대로 설정하십시오.
  2. .tt에서 어셈블리 참조 제거

  3. proj 파일 내에서이 코드를 사용하여 빌드시 변환을 설정하십시오.

    <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>
    
    • 첫 번째 부분은 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


T4Executer does this for VS2019. You can specify templates to ignore on build, and there is a execute after build option.


You just install NuGet Package: Clarius.TransformOnBuild

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


Some guy built a nuget package for this.

Side note: I get compile errors from both TextTemplate.exe and that package (because that package calls TextTemplate.exe) but not from Visual Studio. So apparently the behavior is not the same; heads up.

EDIT: This ended up being my problem.


In Visual Studio 2017 (probably next versions too), you should add this in Pre-build event:

"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"

p.s. Change path to your template if it's located not in root project directory.


Thanks to GitHub.com/Mono/T4, at the moment you can do it for both .NET Core and Visual Studio builds by adding this to your .csproj file:

  <ItemGroup>
    <DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
    <TextTemplate Include="**\*.tt" />
  </ItemGroup>

  <Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
    <ItemGroup>
      <Compile Remove="**\*.cs" />
    </ItemGroup>
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity)" />
    <ItemGroup>
      <Compile Include="**\*.cs" />
    </ItemGroup>
  </Target>

If you transform your templates to different programming languages you should add something like <Compile Remove="**\*.vb" /> and <Compile Include="**\*.vb" /> in order to get these files compiled even if you don't have generated files yet.

Remove and Include trick only needed for first time generation, or you can make the XML-shorter like this:

  <ItemGroup>
    <DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
    <TextTemplate Include="**\*.tt" />
  </ItemGroup>

  <Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity)" />
  </Target>

and just run build twice (for the first time). If you already have generated files committed to the repository there will be no problems on rebuilds with both examples.

In the Visual Studio you might want to see something like this:

enter image description here

instead of this:

enter image description here

So add something like this to your project file:

  <ItemGroup>
    <Compile Update="UInt16Class.cs">
      <DependentUpon>UInt16Class.tt</DependentUpon>
    </Compile>
    <Compile Update="UInt32Class.cs">
      <DependentUpon>UInt32Class.tt</DependentUpon>
    </Compile>
    <Compile Update="UInt64Class.cs">
      <DependentUpon>UInt64Class.tt</DependentUpon>
    </Compile>
    <Compile Update="UInt8Class.cs">
      <DependentUpon>UInt8Class.tt</DependentUpon>
    </Compile>
  </ItemGroup>

Complete example here: GitHub.com/Konard/T4GenericsExample (includes generation of multiple files from single template).

참고URL : https://stackoverflow.com/questions/1646580/get-visual-studio-to-run-a-t4-template-on-every-build

반응형