MSBuild 알기 - #003 Build, Clean, 그리고 Rebuild

소스 코드 내려 받기

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>&amp;</Ampersand>
		<LeftAngleBracket>&lt;</LeftAngleBracket>
		<RightAngleBracket>&gt;</RightAngleBracket>
		<StraightQuotationMark>&quot;</StraightQuotationMark>
		<Quot>$(StraightQuotationMark)</Quot>
		<Apostrophe>&apos;</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 개발환경에서 빌드 스크립트를 처음 도입할 때마다 요긴하게 써 먹는다. 이 소스 코드를 바탕 삼아 이 기능 저 기능 확장해나가면 된다. 얼핏 복잡해 보이나 실은 별 게 없는 이 템플릿을 실제 환경에 적용해보며 속속들이 알맹이를 꺼내 보자.

KITE LIBERATOR

실전!

실전에선 개인적으로 진행 중인 오픈소스 프로젝트인 얼그레이를 빌드해볼 것이다. “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 빌드를 하기로 한다.

[마리아홀릭 01편] - 물음표

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\trunk\201008-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

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu