로컬 컴퓨터에선 Win32 빌드를 하고 빌드 서버에서 x64 빌드를 검증하는 식으로 일하는데, 이번에 x64 빌드가 깨졌다. 뭐가 문제인가 했더니 C++/CLI 프로젝트 하나가 C4945 경고를 내뱉는 바람에, 전체 빌드가 실패하고 말았다. 경고는 곧 오류다라는 정책을 채택했기 때문에 이건 대충 넘어갈 수 있는 문제가 아니었다. 그래서 문제의 원인부터 파악하기로 했다.
warning C4945: ‘DescriptionAttribute’ : cannot import symbol from ‘c:\windows\microsoft.net\framework\v2.0.50727\system.dll’: as ‘System::ComponentModel::DescriptionAttribute’ has already been imported from another assembly
로그를 보니 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll 파일을 참조하는 게 아닌가? x64 빌드이니 C:\WINDOWS\Microsoft.NET\Framework64\를 참조해야 하는데, 뭔가 이상했다. 프로젝트 파일(.vcproj)을 텍스트 편집기에서 열어보니, 경로가 하드코딩되어 있진 않았다.
<References> <AssemblyReference RelativePath="System.dll" AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" CopyLocalDependencies="false" CopyLocalSatelliteAssemblies="false" MinFrameworkVersion="131072" /> </References>
이상하다 싶어 빌드 컴퓨터에 접속해 비주얼 스튜디오를 열고 직접 x64 빌드를 해봤다. 그랬더니 웬걸, 빌드가 된다. 이건 아무래도 msbuild의 버그라는 생각이 순간 들었다. 전에도 비슷한 일이 있었다. MSBuild는 특히 C++/CLI 프로젝트 빌드와 관련된 버그가 많았다. 웹을 뒤져보니 이 문제로 고생한 사람이 많은 듯 했다. 하지만 대부분이 Visual Studio 2005를 사용하고 있었고, 진작에 Hotfix가 나왔다고 한다. 핫픽스가 나온지 오래됐으니 Visual Studio 2008이나 .NET Framework 3.5용 MSBuild에는 이런 문제가 없어야 정상이 아닌가? 어쨌거나 마음이 급해서 핫픽스를 받아볼까 했지만, 그것도 쉽지 않았다. 마이크로소프트 지원 센터에 전화해서 받으라는데, 상담료가 들 뿐더러 몇몇 사람은 이 핫픽스로도 문제가 해결되지 않는다고 했기 때문이다. 실제로 고객 지원 문서에 적힌대로 조치를 취해도 문제가 해결되지 않았기 때문에 다른 방법을 강구해보기로 했다.
드디어 해결
문제를 해결하려면 기본적으로 참조 기능(프로젝트 속성 페이지-공용 속성-프레임워크 참조)에 의존하지 말아야 한다. 특히 System.dll 같은 글로벌 어셈블리는 직접 참조하지 않는다. 대신 [구성 속성-C/C++-고급-#using 강제] 창에 System.dll이라고 적어넣는다. 만약 직접 개발한 프로젝트를 참조해야 한다면, 참조 기능과 #using 강제 기능을 둘 다 쓴다. 참조 기능을 써야 프로젝트 의존성을 부여할 수 있기 때문이다.
에구, 이번 주의 절반은 빌드 서버 때문에 날렸다.
kaistzen님의 집념에 박수를 보냅니다. 덕분에 좋은 팁을 알았네요,만일 저와 같은 경우에는 제가 도움을 드릴수도 있습니다.
감사합니다. ^^
C++/CLI 쪽이 아직 미흡한 점이 있는 것 같고, 특히 x64 환경으로 가면 아쉬운 점이 많네요. SDK 쪽은 잘 갖춰진 것 같은데 도구 쪽이 아직 진행형 같습니다. 조금씩 개선되서 팁이 없어도 되는 제품이 되면 좋겠네요.