실전! 지속적인 통합 3편: 지속적인 컴파일, 그 첫걸음

이 글은 월간 마이크로소프트웨어(일명 마소) 2008년 3월호에 기고한 글입니다. 물론 구성이나 내용 상의 차이가 있을 수 있습니다.

이번 시간엔 지속적인 통합의 시작이자 꽃이라 할 수 있는 컴파일 자동화를 다룬다. 64비트용 Visual C++ 애플리케이션을 개발할 때 부딪힐 법한 문제를 하나씩 해결해보자. 드라이버 문제 등으로 개발자는 32비트 윈도우에서 개발하는데, 개발한 애플리케이션을 실제로 배포할 곳은 64비트 운영체제라면 어떻게 될까? 64비트 운영체제가 처음 등장했을 때, 기존 애플리케이션 중 상당수가 제대로 작동하지 않거나 죽어버리는 일이 많았다. 사용자가 아닌 개발자의 입장에서 보면, 로컬 컴퓨터에서 잘 컴파일되던 코드가 64비트에선 경고나 오류를 내는 경우를 심심찮게 보게 된다. 지속적인 컴파일을 통해 이러한 문제를 조기에 탐지하고, 문제가 걷잡을 수 없게 번지기 전에 해결책을 강구해보자.

최재훈 | SK 아이미디어에서 싸이월드의 새로운 3D 서비스를 개발하고 있다. 주로 닷넷과 Visual C++, 그리고 Microsoft SQL Server를 즐겨 다루고, 디자인 패턴, 리팩토링, 애자일에도 관심을 갖고 있다. 솔직히 말해 흥미로운 주제는 닥치는 대로 읽고 공부하는 편이다.

3월이 되었으니 지속적인 통합 시리즈도 이로써 3번째 글이 된다. 첫 시간엔 지속적인 통합이 무엇인지, 그리고 지속적인 통합을 하면 하루 일과가 어떻게 변하는지를 살펴봤다. 두번째 시간에는 버전 관리 시스템인 서브버전과 이슈 추적 시스템인 Trac을 설치하는 법을 알아봤다. 항상 지면에 쫒겨 설치하는 법만 다루기에 벅찬데, 실제로 활용하는 모습은 기회가 닿을 때마다 조금씩 알아보겠다.

버전 관리 시스템도 갖춰졌으니, 이번 시간에는 아마도 가장 관심이 갈 주제인 지속적인 컴파일에 대해 알아보려 한다. 다만 지속적인 컴파일은 한 회에 다루기엔 너무나 벅찬 주제이기 때문에 가장 간단한 빌드 서버 설치법부터 좀더 어려운 빌드 스크립트 작성법까지 차근차근 알아볼 생각이다.

지속적인 컴파일

지속적인 통합이라 하면 여러 측면에서 살펴볼 수 있다. 크게 나누면 리팩토링과 잦은 커밋 같은 사람이 하는 일이 있고, 빌드 자동화라 통칭해 부르는 컴퓨터가 하는 일이 있다. 이 글에서 중점을 두는 빌드 자동화만 하더라도 또 다시 여러 단계로 나뉘는데, 형상 관리(버전 관리 저장소), 지속적인 컴파일, 지속적인 데이터베이스 통합, 지속적인 테스트 등이 있다. 지난 번에는 형상 관리용 버전 관리 시스템을 설치해봤으니, 이번엔 지속적인 컴파일의 기초적인 지식을 쌓아볼 차례다. 다시 한번 말하지만, 이 글은 Windows 기반의 애플리케이션을 개발하는 실전 사례를 바탕으로 한다. 특히 64비트 시스템 위에 돌아가는 서버 애플리케이션을 주로 다루기 때문에 사용자 인터페이스와 관련된 이슈는 거의 나오지 않을 것이다. 프로그래밍 언어 측면에서 보자면 Visual C++와 C#이 주가 되며, 그 중에서도 C++의 비중이 아주 높다.

목록 1. 지속적인 통합의 여러 측면들

  • 지속적인 컴파일

  • 지속적인 데이터베이스 통합

  • 지속적인 테스트

  • 지속적인 검사 (Continuous Inspection)

  • 지속적인 배포

  • 지속적인 피드백

[목록 1]은 지속적인 통합을 좀더 잘게 나누어본 것인데, 지난 시간에 설치법을 알아본 버전 관리 저장소는 이 모든 측면의 기초가 되며, 형상 관리 시스템은 지속적인 피드백의 한 축을 이룬다. 그리고 나중에 다룰 주제인 빌드 스크립트는 이 모든 걸 실현 가능하게 해주고 묶어주는 풀 같은 역할을 한다.

