pulse.huny.dev
HunyDev
Making Linux Binaries Load Local .so Libraries Automatically

Making Linux Binaries Load Local .so Libraries Automatically

리눅스에서 “실행 파일 옆의 .so를 자동으로 찾게” 만드는 핵심은 ELF rpath/runpath의 $ORIGIN 토큰이다.

Hun Jang
Hun Jang Dec 5, 2025

$ORIGIN으로 이식성 높은 바이너리 만들기

  • ELF 바이너리는 필요한 공유 라이브러리를 동적 로더(ld.so)가 찾는다.
  • 기본 탐색 경로는 LD_LIBRARY_PATHDT_RUNPATH/DT_RPATH → 시스템 디렉터리 순서로 이뤄진다(세부 동작은 아래 참고).
  • $ORIGIN현재 로드되는 객체(실행 파일 또는 .so) 파일이 있는 디렉터리를 의미한다. 그래서 배포 폴더 안에 bin/lib/만 있으면 시스템에 설치 없이도 실행 가능해진다.

빌드 시 설정(권장)

  • 작은따옴표로 감싸 셸이 $ORIGIN을 확장하지 않도록 한다.
  • 여러 경로를 넣으려면 Wl,-rpath,'$ORIGIN/../lib:$ORIGIN'.

빌드 후 수정(이미 만들어진 바이너리)

chrpath도 가능하지만 DT_RUNPATH를 다루기엔 patchelf가 더 범용적이다.

rpath vs runpath 한 줄 정리

  • RUNPATH(DT_RUNPATH): 현대적 방식. LD_LIBRARY_PATH가 먼저 적용되고 그다음 RUNPATH가 적용된다.
  • RPATH(DT_RPATH): 구식. 있을 때는 종종 LD_LIBRARY_PATH보다 우선되어 예상치 못한 탐색 순서를 만들 수 있다.
  • 최신 툴체인은 기본적으로 RUNPATH를 쓴다. 필요하면 -disable-new-dtags로 RPATH를 강제할 수 있다. 일반 배포는 RUNPATH 유지가 안전하다.

디버깅 팁

구조 예시(셀프 컨테인드 배포)

자주 겪는 함정

  • 따옴표 누락: Wl,-rpath,$ORIGIN/../lib로 쓰면 셸이 $ORIGIN을 빈 문자열로 바꿔버린다.
  • 심볼릭 링크/SONAME 불일치: libmylib.so → libmylib.so.1SONAME을 맞춰야 런타임 로딩이 깔끔하다.
  • setuid 바이너리: 보안상 $ORIGIN/LD_LIBRARY_PATH가 무시될 수 있다.
  • 컨테이너/서로 다른 배포판: GLIBC 최소 버전 차이로 로딩 실패 가능 → 가능한 한 낮은 빌드 베이스로 컴파일하거나 정적 링크 후보를 검토.
 

You might also like

BlogPro logo
Made with BlogPro

Tags