CRuby 빌드 시스템의 현재와 미래

[EN] The Evolution of the CRuby Build System / Yuta Saito @kateinoigakukun

작성자
RubyKaigi
발행일
2025년 05월 27일

핵심 요약

  • 1 CRuby 빌드 시스템은 오랜 역사와 다양한 환경 지원으로 복잡성이 증가했으며, 특히 `configure` 시간과 `make` 병렬 처리 효율성 저하 문제가 심화되고 있습니다.
  • 2 현재 빌드 시스템은 `autoconf` 기반의 `configure` 스크립트, 다단계 `make` 구현, Base Ruby 및 Mini Ruby를 활용한 코드 생성 등 여러 복잡한 요소를 포함하고 있습니다.
  • 3 발표자는 Ruby 기반의 새로운 빌드 시스템을 제안하며, 빌드 로직의 명확화, 성능 최적화(병렬 처리), 그리고 최종 사용자를 위한 기존 `configure && make` 경험 유지를 목표로 합니다.

도입

본 발표는 CRuby 빌드 시스템의 역사, 현재 상태, 직면한 도전 과제 및 잠재적인 미래 방향을 탐구합니다. 발표자 UTA는 Goodnotes의 소프트웨어 엔지니어이자 CRuby 및 Swift 커미터로서, Ruby.wasm 포팅 작업 중 CRuby 빌드 시스템의 복잡성에 대한 관심을 갖게 되었으며, 이를 통해 빌드 시스템의 유지보수성과 효율성 개선의 필요성을 절감했습니다. 이 발표는 Ruby 커뮤니티 전체의 빌드 프로세스 개선을 위한 동기에서 시작되었습니다.

CRuby 빌드 프로세스 개요

  • 기본 빌드 과정: 대부분의 사용자는 버전 관리자를 통해 Ruby를 설치하며, 이는 내부적으로 tarball 다운로드 후 configure, make, make install 과정을 거칩니다.
    • configure: 시스템 검사 및 빌드 파일 생성.
    • make: 인터프리터 및 확장 기능 빌드.
    • make install: 빌드된 파일을 최종 위치에 배치.
  • 소스(Git) 빌드: 개발 시 Git 소스에서 직접 빌드하는 경우, 시스템에 base Ruby가 설치되어 있어야 하며, autoconf를 실행하여 configure 스크립트를 생성해야 합니다.
  • 타르볼 vs. 소스 빌드: 타르볼은 base Ruby 의존성 없이 자가 완결적이어야 하므로, Ruby가 필요한 모든 파일(파서용 C 파일, 사전 컴파일된 rb_inc 등)이 미리 생성되어 포함됩니다.

빌드 시스템 분석

  • 빌드 시간 추이: trace-make 도구를 사용하여 빌드 과정을 분석한 결과, configure 시간은 Ruby 버전이 올라갈수록 선형적으로 증가하는 추세를 보입니다. 이는 기능 감지 체크의 증가와 순차적 실행 방식 때문입니다.
    • configure.ac 파일의 라인 수도 6,000 라인에 육박하며, 이는 configure 시간 증가와 직접적인 상관관계를 가집니다.
    • configure.ac의 가장 활발한 커미터는 Nobu로, 이는 빌드 시스템 유지보수의 단일 의존성 문제를 시사합니다.
  • make 시간 추이: make 단계의 컴파일 시간도 Ruby 버전이 증가함에 따라 자연스럽게 늘어나고 있습니다. Ruby 3.3 이후 버전은 5분 이상 소요됩니다(J1 빌드 기준).
    • 병렬 처리(J1)의 한계로 인해 make 과정에 유휴 시간이 많이 발생하며, 이는 단계별 의존성(예: 모든 확장 라이브러리가 구성될 때까지 컴파일 시작 불가)으로 인한 병목 현상 때문입니다.

빌드 프로세스의 복잡성

  • 다양한 make 구현 지원: GNU Make(오래된 버전 포함), BSD Make, Windows용 NMAKE 등 다양한 make 구현을 지원해야 합니다. 이는 common.mk, uncommon.mk, win32/Makefile.sub 등 복잡한 Make 파일 구조를 야기합니다.
  • 다단계 Ruby 변형 사용: 빌드 과정에서 base Ruby, mini Ruby 등 여러 Ruby 변형이 사용됩니다.
    • base Ruby: Ruby 파일을 C로 변환, ERB 템플릿 처리, Racc 파서 처리 등 코드 생성 작업에 사용됩니다.
    • mini Ruby: 확장 라이브러리(extconf.rb)를 구성하고 컴파일하는 데 주로 사용됩니다. 크로스 컴파일 시에는 base Ruby가 이 역할을 대신합니다.
  • 재귀적 make: 확장 라이브러리 빌드는 재귀적 make 방식을 사용합니다. 루트 make 파일이 인터프리터 코어를 컴파일한 후, 각 확장 라이브러리의 configuremake를 재귀적으로 호출하여 빌드합니다. 이는 병목 현상을 유발합니다.

현재의 도전 과제

  • 다양한 빌드 환경: 여러 플랫폼, 인-소스/아웃-오브-소스 빌드, 동적/정적 링크, base Ruby 가용성 등에 대한 복잡한 처리가 필요합니다.
  • make-time 동적 처리: 조건부 타겟 활성화(yes_no 패턴), 복잡한 크로스 컴파일 조건 등으로 인해 빌드 과정 추적 및 디버깅이 어렵습니다.
  • configure.ac의 표현력 한계: configure 단계에서 모든 빌드 로직을 표현하기 어려워, 많은 복잡성이 make 단계로 전가됩니다.
  • 의도치 않은 base Ruby 의존성: 타르볼 빌드 시 base Ruby에 의존해서는 안 되지만, 때때로 의존성이 발생하여 문제가 되며, 이를 쉽게 검증하기 어렵습니다.
  • 빌드 시간 증가: configure의 순차적 실행과 make 단계의 병렬 처리 비효율성이 빌드 시간을 늘리는 주요 원인입니다.

미래 방향성: 새로운 빌드 시스템 제안

  • 복잡성 해소: 빌드 로직을 makem4에서 Ruby로 전환하여 명확성을 높이고, 빌드 계획을 실행 전에 검증할 수 있도록 합니다.
  • 성능 개선: 기능 감지 작업을 빌드 시스템 내에서 병렬화하고, 재귀적 make 대신 단일 빌드 그래프를 사용하여 전체 빌드 과정의 태스크 스케줄링을 최적화하여 유휴 시간을 줄입니다.
  • 새로운 빌드 시스템(작업 중):
    • Ruby를 사용하여 전체 빌드 그래프를 구성합니다.
    • 빌드 시스템을 라이브러리 형태로 제공합니다.
    • 최종 사용자는 Ruby 설치 없이 Ruby를 빌드할 수 있도록 autoconf와 유사한 configure 스크립트를 생성합니다(CMake, Meson과 달리 이식 가능한 Make 파일을 생성).
    • 빌드 그래프를 프로그래밍 방식으로 분석하여 의도치 않은 의존성을 사전에 감지합니다.
    • config.h와 같은 파일 생성을 빌드 시스템 내에 통합합니다.
    • 이는 Rubywin이나 기타 단일 바이너리 패키저와 같은 다른 프로젝트에 CRuby 빌드를 쉽게 통합할 수 있게 합니다.

현재 이 새로운 빌드 시스템은 개발 초기 단계이며, 문서화, Windows 지원, 동적 의존성 처리 등 해결해야 할 과제가 많지만, CRuby 빌드의 근본적인 문제 해결을 목표로 합니다.

결론

CRuby 빌드 시스템은 오랜 진화의 역사 속에서 상당한 복잡성과 성능 문제를 안고 있습니다. 특히 `configure` 시간의 선형적 증가, `make` 단계의 병렬 처리 비효율성, 그리고 다양한 빌드 환경과 `make`-time 동적 처리로 인한 유지보수성 저하가 주요 도전 과제로 부각됩니다. 발표자가 제안하는 Ruby 기반의 새로운 빌드 시스템은 이러한 문제들을 해결하기 위한 혁신적인 접근 방식을 제시합니다. 빌드 로직의 Ruby화, 빌드 계획의 사전 검증, 그리고 병렬 처리 최적화를 통해 CRuby 빌드 과정을 더욱 효율적이고 유지보수하기 쉽게 만들며, 최종 사용자에게는 익숙한 경험을 제공하면서도 개발자에게는 더 나은 환경을 제공할 것으로 기대됩니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!