빌드 환경

노파심에 한번 더 말하지만, 이 글에선 Windows 기반의 게임 서버를 개발하는 사례를 살펴본다. 때문에 거의 100% 윈도우 기반 애플리케이션을 쓰게 된다. 그리고 게임 서버이다 보니 닷넷보다는 Visual C++을 주로 다룬다(물론 닷넷도 언급할 기회가 있을 것이다). 자바나 닷넷의 경우엔 지속적인 통합을 매우 잘 지원하고 있고, 책이나 온라인 문서를 구하기 쉽기 때문에 구현 과정에서 그리 큰 어려움을 겪지 않을 것이니만큼, 이 글의 편향성은 고통 받는 사람을 위한 배려라 생각해주길 바란다.

이 글에서 다루는 지속적인 통합 시스템은 다음과 같은 시스템 환경에서 검증 받았다. 필시 개발 환경이나 주변 여건에 따라 이러한 조건을 완전히 따라 할 수는 없을 텐데, 막히는 부분이 있으면 http://andromedarabbit.net 에 문의를 주면 아는 바 내에서 최선을 다해 답변할 생각이다.

  • Windows 2003 Server Standard x64 Edition Service Pack 2

    바야흐로 64비트 운영체제의 시대가 본격적으로 열렸다. 4기가바이트 이상의 메모리를 운용할 수 있는 환경을 원한다면 64비트 운영체제는 필수 아이템이다. 아직은 32비트 운영체제를 쓰는 곳이 많지만, 신규 서비스부터는 64비트 운영체제를 채택하는 곳이 점차 늘어날 것이다.

    이 글에선 64비트 WOW 시스템을 적용한 Windows Server x64 Edition을 다룬다. WOW 시스템은 간단히 설명하자면, 하나의 운영체제에서 이전 32비트 애플리케이션과 64비트 애플리케이션을 함께 돌릴 수 있게 해주는 시스템이라 할 수 있다. 기존 32비트 애플리케이션을 그대로 활용하면서 64비트 운영체제가 제공하는 넉넉한 메모리 사용량이나 향상된 성능의 이점을 누리고 싶은 조직이라면 아마도 WOW 시스템을 채택하리라 생각한다.

    하지만 32비트와 64비트를 모두 지원하다 보니 예기치 않은 문제가 튀어나오기도 하는데, 이런 문제점들은 기회가 될 때마다 하나씩 다루어보겠다.

  • Visual Studio 2005 Professional Edition

    마이크로소프트사도 지속적인 통합을 구현할 수 있는 솔루션을 내놓았다. 팀 에디션에는 버전 관리 시스템과 빌드 서버 등이 포함되어 있다. 하지만 라이센스 비용 등을 이유로 팀 에디션보다는 프로페셔널 에디션을 쓰는 조직이 더 많은 걸로 안다. 그러므로 이 글은 애플리케이션 개발을 위해 비주얼 스튜디오 라이센스를 구매했지만, 비용상의 이유로 빌드 서버 기능 등이 빠진 팀 에디션 아래 버전을 쓰고 있는 경우를 가정한다.

  • Microsoft SQL Server 2005

    국내에선 온라인 게임 개발시 MSSQL Server를 많이 쓴다고 들었다. 이 글에선 실제 배포 환경이 아닌 개발 환경을 주로 다루므로 Express Edition과 Developer Edition을 다룬다. 익스프레스 에디션은 비주얼 스튜디오와 함께 배포되는데 무료로 사용할 수 있지만, 기능상의 제약이 많다. 하지만 개발자의 로컬 컴퓨터에서 개인 빌드를 돌릴 때는 매우 유용하다. 디벨로퍼 에디션은 최상위 버전인 엔터프라이즈 에디션과 동일한 기능을 제공하지만, 개발용으로만 한정해서 쓸 수 있다. 회사에 라이센스 계약이 되어 있다면 디벨로퍼 에디션을 쓸 수 있을 것이다.

CruiseControl .NET에 대해

이제 빌드 서버를 구축할 준비가 됐다. 그러고 보니 정작 중요한 빌드 서버를 어떤 걸 쓸지 말하지 않은 듯한데, 결론부터 말하자면 CruiseControl .NET이란 오픈 소스 제품을 쓸 것이다. 굳이 CruiseControl .NET을 쓰는 이유는 무엇일까?

