LazarusCompleteGuide:1.0
1장 라자루스(Lazarus)의 아키텍처
라자루스(Lazarus)는 오브젝트 파스칼 (Object Pascal) 언어를 지원하는 통합 개발 환경(IDE)이다. 프리 파스칼 컴파일러(Free Pascal Compiler)는 라자루스를 위한 백엔드(backend)를 제공한다.
이러한 백엔드 엔진과 통합 개발 환경의 결의 예는 C++ 의 비주얼 스튜디오(Visual Studio) 또는 볼랜드의 델파이(Borland Delphi)를 들 수 있겠다. 이러한 결합은 효율적이고 고도로 최적화된 네이티브 소스 코드(native source code)를 생성한다. 반면 Java와 C# 개발 환경은 바이트코드(bytecode)를 생성하는데, 이는 런타임 환경에서 해석되거나 JIT 컴파일러에 의해 저조하게 최적화된 코드로 변환되어야 한다.
라자루스 IDE의 강점으로는, 그래픽 프로그램의 개발을 매우 단순화시키고 용이하게 만드는 RAD 성능을 들 수 있겠다. 이러한 기능의 대부분은 델파이의 것과 유사하다. 하지만 델파이의 경우 델파이 컴파일러(Delphi compiler)를 기반으로 하는 반면 라자루스는 프리 파스칼 컴파일러(Free Pascal Compiler; FPC)를 기반으로 하며 델파이 2007과 대개 호환이 가능하다. 또한 라자루스는 Windows뿐만 아니라 Linux, MacOS X, BSD 등 기타 플랫폼에서도 실행된다. 라자루스가 전적으로 라자루스에서 쓰이듯 프리 파스칼 컴파일러도 파스칼에서 쓰인다. FPC에는 다른 파스칼 변형 언어(dialect)의 확장도 포함하므로 기존의 소스 코드를 복사하기가 수월하다. 플랫폼 독립성에 중점을 둔 FPC는 이동이 불가능한 않은 신호를 감지하여 경고를 생성한다.
라자루스의 그래픽 컴포넌트 라이브러리는 라자루스 컴포넌트 라이브러리(LCL)이라 불린다. 라이브러리의 유닛(unit), 클래스(class), 식별자(identifier) 중 다수는 델파이와 동일한 이름을 가지며 동일한 방식으로 작동하기 때문에 델파이 코드를 라자루스로 직접 복사할 수 있다. 라자루스를 델파이의 복제판으로 간주하기보다는 에뮬레이터(emulator)가 필요 없이 네이티브 애플리케이션을 사용해 플랫폼 독립성을 지원한다는 점에서 델파이 개념의 확장판으로 보면 되겠다. 단, 델파이 컴포넌트 라이브러리(VCL)와의 완전 호환성이 불가하다는 점은 감수해야 한다. LCL는 네이티브 컴포넌트이다. 모든 플랫폼에는 LCL 기반의 애플리케이션들이 다른네이티브 애플리케이션과 동일한 모습으로, 그리고 동일한 방법으로 사용된다. LCL에서도 Windows용 WinAPI, Linux/BSD용 Gtk2, MacOS X용 Carbon/Cocoa와 같이 네이티브 위젯 셋(widget-set)의 사용을 통해 이루어진다.
라자루스와 델파이의 비교 시 주요 차이점으로는, 완전한 오픈 소스이고, 현재 15개 이상의 플랫폼에서 실행되고 있으며, 상업적 사용자들에게도 무료로 배포되며 유연한 라이센스 정책을 기반으로 한다는 점을 들 수 있다. 오픈 소스 공동체의 노력 덕분에 많은 델파이 라이브러리가 라자루스로 복사되어 기타 플랫폼들로 확장되었다. 또한 라자루스에서만 이용 가능한 새로운 라이브러리도 개발되어 왔다. 수많은 포럼, 메일링 목록 및 웹사이트에서 신속하고 직접적인 도움을 제공한다.
프리 파스칼 컴파일러와 이를 수반되는 라이브러리는 라자루스를 위한 탄탄한 기반을 구성한다. FPC와 라자루스가 매우 밀접하게 관련되어 있지만 둘은 서로 구분된 프로젝트이다. 프리 파스칼의 첫 버전은 1993년에 출현한 반면 라자루스는 1999년부터 시작되었다. 프리 파스칼은 Windows 32, Windows 64, WinCE, Linux, FreeBSD, MacOS X/Darwin, DOS, OS/2, Netware (libc와 classic), MorphOS용 32-, 64-비트 컴파일러이며 Intel x86, AMD64/x86_64, PowerPC, PowerPC64, Sparc, ARM 아키텍처에서 실행된다. 컴파일러는 델파이와 마찬가지로 매우 빠르긴 하지만 FPC의 경우 확장성에 중점을 두어 하나 이상의 플랫폼에 최적화되기 때문에 델파이만큼 빠르지는 않다. 규모나 속도와 관련해, 윈도우에서 컴파일된 코드는 델파이에 의해 생성된 코드와 비슷하며 (FPC가 나은 경우도 있고 델파이가 나은 경우도 있음) Linux나 MacOS X에서는 GNU C/C++ 컴파일러에 의해 생성된 코드와 비슷하다.
라자루스는 최근 .NET 지원이 부족하고 델파이의 .bpl 라이브러리에 해당하는 패키지가 없다. 하지만 일반 라이브러리를 컴파일하여 모든 플랫폼에 결합할 수 있다.
네이티브 그래픽 애플리케이션, 윈도우 서비스, 리눅스 데몬, 명령 행 도구, 라이브러리, 플러그인, 데이터베이스 애플리케이션, 웹 애플리케이션, 그 외에도 수많은 기능을 라자루스로 프로그래밍할 수 있다. IDE의 함수 범위는 설계 시 필요한 패키지(design-time package)로 확장 가능하다.
라자루스는 리눅스 시스템에 윈도우 프로그램을 생성하거나 윈도우 시스템에 WinCE 애플리케이션을 생성하는 등 크로스 컴파일이 가능하다. 이러한 상황에서는 코드 찾기와 코드 완성이 지능적으로 운용된다. 재시작할 필요 없이 IDE에서 구성을 변경할 수 있다. 프리 파스칼 컴파일러는 조건부 컴파일을 지원하므로 운영체제, CPU 타입 혹은 기타 기준에 따라 코드를 선택적으로 생성할 수 있도록 해준다.
IDE 환경은 모든 검색 경로(search path)에서 매크로를 허용하므로, 운영체제에 따라 유닛이나 include 파일을 선택할 수 있음을 의미한다. 특히 2개 이상의 플랫폼이 관여된 경우 명확하고 광범위한 구조를 생산한다. LCL 자체가 이러한 개념을 기반으로 하고 있다. 프로그래머에겐 플랫폼 독립적 컴포넌트 집합으로 보이지만 검색 경로에서 매크로는 특정 운영 체제에 맞는 모듈을 네이티브 위젯 셋으로 접근하도록 해준다.
라자루스 패키지 개념은 유닛들을 자체의 컴파일러 구성을 가진 거대한 개체로 통합할 수 있도록 허용한다. 이로 인해 여러 경로와 다양한 운영체제를 가진 컴퓨터들로 코드를 쉽게 복사할 수 있게 된다. 이러한 과정에 필요한 것은 파일의 복사와 패키지의 개방이다. 경로를 수정하거나 스위치를 구성할 필요가 없기 때문에 패키지 업데이트가 상당히 간소화된다.
LCL의 비주얼 컴포넌트는 이벤트를 기반으로 한다. 즉, 전체 애플리케이션을 순차적으로 쓸 필요가 없다는 의미다. 대신 프로그래머가 이벤트에 응답하는 메소드(method)를 개발할 수 있다. LCL 컴포넌트의 상태는 전적으로 속성(property)에 의해 결정된다. 다시 말해, 가상으로 원하는 순서대로 수정이 가능하며, IDE에 폼(form)을 간편하게 그래픽으로 표시할 수 있다. 원하는 함수가 누락된 경우 어떠한 컴포넌트 클래스든 사용자 정의 클래스의 기반으로서 사용이 가능하고 IDE에서 그래픽으로 사용된다. 사용자가 자신만의 컴포넌트 라이브러리를 생성할 수도 있다.
IDE를 통해 윈도우를 그래픽으로 편집도 가능하다. 각 유닛은 기껏해야 하나의 창을 가질 수 있다. 윈도우는 (상속된) 다른 창을 기반으로 하거나 하위 창으로 (프레임) 중첩될 수 있다. 단, 그 속성은 .lfm 파일에 저장된다. 물론 코드를 이용해서 창을 생성하는 방법도 있다. 여기서는 핵심은 폼 에디터(Form Editor)가 소스 코드 에디터(Source Code Editor)와 밀접하게 연관되어 있다는 점이 핵심이다.
새 컴포넌트가 폼 위에 위치하면 소스 코드에 새 변수가 생성되며, OnClick 버튼 이벤트가 설정되면 소스 코드에 새 메소드가 생성된다. 프로그램은 즉시 컴파일 및 실행 가능하다; 그 외에는 어떤 것도 불필요하다. 프로그래밍 언어는 단순한 문법으로 되어 있어야 하고, 컴파일용 파일 결합을 위한 메커니즘을 가져야 한다. 이는 FPC에서 매우 간편하게 구현된다.
C 또는 C++와 같은 언어에서 복수 파일의 컴파일은 주로 make 파일이 명시한다. 하지만 make 파일의 생성 및 유지가 쉽지 않기 때문에 C 사용자가 make 파일을 생성하도록 도와주는 도구가 무수하게 많다.
make 파일이 불필요하다는 사실은 FPC 사용자에겐 좋은 소식이다. 더 좋은 소식은 원한다면 make 파일을 사용할 수도 있다는 점이다. 하지만 이보다 더 완벽한 것은, make 파일을 자동으로 생성하는 도구가 있다는 점이다.
makefile 작업의 목적은 컴파일 과정을 단순화 및 표준화시키는 데 있다. 이는 수정된 파일이 자동적으로 올바른 순서에 따라 컴파일되도록 보장하며, 적절한 컴파일러 파라미터를 명시해준다. 프리 파스칼 컴파일러는 수정된 모든 유닛을 자동으로 컴파일하고, makefile보다 훨씬 빠른 속도로 작업하며, 검사 합계(checksum)로 작업한다. 이러한 검사 합계는 특히 파일이 네트워크 디렉터리에 위치한 경우 중요한데, 클라이언트와 서버 시스템에 시간 참조가 다를 가능성이 있기 때문이다. 수많은 C 프로그래머들이 파일의 타임스탬프(time-stamp)에 문제가 생겼다는 경고에 익숙할 것이다. FPC에서는 이와 관련해 문제가 상대적으로 적기 때문에 프로그래머는 FPC에 단순히 메인 파일을 전달하고 컴파일러가 스스로 모든 보조 파일을 찾도록 하면 된다.
아래의 예를 보자.
fpc program1.pas
위와 같은 경우는 program1이 필요로 하는 모든 파일을 올바르게 자동으로 호출한다. 여기서 다른 프로세서 아키텍처로의 크로스 컴파일을 위해 두 번째 컴파일러가 필요하다. 두 번째 컴파일러는 물론 FPC에 해당하겠지만 목표 아키텍처용 코드를 컴파일할 수 있는 FPC여야 한다.
컴파일러는 소스 파일을 읽음으로써 시작하며, uses 절을 만나면 자동으로 해당하는 유닛을 검색한다. 사전 컴파일된 (Precompiled) .ppu 파일을 찾게 되면 이를 사용한다.
소스 파일만 찾게 되는 경우 (또는 소스 파일이 .ppu 파일보다 새로운 경우) 소스 파일을 컴파일한다. 이러한 파일이 다른 유닛을 필요로 하는 경우 해당하는 다른 유닛이 재귀적으로 컴파일된다.
위의 과정은 모두 빠르게 진행된다 – 컴파일 속도는 보통 10,000 – 100,000 행 / 초이다. 컴파일러는 명시된 파일을 찾고 자동적으로 모든 수정된 파일을 올바른 순서로 컴파일한다.
C 컴파일러와 반대로 컴파일러 변수 대부분이 이해하기가 쉽다. 설정 대다수가 소스 코드에 위치한다는 사실이 부분적인 이유이고, 또 다른 이유는 컴파일러와 시스템 라이브러리가 모든 플랫폼 상의 동일한 소스로부터 발생하기 때문이다.
그 결과, 컴파일러 명령 행 파라미터는 대부분 검색 경로를 명시하는 것으로 한정되며, 시스템 파라미터를 수집하는 데 많이 사용되는 ./configure 는 불필요하다. 이는 라자루스의 좌우명인 ‘한 번 쓰고 어디서든 컴파일하자 (Write Once, Compile Anywhere)’와 일치한다. 예를 들어, C 에서는 configure로 호출 시 무엇보다 int 변수 크기를 검사한다. 프리 파스칼의 경우 타입 크기를 코드에서 직접 알 수 있다.
프리 파스칼에서는 어떤 libc 버전을 사용할 것인지 결정하는 검사가 불필요한데 이는 런타임 라이브러리에서 경험상 가장 드물게 수정되는 코어(core) 함수만을 사용하기 때문이다. 이러한 이유로 파스칼 프로그램은 그와 비슷한 C 프로그램과 동일한 방식으로 다수의 배포판에서 실행된다. 파스칼이 C 헤더 파일을 직접 필요로 하지 않는 것처럼 어떠한 라이브러리를 사용할 것인지 결정하는 구체적인 검사는 불필요하다.
라자루스는 package나 project를 포함시키기 위해 유닛 개념을 확장시킨다.
패키지는 어떻게 컴파일할 것이며 이에 어떠한 패키지가 필요한지에 관한 정보가 담긴 파일 집합이다. 패키지는 라이브러리가 될 수도 있고 단순히 광범위한 프로젝트 내 논리 개체가 될 수도 있다. 라자루스의 프로젝트 또한 파일의 집합이긴 하나 프로그램을 빌딩하는 데 필요한 추가 정보를 포함한다. 또한 각 프로젝트에서 IDE는 에디터에서 열린 파일명, 디버깅 정보, 그 외 데이터를 저장한다. 라자루스 패키지 또는 프로젝트는 향상된 makefile로 생각하면 되겠다. 이는 makefile을 사용하지 않고 더 거대하고 상호 독립적인 라이브러리를 컴파일할 수 있게 해준다. 명령 행 프로그램 lazbuild가 이를 담당한다.
예를 들자면, 프로젝트에는 항시 모든 메타데이터를 보유하는 projectname.lpi가 있다. 또한, .lpi 파일은 XML 파일로서 파일 내 모든 데이터는 IDE를 이용해 쉽게 구성이 가능하므로 수동 편집이 불필요하다 (수 백 개의 파일명을 한 번에 바꾸지 않는 이상). 또한 사용자에 의해 이름과 확장자가 할당된 메인 파일(main file)도 항시 존재한다. 기본적으로는 IDE가 메인 파일에 project1.lpr 명을 할당한다.
이상으로 라자루스가 어떻게 파일을 결합하여 패키지 및 프로젝트라 불리는 커다란 개체를 형성하는지 간략하게 살펴보았다. 독립성 원칙 덕택에 다양한 프로그래머들과 외부 공급자들의 패키지들을 하나로 묶어 처리하는 것이 가능하다. 다음 절에서는 라자루스 소스 코드 에디터(Lazarus Source Code Editor)가 프로그래밍하는 사용자들이 이러한 이점을 어떻게 활용하도록 돕는지를 설명하고자 한다.