MSBuild로 비주얼 스튜디오 솔루션(.sln)을 빌드할 때

  • Post author:
  • Post category:
  • Post comments:16 Comments
  • Post last modified:July 5, 2008

윈도우 프로젝트 필수 유틸리티엔 다음과 같은 대목이 있다.

< devenv > 를 사용하면 Release 모드와 Debug 모드를 구분해서 빌드할 수 있지만, 32, 64비트 빌드를 구분해서 할 수는 없습니다. < devenv >에서 64비트 빌드를 하려면 프로젝트 설정에서 Win32 플랫폼은 삭제하고 x64만 남겨두어야 합니다. VCBuild는 Release 모드와 Debug 모드를 구분해서 빌드할 수 있고, 32, 64비트 빌드를 구분하여 할 수 있습니다.

여기서 말하는 devenv 엘레멘트는 CruiseControl .NET의 설정 파일인 ccnet.config에서 사용된다. 다행스럽게도 이 문제는 MSBuild를 쓰면 쉽게 해결된다. MSBuild 스크립트에서 윈도우 솔루션 파일을 빌드하고, ccnet.config에선 이 스크립트를 실행시키면 된다. 단, 몇 가지 주의할 점이 있다. 마이크로소프트웨어 연재 칼럼에서 하나씩 밝혀나갈 생각인데, 간단하게 요약해보자.

MSBuild 바이너리를 잘 골라야 한다

MSBuild 바이너리는 닷넷 프레임워크와 함께 배포되며 보통 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild.exe 같은 경로를 취한다. 이때 해당 소스 코드가 참조하는 닷넷 프레임워크 버전에 맞춰 경로를 잡아야 한다. 또 64비트 컴파일을 할 거라면 Framework가 아닌 Framework64를 선택해야 한다.

C# 프로젝트는 쉽다

C# 같은 순수 닷넷 프로젝트라면 빌드 자동화가 쉽다. 지속적인 통합 5편에서 언급한 바 있듯, C# 프로젝트 파일(.csproj) 및 솔루션 파일(.sln)은 그 자체가 MSBuild 스크립트에 불과하다. 그래서 다음과 같이 ccnet.config를 구성해도 된다.

<tasks>
         <msbuild>
                    <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
                    <workingDirectory>C:\src\MyProject -mainbuild\trunk\server\src\ConsoleApplication </workingDirectory>
                   <projectFile>ConsoleApplication .sln</projectFile>
                   <buildArgs>/noconsolelogger /p:Configuration=Debug;Platform=Win32 /v: minimal</buildArgs>
                    <logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MSBuild.dll</logger>
         </msbuild>
</tasks>

C++ 프로젝트는 특별하다

안타깝게도 MSBuild 바이너리는 C++ 프로젝트는 빌드하지 못한다. 단 별도의 MSBuild 스크립트를 만들면 방법이 있다. MSBuild엔 <msbuild>란 태스크가 있는데, 여기에 솔루션 파일 이름을 적어주면 대부분 빌드가 된다. 한데 msbuild 태스크는 비주얼 스튜디오 바이너리(devenv.exe)를 호출하지 않고, VCBuild 바이너리를 호출한다. 이는 IDE 종속성을 제거한다는 측면에서 바람직하지만, 안타깝게도 devenv와 VCBuild가 항상 똑같은 방식으로 작동하는 건 아니다. 특히 C++/CLI 기술을 쓰는 경우엔 비주얼 스튜디오로는 빌드가 되던 솔루션을 MSBuild로 빌드하려면 실패하는 일이 잦다.

이땐, MSBuild의 <Exec> 태스크를 사용하여 Devenv를 직접 호출하면 된다. 비주얼 스튜디오 바이너리는 설정(Configuration)값과 플랫폼(Platform)값을 매개변수로 받기 때문에 앞서 윈도우 프로젝트 필수 유틸리티의 한 대목에서 소개한 문제도 발생하지 않는다.

CCNET에는 MSBuild용 로거가 있다. 이 로거는 MSBuild 스크립트에서 <msbuild> 태스크를 사용하여 솔루션 파일을 빌드할 때 가장 잘 작동한다. 하지만 다행스럽게도 <Exec> 태스크를 사용해도 이 로거는 작동한다. 단지, 로그 상세 정도를 지정하는 옵션(Verbose)은 제대로 동작하지 않기 때문에, 웹 대시보드에서 표시되는 로그가 상당히 길어지기 마련이다. 하지만 빌드가 깨졌을 때만 웹 대시보드에 들리게 되니 마우스 스크롤의 불편함 정도는 감수할만하다.

