프로젝트 개수가 많아지다 보면 솔루션 파일을 열어 Visual Studio상에서 빌드를 하는 것보다는 MSBuild를 사용하여 빌드를 하는 것이 현명한 선택일 것입니다. MSBuild를 사용할 경우에 단순히 솔루션 파일을 지정해주면 빌드가 정상적으로 완료되지 않습니다. 바로 프로젝트 간에 참조 문제 때문입니다. MSBuild에서는 파라미터로 솔루션 파일을 지정해주면 해당 솔루션 파일에 정의된 프로젝트 순서대로 빌드 순서를 정해버립니다.
아래의 사이트는 이러한 문제점을 해결해줍니다.
http://serialize.wordpress.com/2009/12/16/msbuild-task/

처음 MSBuild를 접하시는 분은 위의 사이트를 눈을 크게 뜨고 보아도 실행이 잘되지 않을 것입니다.(제가 그랬습니다. ㅋ)
<Project DefaultTargets="BuildProjects" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

 

  <Target Name="BuildProjects">

 

    <GetProjecsInOrder Solution="$(MSBuildProjectDirectory)\MySolution.sln">

      <Output ItemName="ProjectFiles" TaskParameter="Output"/>

    </GetProjecsInOrder>

   

    <Message Text="%(ProjectFiles.FullPath)"/>

   

    <MSBuild Projects="%(ProjectFiles.FullPath)"

      Targets="Build"

      Properties="Configuration=Release"/>

  </Target>

 

  <UsingTask AssemblyFile="MSBuildTasks.dll" TaskName="GetProjecsInOrder" />

 

</Project>

=> MSBuildTasks.dll이라는 사용하는 구문을 몰라서였습니다. -_- MSBuildTasks.dll소스를 열어보면 Task라는 클래스(빌드가 되는 단위 ITaskItem이 프로젝트와 매칭되는 빌드의 단위)를 상속받아서 구현하고 있는 것을 볼 수 있습니다. 솔루션 파일를 정규식으로 필터링을 해서 프로젝트의 정보를 얻습니다. 이 프로젝트 정보로 해당 프로젝트 파일를 열어 프로젝트 파일에 있는 프로젝트 참조에 대한 정보를 정규식을 통해서 얻습니다. 이렇게 모든 정보를 얻고 나서 Recusive한 알고리즘(?!)을 통해서 빌드되는 프로젝트의 순서를 정해주게 됩니다. 위의 Message 앨리먼트를 사용하게 되면 이러한 빌드 순서에 대해서 화면에 찍어주게 됩니다.
한 가지 아쉬운 점이라면 바로 프로젝트 참조에 대해서만 빌드 순서를 정해준다는 것입니다. 물론 일반적인 솔루션이라면 당연히 프로젝트 참조 대해서만 빌드 순서를 정해주면 되지만 모든지 예외는 존재하는 것 같습니다. 그닥 어렵지는 않습니다. 이전 포스트에서 소개해드린 솔루션 파일에 어셈블리 참조에 대한 Project Dependencies 정보가 사전에 필요합니다. 그리고 이 정보를 사용하여 어셈블리 참조에 대한 정보를 얻어 위에서 사용한 Recursive한 루틴을 태우면 됩니다. 프로젝트 참조와 어셈블리 참조 모두를 적용하면 어떻게 될지도 궁금하네요 ^^

<2010-05-12>
MSBuild에서 솔루션 파일안에 프로젝트 파일의 정보 순서대로 빌드를 해준다고 생각했었는데 다시 해보니 Project Dependency에 의해서 빌드 순서를 정해서 빌드를 합니다. 위의 사이트의 해결방법이 그렇다면 쓸모없는 방법이라는 결론입니다. 하지만 700정도 되는 프로젝트를 단순히 솔루션 파일에 의해서 MSBuild를 하면 제대로 빌드가 되지 않습니다. 무엇인가 정확하게 알지 못하는 부분이 있는 것 같아 정확하게 원인이 파악되면 다시 글을 수정하도록 하겠습니다.

<2010-05-23>
Project Dependency를 나타내는 방법은 아래의 두 가지입니다.
1. 프로젝트 참조를 한다.
2. Project Dependencies 메뉴에서 수동으로 Dependency를 정의한다.
2번 째 방법은 솔루션 파일에 ProjectSection(ProjectDependencies)에서 찾아볼 수 있지만 1번 째 방법은 그렇지 않습니다.

MSBuild시에 솔루션 파일을 지정하고 빌드할 경우 테스트해 본 결과 1번째 2번째 방법 모두 빌드 오더를 MSBuild 자체적으로 계산하여 정확하게 빌드를 해주는 것을 확인하였습니다. 위의 사이트의 해결방법이 쓸모없는 방법인 것으로 판단됩니다. --;
Posted by resisa