빌드는 한 방에 이루어져야 한다

대부분의 프로젝트는 달랑 한 개의 결과물 – 배포할 프로그램 바이너리일지, 웹 페이지와 디비 등등등일지, 묶여있는 게임 팩키지 일지는 프로젝트마다 다르겠지만 – 만을 내놓는 경우는 없다.

예를 들어서 문자열을 처리하는 라이브러리를 만든다고 하자.

  • blah, blah, blah … 하는 기능을 지원하고(그렇다 치자)
  • utf-8 기반 문자열 버젼과 UCS2기반 문자열 버젼을 제공한다
  • static library (.a / .lib)와 shared library (.so / .dll)를 제공한다
  • Debug 정보를 포함한 버젼과 그렇지 않은 버젼을 제공한다

이제 가능한 조합은 총, 2 × 2 × 2 = 8 가지이다. (예: utf-8 based, static, debug; utf-8 based, shared, release; …. ) 이걸 손으로 일일이 만든다는 것은 사실 뻘짓이다. 출시 직전에 이런 일을 해야한다면 실수할 가능성도 생기고 – 많은 프로그래밍 스타일 책에서 지적하는 내용이다 – 귀찮기도 귀찮다. 그리고 이 귀차니즘이 프로그램의 질을 낮추는 원인 중 하나라고 생각한다.

On *nix system – Solaris, BSD-variant, linux, OS X 등등에서는, 간단히 makefile의 매크로(상수 정의?)를 사용하면 된다. 공통된 설정을 하나의 변수로 유지하고 각 설정을 “$(공통설정) $(개별설정)” 하는 식으로 유지하면 된다 – 정보를 여기저기 중복시키는 것은 죄악이다. 실수를 복사하지는 말자 ;)

On Windows system – 내가 써본 Win32 개발 환경이 따로 있는게 아니라 Visual Studio 씨리즈 – VS 6.0, .net 2003, .net 2005 – 뿐인지라 간단히 설명하자면, VS에서 빌드하는 것은 간단한 명령어로 되며 – devenv SolutionFile.sln /build $(ConfiguraionName) 로 빌드된다 – ,각 설정은 IDE의 configuration manager나 project_name.vcproj 파일을 직접 수정해야 한다는 것이다. 문제는 configuratoin이 각 설정(기본적으로 debug/release가 있으면 추가/수정할 수 있는 구조다) 별로 완전히 별도로 관리돤다라는 점이다. 그래서 각각의 설정이 맞지 않는지 세심히 관찰할 필요가 있다.

물론 VS에 있는 컴파일러/빌더 등을 직접 불러서 실행시킬 수도 있지만 그런 경우엔 IDE 설정과 스크립트 기반 빌드가 완전히 따로놀게되는 문제가 있다 – 사실 스크립트 기반 빌드 -> IDE설정 반영하기 같은 스크립트를 만들 수 있을것 같긴 하다.

내 짧은 경험으로 생각하기에 간단히 설정할 수 있는 빌드는 이런 툴들을 이용하는 수준이다. 물론 프로그램 바이너리가 만들어졌다고 빌드가 끝나는 것은 아니다. 프로그램을 만들기 전에 필요한 것들을 생성하는 부분도 있어야 할 것이고 완성된 프로그램 바이너리, 각종 리소스 등을 적절히 배치하는 것도 필요하다.

그러나 이런 부분들은 미리 정의한 간단한 리소스 배치 설정 + 해석하는 스크립트(batch건 shell script이건 python script이건간에)면 된다 – 필자는 간단한 xml 문법으로 정의한 리소스 배치 + python을 사용하고 있다)

위의 사항들을 이용해서 바이너리 빌드 + 리소스 배치 스크립트를 만들었으면 한 방에 빌드를 만들어낼 수 있을 것이다 – 사실 처음 설정하기가 귀찮지 그 다음부터는 아주 점진적인 변화만 필요할 것이다.

한 방에 이루어지는 빌드를 지지하는 내용 – 더 읽을거리들

  • 실용주의 프로그래머 (The Programatic Programmer) – 주제 42: 유비쿼터스 자동화
  • C++코딩의 정석 (C++ Coding Standards: 101 Rules, Guidelines, and Best Practices) – 주제 2. 자동화된 빌드 시스템을 이용하라

…사실 이 글을 쓰는 이유는 오늘 출근해보니 전체 빌드가 깨져 있었기 때문에. 프로젝트에서 사용하는 내부 라이브러리의 .vcproj 파일 내용이

  • 하나의 설정(총 4개의 설정이 있는데 그 중 1개)만 변경된 부분이 있었고 – 반영되지 않은 3개의 설정이 깨졌다
  • (테스트를 위해서라고 추정되지만) 실행 바이너리 코드 중 일부에 virtual function 정의 부분이 주석처리 되어 있어서 해당 바이너리의 모든 빌드가 깨졌다
  • 전체 빌드 스크립트에 해당 변경 내용이 반영되어 있지 않아서 nigthly build가 깨져 있었다.

o <-<