This Post Has 16 Comments

  1. 바하문트

    언제나 느끼는 거지만 프로그래머들은 머리구조가 괴상한 것 같습니다^-^ 이런 걸 매일 어떻게 들여다 보고 있는지…

  2. 최재훈

    제가 생각해도 신기할 때가 있습니다.  gulp

  3. 2P

    안녕하세요 몇가지 질문이 있어서 글남깁니다.
    msbuild를 사용하는 이유가 32/64 비트 구분하는 이유 뿐인가요?
    cruisecontrol.net 에서도 exec태스크가 있어서 여기서 직접 devenv를 다뤄도 되겠다 싶은데
    굳이 msbuild를 사용하는 이유가 있는지 궁금합니다.
    그리고 저는 .net framework 2.0.50727 깔려있긴한데 msbuild 바이너리가 없더군요..

    참, 마지막으로 msbuild로 vc7 프로젝트도 빌드가 가능한가요? (vc8부터 기본 포함 툴이라고 들어서..)

  4. 최재훈

    “C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727” 이 디렉터리에 바이너리가 있으리라 생각합니다.

    MSBuild는 비주얼 스튜디오와 상관없이 닷넷 프레임워크 SDK의 일부로써 배포됩니다.

    MSBuild에서 Exec 태스크를 이용해 devenv.exe를 호출하여 빌드하시는 편이 좋습니다.

    MSBuild를 사용하면 여러 가지 일을 할 수 있습니다. 데이터베이스를 생성한다던가, SVN을 조정한더던가. CCNet은 MSBuild를 호출하는 역할만 하고, 실제 빌드는 MSBuild에서 하는 편이 좋습니다.

  5. 2P

    답변 감사드립니다.  surprised
    당연히 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild”에 있을줄 알았는데 “C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\” 에 들어있었던거군요.;;
    하지만 msbuild가 vc7 프로젝트는 지원을 하지 않는지 최신버전으로 변환하라는 메세지를 토해냅니다  downer
    NAnt를 사용하든지 해야할것 같네요

  6. 최재훈

    myproject.sln 이렇게 하시나요? 저는 < exec cmd="devenv.exe /build myproject.sln" / >

    을 추천합니다.

    일단 첫번째 방식이라고 가정하겠습니다. msbuild의 버전을 바꿔보세요. .NET Framework 3.0이나 1.1 디렉터리에 있는 MSBuild로 시도해보면 될 겁니다. VC7이라면 VS2005을 말씀하시는 듯 한데, 저희 팀에선 VS2005와 VS2008을 둘 다 자동화해서 씁니다. 안 되진 않을 겁니다.

  7. 2P

    감사합니다.ㅜ.ㅡ
    vs2003 사용중입니다.
    조금 검색을 해봤더니 vs2003은 msbuild에서 지원하지 않는다는 내용뿐이네요..
    말씀하신 다른버전의 .net framework도 검토해봤ㅇ나 1.x 에는 msbuild가 포함되어있지 않고 3.x에는 역시나 지원하지 않는군요
    2005나 2008로 마이그레이션을 계획중이긴 한데 아직 곤란한 점이 한두가지 남아있는 상황이라
    일단 CI는 exec를 통해서 해두도록 하고 이후에 마이그레이션이 진행된다면 바꿔야겠군요 ㅜ.ㅡ

  8. 최재훈

    아, VC7이란 게 VS2003이었던가요? 제가 헷갈렸군요. 말씀하신대로 VC7에선 < msbuild >

    태스크를 써서 솔루션 파일을 빌드하지 못합니다.

    그렇다하더라도 닷넷 프레임워크 2.0을 설치하고,

    < exec >

    태그를 사용하면 문제 없을 겁니다.

  9. 김정선

    안녕하세요.

    MSbuild를 이용해서 .sln을 빌드할 때, XML document file이 자동으로 만들어지도록 하는 option이 있나요? 각 project file에다 설정을 해주려니 너무 많아서요. (Projec file -> Properties -> Build -> output -> XML document file)

    Thanks.

  10. 최재훈

    XML 문서화는 C#에서만 지원되는 기능이라 C++/CLI를 주로 쓰는 입장에선 거의 안 쓰게 됩니다. 더 손쉬운 방법이 있는진 저도 모르겠습니다.

    사실 이렇게 손이 많이 가는 부분이 참 답답한데요. XML 문서화 기능은 차지하고라도 거의 동일한 빌드 설정값을 프로젝트마다 설정해야 할 때는 참 답답합니다.

  11. 김정선

    앗 감사합니다. 답변이 너무 빨라서 깜짝 놀랬네여.
    예.. msbuild에서 option으로 처리할 수 있으면 좋을텐데 아쉽네여.
    감사합니다!

  12. 이정우

    안녕하세요. .net 관련 프로젝트를 처음 진행을 하게 되었습니다. 정말 많은 도움이되고 있습니다. 감사합니다. 다름이 아니라 자동화 환경 구축을 테스트하고 있는데요. 이상한 점이 있어서요.
    svn 에서 변경된 정보를 xml 로 가져옴에도 불구하고
    ccnet 로그에서는 “No modifications detected.” 라고 자꾸 나오는군요.~ force build 하면 update 되고요. google 에 찾아봐도 비슷한 증상이 있는거 같은데요.~~ 어찌된 일인지 모르겟네요. 혹시 이부분에 대한 피드백을 받을 수 있는지요?

  13. 이정우

    아 해결했습니다.~ svn 서버의 시간과 ccnet 서버의 시간이 맞지 않아서…  issue 에 등록이 되어 있네요.~~감사합니다.

  14. CHOI, Jaehoon

    방금 질문을 봤는데 벌써 해결하셨다니 다행이네요.  grin

  15. 이정우

    시간은 해결이 된거 같은데요. force build 를 하면 cctray에서 알림을 해줍니다.
    그런데 자동 빌드됬을 대에는 공지를 안해주네요. 이상한 점은 아래와 같은 메세지가 서버 로그에 찍힙니다.
    The most recent modification at 2009-03-24 오전 8:26:34 is within in the modification delay.  Waiting for 7.8 seconds until 2009-03-24 오전 8:26:44 before checking again.
    조언 부탁드립니다.~~

  16. 최재훈

    아침 일찍 출근하셨나 보네요. 아래 메시지는 신경 안 쓰셔도 됩니다. SVN이 아닌 CVS 같이 원자적 커밋을 지원 안 하는 소스서버를 쓸 때 일정 시간을 기다렸다가 빌드하게 하는 옵션일 뿐입니다.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.