우선 Visual C++ 애플리케이션 개발이란 측면을 생각해야 한다. Visual C++ 소스 코드를 컴파일하려면, 그리고 x64 윈도우 환경에서 애플리케이션을 검증하려면 빌드 서버 역시 윈도우용으로 개발된 것이어야 한다.

그리고 할 수 있다면 구매 비용이 안 드는 오픈 소스 프로젝트를 활용하려고 한다. 상용 서비스를 개발하는 한 사람으로서 상용 제품을 쓰는 것이 싫지는 않다. 하지만 오픈 소스 프로젝트에 충분히 좋은 제품이 있다면 굳이 예산을 쓸 필요는 없을 것이다. 예산을 아껴 다른 개발 지원 도구를 살 수도 있을 테니 아낄 수 있는 곳에선 아끼는 편이 좋다. 그리고 좀더 실용적인 측면에서 보면, 지속적인 통합에 예산을 투입하기 꺼려하는 관리자 밑에서 일하거나, 아직 이러한 시스템이 필요하다는 공감대가 형성되지 않은 팀에서 자신이 앞장서 빌드 시스템을 구축하려는 경우, 다시 말해 돈은 없지만 시간은 있는 경우엔 오픈 소스 제품이 좋다.

CruiseControl .NET은 사실 닷넷 프로젝트를 지원하려는 목적으로 만들어진 제품이다. 지속적인 통합을 주도해온 사람들, 마틴 파울러나 켄트 벡 같은 이들이 자바나 닷넷 또는 루비 같은 환경을 주로 다뤄왔다 보니 안타깝게도 C++ 전용 빌드 서버란 전무하다고 봐도 된다. 그러니 윈도우 플랫폼용으로 개발된 빌드 서버를 활용하는 수밖에 없는데, 그래도 Visual C++라면 같은 마이크로소프트 사가 만들어낸 개발 플랫폼인 닷넷용으로 만들어진 CruiseControl .NET 이 이런 용도론 적합하다 하겠다.

CruiseControl의 장점이라 한다면, 설치하기 쉽고, 웹에서 빌드 결과를 볼 수 있도록 대시보드를 제공하며, 트레이아이콘을 통해 빌드 상황을 실시간으로 확인할 수 있다는 점이겠다. 물론 단점도 있는데, 깔끔한 그래픽 사용자 인터페이스를 통해 설정하는 게 아니라, XML 파일을 손수 수정해줘야 한다는 것이다. 하지만 이러한 불편함은 감수할만한데, CruiseControl .NET 문서 또는 공식 웹사이트에 예제가 충분하기 때문이다.

따라하기 – 소스 코드 내려받기

이제 지속적인 컴파일 환경을 구축해보자. 본의 아니게 설명이 길어지다 보니 모든 걸 다루지는 못하고, 미흡한 부분은 다음 호에서 설명해야 할 듯 하다. 하지만 지면이 부족하다고 대충 설명하고 넘길 수는 없는 노릇이니 감질 맛 나더라도 양해해주길 바란다.

