프로젝트 파일 이해
작성자 : Jason Lee
Microsoft Build Engine(MSBuild) 프로젝트 파일은 빌드 및 배포 프로세스의 핵심입니다. 이 항목은 MSBuild 및 프로젝트 파일에 대한 개념적 개요로 시작합니다. 프로젝트 파일로 작업할 때 발생하는 주요 구성 요소에 대해 설명하고 프로젝트 파일을 사용하여 실제 애플리케이션을 배포하는 방법의 예제를 통해 작동합니다.
학습할 내용:
- MSBuild에서 MSBuild 프로젝트 파일을 사용하여 프로젝트를 빌드하는 방법
- MSBuild가 IIS(인터넷 정보 서비스) 웹 배포 도구(웹 배포)와 같은 배포 기술과 통합되는 방법
- 프로젝트 파일의 주요 구성 요소를 이해하는 방법
- 프로젝트 파일을 사용하여 복잡한 애플리케이션을 빌드하고 배포하는 방법
MSBuild 및 프로젝트 파일
Visual Studio에서 솔루션을 만들고 빌드할 때 Visual Studio는 MSBuild를 사용하여 솔루션의 각 프로젝트를 빌드합니다. 모든 Visual Studio 프로젝트에는 프로젝트 형식을 반영하는 파일 확장명(예: C# 프로젝트(.csproj), Visual Basic.NET 프로젝트(.vbproj) 또는 데이터베이스 프로젝트(.dbproj))가 포함된 MSBuild 프로젝트 파일이 포함됩니다. 프로젝트를 빌드하려면 MSBuild가 프로젝트와 연결된 프로젝트 파일을 처리해야 합니다. 프로젝트 파일은 포함할 콘텐츠, 플랫폼 요구 사항, 버전 관리 정보, 웹 서버 또는 데이터베이스 서버 설정 및 수행해야 하는 작업과 같이 프로젝트를 빌드하기 위해 MSBuild에 필요한 모든 정보와 지침을 포함하는 XML 문서입니다.
MSBuild 프로젝트 파일은 MSBuild XML 스키마를 기반으로 하므로 빌드 프로세스가 완전히 열려 있고 투명합니다. 또한 MSBuild 엔진을 사용하기 위해 Visual Studio를 설치할 필요가 없습니다. MSBuild.exe 실행 파일은 .NET Framework 일부이며 명령 프롬프트에서 실행할 수 있습니다. 개발자는 MSBuild XML 스키마를 사용하여 고유한 MSBuild 프로젝트 파일을 만들어 프로젝트를 빌드하고 배포하는 방법에 대해 정교하고 세분화된 제어를 적용할 수 있습니다. 이러한 사용자 지정 프로젝트 파일은 Visual Studio에서 자동으로 생성하는 프로젝트 파일과 정확히 동일한 방식으로 작동합니다.
참고
TFS(Team Foundation Server)에서 팀 빌드 서비스와 함께 MSBuild 프로젝트 파일을 사용할 수도 있습니다. 예를 들어 CI(연속 통합) 시나리오에서 프로젝트 파일을 사용하여 새 코드를 체크 인할 때 테스트 환경에 대한 배포를 자동화할 수 있습니다. 자세한 내용은 자동화된 웹 배포를 위한 Team Foundation Server 구성을 참조하세요.
프로젝트 파일 명명 규칙
고유한 프로젝트 파일을 만들 때 원하는 파일 확장자를 사용할 수 있습니다. 그러나 다른 사용자가 쉽게 이해할 수 있도록 하려면 다음과 같은 일반적인 규칙을 사용해야 합니다.
- 프로젝트를 빌드하는 프로젝트 파일을 만들 때 .proj 확장을 사용합니다.
- 재사용 가능한 프로젝트 파일을 만들어 다른 프로젝트 파일로 가져올 때 .targets 확장을 사용합니다. .targets 확장이 있는 파일은 일반적으로 아무것도 직접 빌드하지 않으며 , .proj 파일로 가져올 수 있는 지침만 포함됩니다.
배포 기술과 통합
Visual Studio 2010에서 웹 애플리케이션 프로젝트(예: ASP.NET 웹 애플리케이션 및 MVC 웹 애플리케이션 ASP.NET)로 작업한 경우 이러한 프로젝트에는 웹 애플리케이션을 패키징하고 대상 환경에 배포하기 위한 기본 제공 지원이 포함되어 있음을 알 수 있습니다. 이러한 프로젝트의 속성 페이지에는 애플리케이션의 구성 요소를 패키지하고 배포하는 방법을 구성하는 데 사용할 수 있는 패키지 /웹 게시 및 패키지 /게시 SQL 탭이 포함됩니다. 패키지 /웹 게시 탭이 표시됩니다.
이러한 기능의 기본 기술을 WPP(웹 게시 파이프라인)라고 합니다. WPP는 기본적으로 MSBuild 및 Web Deploy 를 함께 제공하여 웹 애플리케이션에 대한 전체 빌드, 패키지 및 배포 프로세스를 제공합니다.
좋은 소식은 웹 프로젝트에 대한 사용자 지정 프로젝트 파일을 만들 때 WPP가 제공하는 통합 지점을 활용할 수 있다는 것입니다. 프로젝트를 빌드하고, 웹 배포 패키지를 만들고, 단일 프로젝트 파일 및 MSBuild에 대한 단일 호출을 통해 원격 서버에 이러한 패키지를 설치할 수 있는 배포 지침을 프로젝트 파일에 포함할 수 있습니다. 빌드 프로세스의 일부로 다른 실행 파일을 호출할 수도 있습니다. 예를 들어 VSDBCMD.exe 명령줄 도구를 실행하여 스키마 파일에서 데이터베이스를 배포할 수 있습니다. 이 항목에서는 엔터프라이즈 배포 시나리오의 요구 사항을 충족하기 위해 이러한 기능을 활용하는 방법을 알아봅니다.
참고
웹 애플리케이션 배포 프로세스의 작동 방식에 대한 자세한 내용은 ASP.NET 웹 애플리케이션 프로젝트 배포 개요를 참조하세요.
프로젝트 파일 분석
빌드 프로세스를 좀 더 자세히 살펴보기 전에 MSBuild 프로젝트 파일의 기본 구조를 숙지하는 데 몇 분 정도 걸리는 것이 좋습니다. 이 섹션에서는 프로젝트 파일을 검토, 편집 또는 만들 때 발생하는 보다 일반적인 요소에 대한 개요를 제공합니다. 특히 다음 사항에 대해 알아봅니다.
- 속성을 사용하여 빌드 프로세스에 대한 변수를 관리하는 방법입니다.
- 항목을 사용하여 코드 파일과 같은 빌드 프로세스에 대한 입력을 식별하는 방법입니다.
- 프로젝트 파일의 다른 위치에 정의된 속성 및 항목을 사용하여 대상 및 작업을 사용하여 MSBuild에 실행 지침을 제공하는 방법입니다.
MSBuild 프로젝트 파일의 주요 요소 간의 관계를 보여 줍니다.
Project 요소
Project 요소는 모든 프로젝트 파일의 루트 요소입니다. 프로젝트 파일의 XML 스키마를 식별하는 것 외에도 Project 요소에는 빌드 프로세스의 진입점을 지정하는 특성이 포함될 수 있습니다. 예를 들어 Contact Manager 샘플 솔루션에서 Publish.proj 파일은 빌드가 FullPublish라는 대상을 호출하여 시작되도록 지정합니다.
<Project ToolsVersion="4.0" DefaultTargets="FullPublish"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
속성 및 조건
프로젝트 파일은 일반적으로 프로젝트를 성공적으로 빌드하고 배포하기 위해 다양한 정보를 제공해야 합니다. 이러한 정보에는 서버 이름, 연결 문자열, 자격 증명, 빌드 구성, 원본 및 대상 파일 경로 및 사용자 지정을 지원하기 위해 포함하려는 기타 정보가 포함될 수 있습니다. 프로젝트 파일에서 속성은 PropertyGroup 요소 내에서 정의되어야 합니다. MSBuild 속성은 키-값 쌍으로 구성됩니다. PropertyGroup 요소 내에서 요소 이름은 속성 키를 정의하고 요소의 콘텐츠는 속성 값을 정의합니다. 예를 들어 ServerName 및 ConnectionString이라는 속성을 정의하여 정적 서버 이름과 연결 문자열 저장할 수 있습니다.
<PropertyGroup>
<ServerName>FABRIKAM\TEST1</ServerName>
<ConnectionString>
Data Source=FABRIKAM\TESTDB;InitialCatalog=ContactManager,...
</ConnectionString>
</PropertyGroup>
속성 값을 검색하려면 $(PropertyName) 형식을 사용합니다. 예를 들어 ServerName 속성 값을 검색하려면 다음을 입력합니다.
$(ServerName)
참고
이 항목의 뒷부분에서 속성 값을 사용하는 방법과 시기에 대한 예제가 표시됩니다.
프로젝트 파일에 정적 속성으로 정보를 포함하는 것이 항상 빌드 프로세스를 관리하는 이상적인 방법은 아닙니다. 많은 시나리오에서 다른 원본에서 정보를 가져오거나 사용자가 명령 프롬프트에서 정보를 제공할 수 있도록 권한을 부여하려고 합니다. MSBuild를 사용하면 모든 속성 값을 명령줄 매개 변수로 지정할 수 있습니다. 예를 들어 사용자가 명령줄에서 MSBuild.exe 실행할 때 ServerName 에 대한 값을 제공할 수 있습니다.
msbuild.exe Publish.proj /p:ServerName=FABRIKAM\TESTWEB1
참고
MSBuild.exe 사용할 수 있는 인수 및 스위치에 대한 자세한 내용은 MSBuild 명령줄 참조를 참조하세요.
동일한 속성 구문을 사용하여 환경 변수 및 기본 제공 프로젝트 속성의 값을 가져올 수 있습니다. 일반적으로 사용되는 많은 속성이 정의되며 관련 매개 변수 이름을 포함하여 프로젝트 파일에서 사용할 수 있습니다. 예를 들어 현재 프로젝트 플랫폼(예: x86 또는 AnyCpu)을 검색하려면 프로젝트 파일에 $(Platform) 속성 참조를 포함할 수 있습니다. 자세한 내용은 빌드 명령 및 속성에 대한 매크로, 일반적인 MSBuild 프로젝트 속성 및 예약 속성을 참조하세요.
속성은 종종 조건과 함께 사용됩니다. 대부분의 MSBuild 요소는 MSBuild 가 요소를 평가해야 하는 조건을 지정할 수 있는 Condition 특성을 지원합니다. 예를 들어 다음 속성 정의를 고려합니다.
<PropertyGroup>
<OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\</OutputRoot>
...
</PropertyGroup>
MSBuild가 이 속성 정의를 처리할 때 먼저 $(OutputRoot) 속성 값을 사용할 수 있는지 확인합니다. 속성 값이 비어 있으면 즉, 사용자가 이 속성에 대한 값을 제공하지 않은 경우 조건이 true 로 평가되고 속성 값이 로 설정됩니다 . \Publish\Out. 사용자가 이 속성에 대한 값을 제공한 경우 조건은 false 로 평가되고 정적 속성 값은 사용되지 않습니다.
조건을 지정할 수 있는 다양한 방법에 대한 자세한 내용은 MSBuild 조건을 참조하세요.
항목 및 항목 그룹
프로젝트 파일의 중요한 역할 중 하나는 빌드 프로세스에 대한 입력을 정의하는 것입니다. 일반적으로 이러한 입력은 코드 파일, 구성 파일, 명령 파일 및 빌드 프로세스의 일부로 처리하거나 복사해야 하는 기타 파일입니다. MSBuild 프로젝트 스키마에서 이러한 입력은 Item 요소로 표시됩니다. 프로젝트 파일에서 항목은 ItemGroup 요소 내에서 정의되어야 합니다. Property 요소와 마찬가지로 원하는 방식으로 Item 요소의 이름을 지정할 수 있습니다. 그러나 항목이 나타내는 파일 또는 와일드카드를 식별하려면 Include 특성을 지정해야 합니다.
<ItemGroup>
<ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
</ItemGroup>
이름이 같은 여러 Item 요소를 지정하면 명명된 리소스 목록을 효과적으로 만들 수 있습니다. 이 작업을 수행하는 좋은 방법은 Visual Studio에서 만드는 프로젝트 파일 중 하나를 살펴보는 것입니다. 예를 들어 샘플 솔루션의 ContactManager.Mvc.csproj 파일에는 항목 그룹이 많이 포함되며 각각 이름이 동일한 항목 요소가 여러 개 있습니다.
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
...
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\ContactsController.cs" />
<Compile Include="Controllers\HomeController.cs" />
...
</ItemGroup>
<ItemGroup>
<Content Include="Content\Custom.css" />
<Content Include="CreateDatabase.sql" />
<Content Include="DropDatabase.sql" />
...
</ItemGroup>
이러한 방식으로 프로젝트 파일은 MSBuild에 동일한 방식으로 처리해야 하는 파일 목록을 생성하도록 지시합니다. 참조 목록에는 성공적인 빌드를 위해 준비해야 하는 어셈블리가 포함되고, 컴파일 목록에는 컴파일해야 하는 코드 파일이 포함되며, 콘텐츠 목록에는 변경되지 않고 복사해야 하는 리소스가 포함됩니다. 빌드 프로세스가 이 항목의 뒷부분에서 이러한 항목을 참조하고 사용하는 방법을 살펴보겠습니다.
항목 요소에는 ItemMetadata 자식 요소가 포함될 수도 있습니다. 이러한 쌍은 사용자 정의 키-값 쌍이며 기본적으로 해당 항목과 관련된 속성을 나타냅니다. 예를 들어 프로젝트 파일의 많은 Compile 항목 요소에는 DependentUpon 자식 요소가 포함됩니다.
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
참고
사용자가 만든 항목 메타데이터 외에도 모든 항목에는 생성할 때 다양한 공통 메타데이터가 할당됩니다. 자세한 내용은 잘 알려진 항목 메타데이터를 참조하세요.
루트 수준 Project 요소 또는 특정 대상 요소 내에서 ItemGroup 요소를 만들 수 있습니다. 또한 ItemGroup 요소는 조건 특성을 지원하므로 프로젝트 구성 또는 플랫폼과 같은 조건에 따라 입력을 빌드 프로세스에 맞게 조정할 수 있습니다.
대상 및 작업
MSBuild 스키마에서 Task 요소는 개별 빌드 명령(또는 작업)을 나타냅니다. MSBuild에는 미리 정의된 여러 작업이 포함됩니다. 예를 들면 다음과 같습니다.
- 복사 작업은 파일을 새 위치에 복사합니다.
- Csc 작업은 Visual C# 컴파일러를 호출합니다.
- Vbc 작업은 Visual Basic 컴파일러를 호출합니다.
- Exec 작업은 지정된 프로그램을 실행합니다.
- 메시지 태스크는 로거에 메시지를 씁니다.
참고
기본 제공되는 작업에 대한 자세한 내용은 MSBuild 작업 참조를 참조하세요. 사용자 지정 작업을 만드는 방법을 포함하여 작업에 대한 자세한 내용은 MSBuild 작업을 참조하세요.
작업은 항상 대상 요소 내에 포함되어야 합니다. Target 요소는 순차적으로 실행되는 하나 이상의 작업 집합이며 프로젝트 파일에는 여러 대상이 포함될 수 있습니다. 작업 또는 작업 집합을 실행하려는 경우 해당 작업이 포함된 대상을 호출합니다. 예를 들어 메시지를 기록하는 간단한 프로젝트 파일이 있다고 가정해 보겠습니다.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="LogMessage">
<Message Text="Hello world!" />
</Target>
</Project>
/t 스위치를 사용하여 대상을 지정하여 명령줄에서 대상을 호출할 수 있습니다.
msbuild.exe Publish.proj /t:LogMessage
또는 Project 요소에 DefaultTargets 특성을 추가하여 호출할 대상을 지정할 수 있습니다.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="FullPublish">
<Target Name="LogMessage">
<Message Text="Hello world!" />
</Target>
</Project>
이 경우 명령줄에서 대상을 지정할 필요가 없습니다. 프로젝트 파일을 지정하기만 하면 MSBuild가 FullPublish 대상을 호출합니다.
msbuild.exe Publish.proj
대상과 작업 모두 조건 특성을 포함할 수 있습니다. 따라서 특정 조건이 충족되는 경우 전체 대상 또는 개별 작업을 생략하도록 선택할 수 있습니다.
일반적으로 유용한 작업 및 대상을 만들 때 프로젝트 파일의 다른 곳에서 정의한 속성 및 항목을 참조해야 합니다.
- 속성 값을 사용하려면 $(PropertyName)을 입력합니다. 여기서 PropertyName 은 Property 요소의 이름 또는 매개 변수의 이름입니다.
- 항목을 사용하려면 @(ItemName)을 입력합니다. 여기서 ItemName 은 Item 요소의 이름입니다.
참고
이름이 같은 여러 항목을 만드는 경우 목록을 작성하는 것입니다. 반면, 동일한 이름을 가진 여러 속성을 만드는 경우 제공한 마지막 속성 값은 동일한 이름의 이전 속성을 덮어씁니다. 속성은 단일 값만 포함할 수 있습니다.
예를 들어 샘플 솔루션의 Publish.proj 파일에서 BuildProjects 대상을 살펴봅니다 .
<Target Name="BuildProjects" Condition=" '$(BuildingInTeamBuild)'!='true' ">
<MSBuild Projects="@(ProjectsToBuild)"
Properties="OutDir=$(OutputRoot);
Configuration=$(Configuration);
DeployOnBuild=true;
DeployTarget=Package"
Targets="Build" />
</Target>
이 샘플에서는 다음 핵심 사항을 관찰할 수 있습니다.
BuildingInTeamBuild 매개 변수가 지정되고 값이 true이면 이 대상 내의 태스크가 실행되지 않습니다.
대상에는 MSBuild 작업의 단일 instance 포함됩니다. 이 작업을 통해 다른 MSBuild 프로젝트를 빌드할 수 있습니다.
ProjectsToBuild 항목이 작업에 전달됩니다. 이 항목은 프로젝트 또는 솔루션 파일 목록을 나타낼 수 있으며, 모두 항목 그룹 내 의 ProjectsToBuild 항목 요소에 의해 정의됩니다. 이 경우 ProjectsToBuild 항목은 단일 솔루션 파일을 참조합니다.
<ItemGroup> <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/> </ItemGroup>
MSBuild 작업에 전달된 속성 값에는 OutputRoot 및 Configuration이라는 매개 변수가 포함됩니다. 이러한 값은 매개 변수 값이 제공된 경우 또는 정적 속성 값이 아닌 경우 매개 변수 값으로 설정됩니다.
<PropertyGroup> ... <Configuration Condition=" '$(Configuration)'=='' ">Release </Configuration> <OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\ </OutputRoot> ... </PropertyGroup>
MSBuild 태스크가 Build라는 대상을 호출하는 것을 볼 수도 있습니다. Visual Studio 프로젝트 파일에서 널리 사용되며 빌드, 정리, 다시 빌드 및 게시와 같은 사용자 지정 프로젝트 파일에서 사용할 수 있는 몇 가지 기본 제공 대상 중 하나입니다. 대상 및 태스크를 사용하여 빌드 프로세스를 제어하는 방법, 특히 MSBuild 작업에 대한 자세한 내용은 이 항목의 뒷부분에서 알아봅니다.
참고
대상에 대한 자세한 내용은 MSBuild 대상을 참조하세요.
여러 환경을 지원하도록 프로젝트 파일 분할
테스트 서버, 스테이징 플랫폼 및 프로덕션 환경과 같은 여러 환경에 솔루션을 배포할 수 있다고 가정합니다. 구성은 서버 이름, 연결 문자열 등뿐만 아니라 자격 증명, 보안 설정 및 기타 여러 요인 측면에서도 이러한 환경마다 크게 다를 수 있습니다. 이 작업을 정기적으로 수행해야 하는 경우 대상 환경을 전환할 때마다 프로젝트 파일에서 여러 속성을 편집하는 것이 정말 편하지 않습니다. 빌드 프로세스에 속성 값의 무한 목록을 제공해야 하는 이상적인 솔루션도 아닙니다.
다행히 대안이 있습니다. MSBuild를 사용하면 빌드 구성을 여러 프로젝트 파일로 분할할 수 있습니다. 이 작동 방식을 확인하려면 샘플 솔루션에서 다음 두 개의 사용자 지정 프로젝트 파일이 있습니다.
- Publish.proj는 모든 환경에 공통적인 속성, 항목 및 대상을 포함합니다.
- 개발자 환경과 관련된 속성이 포함된 Env-Dev.proj.
이제 Publish.proj 파일에는 열기 프로젝트 태그 바로 아래에 Import 요소가 포함되어 있습니다.
<Import Project="$(TargetEnvPropsFile)"/>
Import 요소는 다른 MSBuild 프로젝트 파일의 내용을 현재 MSBuild 프로젝트 파일로 가져오는 데 사용됩니다. 이 경우 TargetEnvPropsFile 매개 변수는 가져오려는 프로젝트 파일의 파일 이름을 제공합니다. MSBuild를 실행할 때 이 매개 변수에 대한 값을 제공할 수 있습니다.
msbuild.exe Publish.proj /p:TargetEnvPropsFile=EnvConfig\Env-Dev.proj
이렇게 하면 두 파일의 내용을 단일 프로젝트 파일로 효과적으로 병합합니다. 이 방법을 사용하여 유니버설 빌드 구성을 포함하는 하나의 프로젝트 파일과 환경별 속성을 포함하는 여러 보조 프로젝트 파일을 만들 수 있습니다. 따라서 매개 변수 값이 다른 명령을 실행하기만 하면 솔루션을 다른 환경에 배포할 수 있습니다.
이러한 방식으로 프로젝트 파일을 분할하는 것이 좋습니다. 개발자는 단일 명령을 실행하여 여러 환경에 배포하는 동시에 여러 프로젝트 파일에서 범용 빌드 속성이 중복되는 것을 방지할 수 있습니다.
참고
사용자 고유의 서버 환경에 대한 환경별 프로젝트 파일을 사용자 지정하는 방법에 대한 지침은 대상 환경에 대한 배포 속성 구성을 참조하세요.
결론
이 항목에서는 MSBuild 프로젝트 파일에 대한 일반적인 소개를 제공하고 빌드 프로세스를 제어하기 위해 사용자 지정 프로젝트 파일을 만드는 방법을 설명했습니다. 또한 프로젝트를 쉽게 빌드하고 여러 대상에 배포할 수 있도록 프로젝트 파일을 범용 빌드 지침 및 환경별 빌드 속성으로 분할하는 개념을 도입했습니다.
다음 항목인 빌드 프로세스 이해에서는 현실적인 수준의 복잡성으로 솔루션 배포를 안내하여 프로젝트 파일을 사용하여 빌드 및 배포를 제어하는 방법에 대한 더 많은 인사이트를 제공합니다.
추가 정보
프로젝트 파일 및 WPP에 대한 자세한 소개는 Microsoft Build Engine 내부: Sayed Ibrahim Hashimi 및 William Bartholomew, ISBN: 978-0-7356-4524-0의 MSBuild 및 Team Foundation 빌드 사용을 참조하세요.