C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[527] 지겨운 컴파일 시간을 단축하자.
김태선 [jsdkts] 7909 읽음    2005-12-02 16:50
컴파일 시간 문제가 심각한 이유는 C++은 초고속 컴파일러의 선두주자인 델파이가 아니며,
언어를 만들 당시 컴파일 시간을 심각하게 고려한 현대적 디자인의 산물이 아니라는데 있습니다.
처음 C++컴파일러가 만들어질 당시 C 언어에 대한 프리프로세서로 작동했다는 사실은,
수백만 라인을 가뿐히 오가는 현대적 플밍 환경에서 본다면 그야말로 경악할 일입니다.
윈도 시대가 열린 이후 C++컴파일러가 컴파일해야 하는 소스라인수는 수백만에서 수천만라인으로
늘어났음에도 불구하고, C++은 언어의 구조적 제약사항 때문에 컴파일 시간을 단축할 방법을 찾지 못하고 있는 실정입니다.

이 문제의 최선의 해결 방법은 다음 2가지로 요약할 수 있습니다.
첫째는 미리 컴파일된 헤더를 통일 시키는 것이고,
둘째는 소스 파일간의 의존관계를 개선하는 것입니다.


우선 컴파일 시간에 가장 큰 영향을 주는 것은 수백만라인에 달하는 컴파일러가 제공하는 헤더파일입니다.
이에 대한 처리 방법은 이곳 팁란의 유광희님의 팁을 보시면 될 것입니다.
아주 간단히 요약하자면,
제공되는 헤더중에서 사용하는 것은 PreHeader.h 파일에 한꺼번에 모아 놓고
#pragma hdrstop 지시자로 프리컴파일링이 되게 해 놓으며,
프로젝트에서 쓰이는 모든 cpp 소스 파일에는 프리컴파일 헤더  #include "PreHeader.h" 를 하고
그 밑에 프로젝트에서 만든 헤더파일을 include 하는 방법을 쓰면 됩니다.
이때 프로젝트의 헤더도 하나로 모을 것인지 아닌지는 각자가 판단해야 합니다.

사실 C++ 언어에 있어 컴파일 시간의 심각성은, VC++ 위자드가 생성하는 기본 프로젝트 파일들의 구조를 보아도
알수 있습니다.
모든 헤더 중에 프리컴파일이 필요한 것은 거의 강제적으로 StdAfx.h 에 모아 놓게 했는데,
이는 곧 방금 설명드린 PreHeader.h 에 해당하는 것으로 전적으로 컴파일 시간 때문에 취한 방법입니다.

두번째, 소스파일의 의존성 문제입니다.
특히 빌더의 문제를 말해 보겠습니다.
보통 메인 폼 파일에는 상당한 갯수의 컴포넌트가 놓여지고 따라서 코딩이 많아지는데
이렇게 메인 폼에 코딩을 몰아 넣는 것은 매우 좋지 않은 습관일 뿐만 아니라,
View(화면)와 Document(구현)를 분리하지 않고 폼 클래스에서 모든 것을 해결하려는 것은
프로그램이 커지면 커질수록, 복잡해지면 복잡해질수록 문제를 가중시키는 좋지 않은 방법입니다.

사실 폼 소스 파일에는 폼과 관련된 아주 간단한 함수나 처리 외에는 두는 것이 좋지 않습니다.
즉 화면에 실제로 보여지는 부분 외에는 폼 파일에 코딩하지 말아야 합니다.
실제 데이타를 다루는 구현부분은 따로 유닛을 빼서 코딩하는 것이 좋은데,
이는 그간 수 많은 플머들의 작업의 산물로서 권고되는 사항입니다.

폼이 늘어가고 다른 폼을 참조하는 클래스가 많아 질수록 의존성은 복잡하게 얽히게 됩니다.
메인 폼과 연관 기능을 사용하는 폼이 있다면 거의 예외없이 메인폼의 헤더파일을 inlcude 하게 되고
메인 폼의 무언가 조그만 변화도 관련 파일을 죄다 재 컴파일 하는 사태로 번지면
그때부터 컴파일 시간 악몽에 시달리게 됩니다.
프로젝트가 작을때는 괜잖습니다.
cpp 소스 파일이 수십개로 늘어나면,  프리컴파일링을 적절하게 적용했는데도 불구하고
컴파일 시간이 1분을 넘기게 되는 상황이 일어나면...
구현에 신경써야할 머리가 엉뚱한 감정으로 인해 흐려지게 됩니다..

델파이 같으면 의존성 문제가 심각하지 않으며 컴파일 시간이 문제시 되지 않으나,
C++은 조그만것 하나 고치고 컴파일 시간이 수십초에서 수분이 걸리니, 이건 재앙이나 다름 없습니다.
그러므로, 프로그램의 구조가 OOP 지향적이고 화면처리와 구현부를 분리하는 방식외에
컴파일 시간 단축을 위한 구조를 별도로 가지는 것 또한 개발의 효율성을 위해 매우 중요합니다.

위의 메인폼의 예를 계속 말해 보자면,
메인폼의 함수를 다른 수십개의 하위 폼이나 다른 모듈에서 참조할때
메인폼의 헤더파일에 조그만 변화로 수십개의 다른 소스파일을 통채로 컴파일되는 사태를 막으려면,
너무나 당연한 이야기이지만 메인폼의 헤더파일을 include 하지 않으면 됩니다.
또한 메인 폼의 함수를 호출하지 않으면 됩니다.

그러면 어떻게 프로그램 하지 ?
방법은 컴파일 시간에 지대한 지장을 주는 메인폼을 직접 include 및 호출 하지 말고
중간에 인터페이스용 유닛 파일 만들어 간접적으로 부르는 방법을 사용하면 됩니다.

가령
TFormMain 의 메인 폼파일에 대해 인터페이스용  CMainInterface 클래스 파일을 만들어
이 클래스를 통해 메인의 내용에 접근하면 됩니다.
그러면 빈번한 메인 폼의 수정이 있어도, 재 컴파일 되는 것은 메인폼과 CMainInterface 클래스가 있는
소스 파일에 한정됩니다.
그리고 인터페이스용 CMainInterface 클래스는 특성상 그다지 변하지 않으므로, 수백번 컴파일을
반복하면 할수록 전체적인 컴파일 시간을 무척 아껴주게 됩니다.


이건 제가 실무를 하면서 소스가 너무 많아지고 커지면서 그것을 극복하는 방법으로 썼던 것인데...
프로젝트가 너무 커져 컴파일 시간에 부담될 때 사용해 보시기 바랍니다.
조그만것 하나 고치고 1분이상 컴파일하는 것을 그대로 지켜보는 분은 아마 인격 수양이 상당하신 분인듯... ^^;

예제도 없이 말로만  설명해서 지송...
김태선 [jsdkts]   2005-12-04 11:17 X
#pragma once
VC++에 있는 이 지시자는 해당 헤더파일이 단 한번만 include 되어 컴파일되도록 해줍니다.
보통 전통적인 C++에서는
헤더가 한번만 포함되게 하기 위해
#ifndef Unit1H
#define Unit1H
  // 헤더 내용
#endif
식으로 코딩하는데,
#pragma once 지시자는 보다 빨리 컴파일 할수 있도록 하기 때문에
BDS 2006에서는 추가되었으면 하는 기대를 했었는데 ...
BDS 2006을 써볼 기회가 생기면 실험을 해봐야 겠군요.

+ -

관련 글 리스트
527 지겨운 컴파일 시간을 단축하자. 김태선 7909 2005/12/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.