소스 코드 내려 받기
svn checkout h ttp://imaso.googlecode.com/svn/trunk/201008-MSBuildTutorial imaso-read-only
201008-MSBuildTutorial 폴더에서 이번 실습에 쓸 하위 폴더는 두 개 뿐이다. 003, Shared 이 두 폴더만 내려 받아도 괜찮다.
우려먹자
아래 예제는 003 폴더에 있는 msbuild-basic-template.xml 파일이다. 파일 이름이 암시하는 바, 빌드 스크립트를 작성할 때 기본 코드로 활용하곤 한다.
<?xml version="1.0" encoding="utf-8" ?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" > <!-- Special characters --> <PropertyGroup> <Semicolon>%3b</Semicolon> <Ampersand>&</Ampersand> <LeftAngleBracket><</LeftAngleBracket> <RightAngleBracket>></RightAngleBracket> <StraightQuotationMark>"</StraightQuotationMark> <Quot>$(StraightQuotationMark)</Quot> <Apostrophe>'</Apostrophe> </PropertyGroup> <!-- Folders --> <PropertyGroup> <RootDir>$(MSBuildProjectDirectory)</RootDir> </PropertyGroup> <!-- Tools --> <PropertyGroup> <DevEnv>devenv.exe</DevEnv> </PropertyGroup> <!-- Build configuration: DEBUG/RELEASE, Any CPU/x86/Win32/x64 --> <PropertyGroup> <Platform Condition=" '$(Platform)' == '' AND '$(MSBuildBinPath)'=='C:\Windows\Microsoft.NET\Framework64\v2.0.50727' " >x64</Platform> <Platform Condition=" '$(Platform)' == '' ">Win32</Platform> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <BuildCondition>$(Configuration)|$(Platform)</BuildCondition> </PropertyGroup> <PropertyGroup Condition=" '$(BuildCondition)' == 'Debug|Win32' "> </PropertyGroup> <PropertyGroup Condition=" '$(BuildCondition)' == 'Release|x64' "> </PropertyGroup> <ItemGroup> <ProjectReferences Include="$(RootDir)\Projects.sln"> <Configuration>$(Configuration)</Configuration> <Platform>$(Platform)</Platform> <BuildCondition>%(Configuration)|%(Platform)</BuildCondition> </ProjectReferences> </ItemGroup> <Target Name="Clean"> <Message Text="타겟: Clean" /> <Exec Command="$(DevEnv) $(Quot)%(ProjectReferences.FullPath)$(Quot) /Clean $(Quot)%(ProjectReferences.BuildCondition)$(Quot)" ContinueOnError="false" IgnoreExitCode="false" /> </Target> <Target Name="Build"> <Message Text="타겟: Build" /> <Message Text="빌드 조건: '$(BuildCondition)'" Importance="high" /> <Exec Command="$(DevEnv) $(Quot)%(ProjectReferences.FullPath)$(Quot) /Build $(Quot)%(ProjectReferences.BuildCondition)$(Quot)" ContinueOnError="false" IgnoreExitCode="false" /> </Target> <Target Name="Rebuild" DependsOnTargets="Clean; Build"> <Message Text="타겟: Rebuild" /> </Target> </Project>
이 빌드 스크립트는 짧지만 나름의 노하우가 집적된 코드이다. 대부분의 Visual Studio 개발환경에서 빌드 스크립트를 처음 도입할 때마다 요긴하게 써 먹는다. 이 소스 코드를 바탕 삼아 이 기능 저 기능 확장해나가면 된다. 얼핏 복잡해 보이나 실은 별 게 없는 이 템플릿을 실제 환경에 적용해보며 속속들이 알맹이를 꺼내 보자.
실전!
실전에선 개인적으로 진행 중인 오픈소스 프로젝트인 얼그레이를 빌드해볼 것이다. “003\msbuild.xml” 파일을 열어서 살펴보자.
폴더
<!-- Folders --> <PropertyGroup> <RootDir>$(MSBuildProjectDirectory)</RootDir> <SharedDir>$(RootDir)\..\Shared</SharedDir> <EarlgreyDir>$(SharedDir)\Earlgrey</EarlgreyDir> </PropertyGroup>
$(RootDir) 는 이 빌드 스크립트가 놓인 폴더가 된다. 정말 정말 피치 못할 사정이 없는 한 “C:\Workspace” 처럼 경로를 하드코딩하는 건 좋지 않다. 빌드 자동화의 기본 원칙 첫 번째!
Subversion 에서 내려 받은 소스 코드와 Visual Studio만 있으면 알아서 빌드해서 작동하는 프로그램을 만들어내야 한다.
소스 코드를 내려 받는 경로는 어디든 상관 없어야 한다. 꼭 “D:\Workspace”에 소스 코드가 있어야 한다던가, 이런 건 지양하자. 신입 사원이 들어와서 “설치 다 했는데 왜 안 되요?” 라고 물을 때 우리 소스코드는 ‘D:\Workspace’에 있어야만 작동돼?”라고 하면 쪽 팔리지 않겠는가? 사람이 기억할 거리를 줄이는 게 자동화의 기본이다.
빌드 설정
<!-- Build configuration: DEBUG/RELEASE, Any CPU/x86/Win32/x64 --> <PropertyGroup> <Platform Condition=" '$(Platform)' == '' AND '$(MSBuildBinPath)'=='C:\Windows\Microsoft.NET\Framework64\v2.0.50727' " >x64</Platform> <Platform Condition=" '$(Platform)' == '' ">Win32</Platform> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <BuildCondition>$(Configuration)|$(Platform)</BuildCondition> </PropertyGroup>
Platform
Platform은 x64 빌드인지, Win32 빌드인지 등을 결정한다.
'$(Platform)' == ''
이 조건은 $(Platform)을 사전에 정의하거나 msbuild.exe 의 명령 줄 옵션으로 정의하지 않았는지 확인한다. 사전에 정의한 값이 있으면 그 값을 사용한다.
'$(MSBuildBinPath)'=='$(WINDIR)\Microsoft.NET\Framework64\v3.5'
이 빌드 스크립트를 실행한 MSBuild 인터프리터가 64비트 빌드용이라면 당연하게도 x64용 코드를 만들어낸다.
Configuration
그다지 볼 것도 없다. 사전에 정의한 값이 없다면 Debug 빌드를 하기로 한다.
Visual Studio 솔루션
<ItemGroup> <ProjectReferences Include="$(EarlgreyDir)\src\Earlgrey.sln"> <Configuration>$(Configuration)</Configuration> <Platform>$(Platform)</Platform> <BuildCondition>%(Configuration)|%(Platform)</BuildCondition> </ProjectReferences> </ItemGroup>
Earlgrey.sln 이란 솔루션 파일이 있고 앞서 정의한 $(Configuration), $(Platform) 값에 따라 빌드하기로 한다. 계산해보면 4가지 조합이 가능하다.
-
Debug|Win32
-
Release|Win32
-
Debug|x64
-
Release|x64
솔루션 빌드
<Target Name="Build"> <Exec Command="$(DevEnv) $(Quot)%(ProjectReferences.FullPath)$(Quot) /Build $(Quot)%(ProjectReferences.BuildCondition)$(Quot)" ContinueOnError="false" IgnoreExitCode="false" /> </Target>
솔루션은 Visual Studio 바이너리인 devenv.exe 를 호출해 실행한다. 코드가 복잡해 보이나 변수 값을 해석하고 나면 이렇게 간단해진다.
devenv.exe "C:\imaso\trunk1008-MSBuildTutorial\Shared\Earlgrey\src\Earlgrey.sln" \ /Build "Debug|Win32"
타겟 Clean 도 차이가 없기 때문에 설명하지 않는다.
실행!!!
네 가지 빌드 구성에 맞춰 빌드하는 법을 알아보고 실제로 돌려보자. 여기서 눈 여겨 볼 것은 /p 명령 줄 옵션을 사용해서 $(Configuration)의 값을 사전에 지정하는 대목이다.
Debug|Win32
MSBuild_Win32.bat msbuild.xml /t:build
Debug|x64
MSBuild_Win64.bat msbuild.xml /t:build
Release|Win32
MSBuild_Win32.bat msbuild.xml /t:build /p:Configuration=Release
Release|x64
MSBuild_x64.bat msbuild.xml /t:build /p:Configuration=Release