1. Ruby 4.0 환경에서의 네이티브 확장 검증 배경
Ruby 4.0은 패키징 및 표준 라이브러리 구조에 여러 변화를 도입했습니다. ruby-libgd는 extconf.rb를 통해 공유 객체를 컴파일하고 libgd와 링크되는 C 확장이므로, 이러한 변화에 민감하게 반응합니다. 개발자는 단순히 “지원 예정”이라고 명시하는 대신, Docker와 CI를 활용한 깨끗한 환경에서 다음 세 가지 엄격한 기준을 바탕으로 호환성을 검증했습니다.
- Ruby 4.0.1에서 확장이 성공적으로 컴파일되어야 함
- 전체 테스트 스위트가 통과해야 함
- require "gd/gd"를 통한 런타임 로드가 정상적으로 작동해야 함
2. 핵심 문제: archhdrdir 누락 현상
가장 먼저 마주한 문제는 C 코드 자체의 오류가 아닌 빌드 환경의 설정 오류였습니다. Ruby 4.0.1 Docker 이미지 내에서 RbConfig::CONFIG['archhdrdir'] 값이 nil로 반환되는 현상이 발견되었습니다. archhdrdir은 ruby/config.h와 같은 아키텍처별 헤더 파일이 위치한 경로를 가리키는데, 이 값이 없으면 mkmf가 헤더를 제대로 찾지 못해 컴파일에 실패하거나 엉뚱한 경로를 참조하게 됩니다. 이는 소스 코드의 결함이 아니라 배포판의 패키징 방식 변화로 인한 문제였습니다.
3. 해결 전략: 환경 변수를 통한 정석적 접근
개발자는 이 문제를 해결하기 위해 다음과 같은 소모적인 방식(Anti-patterns)을 의도적으로 지양했습니다.
- ruby-dev 패키지 강제 설치 (Docker 이미지 구조 파괴)
- extconf.rb 파일에 하드코딩된 경로 패치 적용
- Ruby 헤더 파일을 Gem 내부에 포함(Vendoring)
- 런타임에서 LoadError를 무시하는 코드 추가
대신, Docker 빌드 시점에 헤더 경로를 명시적으로 내보내는(export) 방식을 선택했습니다. export RUBY_HDR_DIR="/usr/local/include/ruby-4.0.0/x86_64-linux"와 같이 설정하면 mkmf에 헤더 위치를 정확히 알려줄 수 있습니다. 이 방식은 소스 코드를 수정하지 않으면서도 컴파일과 링크를 성공시켰으며, 오직 Docker 기반의 Ruby 4.0 빌드 과정에만 영향을 미치는 깔끔한 해결책이 되었습니다.
4. CI 환경에서의 빌드 자동화 개선
Bundler를 사용하여 로컬 소스 경로(path: ".")에서 Gem을 테스트할 때, 네이티브 확장이 자동으로 빌드되지 않아 gd/gd.so 파일을 찾지 못하는 문제가 CI 단계에서 추가로 발견되었습니다. 로컬 개발 환경에서는 기존에 빌드된 파일이 있어 문제가 드러나지 않았으나, 깨끗한 CI 환경에서는 오류를 유발했습니다. 이를 해결하기 위해 CI 워크플로우에 ruby ext/gd/extconf.rb && make와 같은 명시적인 컴파일 단계를 추가했습니다. 이는 Ruby 4뿐만 아니라 모든 버전의 네이티브 Gem 개발 시 CI 환경에서 반드시 고려해야 할 표준 절차입니다.
5. 검증 결과 및 릴리스
모든 환경 설정과 빌드 흐름을 수정한 후, ruby-libgd는 Ruby 4.0.1에서 어떠한 API 변경이나 버전별 분기 처리 없이도 완벽하게 작동함을 확인했습니다. 이러한 검증 결과는 ruby-libgd 0.2.4 패치 릴리스의 CHANGELOG에 공식적으로 기록되었습니다. 개발자는 이를 통해 사용자들에게 단순한 주장이 아닌, 테스트로 입증된 신뢰할 수 있는 호환성 정보를 제공할 수 있게 되었습니다.