우선 서브버전 버전 관리 저장소에서 컴파일할 소스 코드를 가져와야 할 테니 서브 버전 클라이언트 애플리케이션인 TortoiseSVN (http://tortoisesvn.net/)을 빌드 머신(이 경우엔 Windows Standard Edition x64)에 설치한다. 이 예제에서는 x64용 TortoiseSVN 버전 1.4.6을 설치하지만, 서버 애플리케이션이 아닌 만큼 버전이 조금 차이 나더라도 크게 변할 점은 없을 것이다.

TortoiseSVN은 윈도우용 서브버전 클라이언트인데, 윈도우 셸과 통합되는 데다가 파일 차이점 분석 도구(Diff) 등과 연동되기 때문에 상당히 편리하다. 오픈 소스라는 것도 매력적이며, 한글 메뉴까지 지원한다.

SVN - Checkout
[그림 1] TortoiseSVN을 사용해 소스 코드 내려 받기

TortoiseSVN을 설치하면 운영체제를 다시 부팅하라는 메시지가 뜬다. 꼭 다시 부팅하지 않아도 체크인이나 체크인 같은 주력 기능은 작동하지만, 윈도우 셸 통합 기능을 완전히 사용하려면 다시 부팅하는 편이 좋다. 다시 부팅을 했으면, 소스 코드를 내려 받을 폴더로 가서 마우스 오른쪽 버튼을 누른 후 SVN 체크아웃(SVN Checkout) 메뉴를 선택한다. 이때 [그림 1]을 주목하길 바란다. 그림은 간단하지만, 눈 여겨 볼 것은 많다. 우선 저장소의 기본 구조를 다시 상기해보자.

SVN - Repository Browser
[그림 2] 기본적인 저장소 구조
[그림 2]에서 알 수 있듯 프로젝트 디렉토리는 크게 branches, tags, trunk 디렉토리로 나뉘는데, 이때 실제 빌드에 쓰는 디렉토리는 trunk이다. Trunk는 현재 왕성하게 개발 중인 프로젝트가 들어간다. 물론 중간에 이런저런 이유로 분기된 프로젝트를 지속적인 컴파일 대상으로 삼을 수는 있지만, 지속적인 통합 커뮤니티에서는 trunk를 빌드 대상으로 삼는 걸 원칙으로 생각한다. 분기됐던 프로젝트는 나중에 trunk와 통합을 하던가, 아니면 아예 새로운 프로젝트로 빼내 지속적으로 컴파일하는 편이 좋다.

다시 [그림 1]으로 돌아가보자. 여기서는 Trunk 폴더뿐만 아니라 프로젝트 폴더 전체를 체크아웃한다. 원칙대로라면 Trunk 폴더만 내려 받으면 되지만, 어쩌다 branch나 tag 폴더에 들어있는 소프트웨어 자산을 써야 할 수도 있기 때문이다. 어차피 나중에 CruiseControl .NET 설정 파일에서 trunk 폴더만 업데이트하라는 식으로 조정할 수 있기 때문에 성능 하락의 단점은 겪지 않는다. 굳이 불편한 점을 꼽자면 처음 체크아웃할 때 시간을 제법 잡아먹을 수 있다는 것뿐이다.

Checkout directory(체크아웃 디렉토리)라는 부분을 보면, 로컬 디렉토리 이름이 원래 프로젝트 이름보다 길다. “Myproject-x64-release”라는 이름에서 바로 알 수 있듯, 플랫폼(Platform)과 설정(Configuration) 값을 프로젝트 이름 뒤에 붙이다. 만약 32비트 윈도우에서 개발하고, 64비트 윈도우에 배포하는 애플리케이션이라면 Win32-Debug, Win32-Release, x64-Debug, x64-Release 등 최소한 네 개의 로컬 복사본을 갖게 된다. 이 폴더에서는 각각의 이름에 맞는 빌드를 수행한다. 물론 한 디렉토리만 만들어서 네 가지 설정 값을 번갈아 가며 빌드할 수도 있다. 하지만 이렇게 하면 멀티 프로세서를 활용한 동시 빌드는 생각하기 힘들어지며, 설사 선입선출 방식으로 빌드를 하더라도 이전 빌드 때 만들어진 산출물 때문에 미묘한 문제가 발생할 수도 있다. 차라리 각 설정 값에 맞춰 디렉토리를 나누는 편이 다루기 쉽다.

목록 2. 소스 코드를 내려 받을 때의 원칙

  • 우선 Win32|DEBUG 용 디렉토리만 만든다.

  • 이때 프로젝트 전체를 내려 받는다. 서버 팀이라고 서버 디렉토리만 내려 받는다면, 나중에 곤란해질 수 있다. 서버 애플리케이션이 클라이언트 컴포넌트를 일부 가져와 쓰거나 서버와 클라이언트가 라이브러리를 공유하는 경우가 있을 수 있다.

  • 다 내려 받는 것도 나쁜 점이 있다. 애플리케이션과 전혀 상관 없는 자산, 예를 들면 기획 문서 하나가 바뀌어도 빌드가 시동될 수 있다.

  • 제일 좋은 방법은 빌드할 때 필요한 소프트웨어 자산과 그렇지 않은 기타 자산으로 나누고, 소프트웨어 자산을 포함한 디렉토리만 내려 받는 것이다.

따라하기 – 윈도우용 서브버전 바이너리 설치하기

서브버전을 이미 갖춘 상태라 가정하는데 무엇 때문에 또 빌드 서버에 서브버전을 설치하느냐? 이런 의문이 들 법하지만 여기선 별도의 버전 관리 저장소를 돌리려는 것은 아니다. CruiseControl .NET과 서브버전을 연동하려면 윈도우용 서브버전 바이너리가 필요하기 때문에 설치할 뿐이다.

서브버전은 프로젝트 홈페이지(http://subversion.tigris.org/) 뿐만 아니라 CollabNet, Inc(http://www.collab.net/)나 VisualSVN(http://www.visualsvn.com/) 홈페이지에서 다운로드 받을 수 있다. 조금씩 성격이 다른데 여기서는 프로젝트 홈페이지에서 최신 버전(1.4.5)을 다운로드 받는다. VisualSVN 등이 제공하는 부가 기능은 서브버전 서버를 돌릴 때는 아주 유용하지만, 여기서는 단순히 서브버전 클라이언트 기능만이 필요하기 때문에 가장 간단한 것이 가장 유용한 것이 된다.

x64 바이너리를 제공하지 않기 때문에 Windows 2003 Server x64 Edition에 서브버전을 설치하면 “C:\Program Files (x86)\Subversion”이 기본 경로가 된다. x64 WOW 시스템에선 32비트 바이너리는 “Program Files (x86)”에 설치되며 64비트용 바이너리가 “Program Files”에 설치되기 때문이다.

따라하기 – IIS 웹 서버 및 ASP.NET 설치하기

CruiseControl.NET은 크게 두 구성요소로 나뉘는데, 하나는 빌드 스케줄러인 서버이고, 다른 하나는 빌드 결과를 보여주는 웹 대시보드이다. CruiseControl.NET 대시보드는 선택사항일 뿐이라서 꼭 설치해야 하는 건 아니지만,

  1. [제어판 – 프로그램 추가/제거 – Windows 구성 요소 추가/제거 – Application Server – Internet Information Services]
  2. [IIS 관리자 – 웹 서비스 확장(Web Service Extensions)]에서 ASP.NET 활성화시킨다. [그림 3]을 참고하면 된다.

  3. ASP.NET 2.0을 설치한다.
    C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\aspnet_regiis.exe –I

  4. IIS 관리자에서 ‘웹 사이트’나 원하는 웹 사이트 구성(예, ‘Default Web Site’)을 선택하고 설정 메뉴에 들어간다. ASP.NET 버전 선택해준다. 여기선 2.0을 골랐다. [그림 4]를 참고하면 된다.

ASP.NET 활성화하기 - 1
[그림 3] ASP.NET 활성화하기 – 1
ASP.NET 활성화하기 - 2
[그림 4] ASP.NET 활성화하기 – 2

목록 3. 트러블 슈팅

CruiseControl.NET 대시보드(예, http://localhost/ccnet/1)에 접속했는데 오류 메시지가 뜨는 경우가 있다.

If IIS was installed after the .NET framework, you will need to either run aspnet_regiis.exe or open IIS manager, right-click the ccnet website, select properties and then the ASP.NET tab. Make sure the ASP.NET version has something displayed in the dropdown (eg. .NET 2.0, 2.0.50727) and click OK.

이런 오류 메시지가 뜨는 건 IIS 웹 서버와 ASP.NET을 완전히 설치하지 않고 CruiseControl.NET부터 설치했기 때문이다.

부록. 지속적인 통합 팁 – SVN Notifier

두 사람이 한 소스 코드를 건드리다 보니, 충돌이 일어나는 일이 잦았다. 이런 문제를 해결하려면 참가자 모두가 자주 커밋하고 자주 업데이트하는 수밖에 없다. 자주 커밋하는 건 각자 노력에 달린 문제이고 이를 도와줄 기술적 보완 장치는 없다. 하지만 자주 업데이트하는 것이라면 쓸만한 도구가 있다.

SVN Notifier(http://svnnotifier.tigris.org/)가 하는 일은 아주 간단하다. 소스 코드가 업데이트되었는지 확인하고 사용자에게 알려주는 것이다. 간단한 기능이지만, 의사소통에 소모되는 비용을 자동화를 통해 상당히 해소시킬 수 있다.

SVN Notifier 스크린샷

SVN Notifier 스크린샷 1

SVN Notifier 스크린샷 2

이 도구를 설치하고 나서 컴퓨터의 반응 속도가 떨어지는 경험을 할 수 있는데, SVN Notifier가 버전 관리 저장소에 새로운 변경 사항이 없는지 지나치게 자주 확인하기 때문에 벌어지는 문제다. SVN Notifier 설치 시 업데이트 확인 주기가 매우 짧게 설정되어 있는데, 이 값만 적당히(예, 5분 내지 10분 이내) 바꿔주면 간단히 해결된다.

끝마치는 말

지속적인 통합에 관한 글을 연재하면서 항상 느끼는 것이지만, 매번 할 말을 다 못하고 끝나는 것 같아 아쉽다. 원칙이나 개요가 아닌 실제적인 정보를 제공하려다 보니 예제가 많아지고, 트러블 슈팅 같은 예외 사항에 관한 언급도 해야 하니 생각보다 더디다. 하지만 달리 생각하면 아무리 지면이 많아도 항상 부족할지도 모르겠다. 느긋한 마음으로 지켜봐 주길 바란다.

최 재훈

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