내가 빌드한 프로젝트의 실행 프로그램을 다른 환경에서 실행하면 에러가 발생할 수 있다. 그 이유는 실행파일이 올바른 라이브러리 경로를 참조할 수 없기 때문이다. 어떻게 하면 LD_LIBRARY_PATH 환경변수 설정을 따로 하지 않고 바로 실행프로그램을 실행할 수 있을까?
우선 리눅스에는 RPATH와 RUNPATH라는 개념이 있다.
RPATH | 바이너리에 "공유 라이브러리를 찾을 경로"를 직접 박아넣음. 시스템 기본 규칙보다 우선함. |
RUNPATH | 비슷하게 "공유 라이브러리 경로"를 설정하는데, LD_LIBRARY_PATH 환경변수가 우선함. |
즉, RPATH는 무시하기 어렵고 고정적이고, RUNPATH는 LD_LIBRARY_PATH로 쉽게 오버라이드할 수 있다.
RPATH는 LD_LIBRARY_PATH와 같은 시스템 변수를 무시할 수 있기 때문에 보안상의 문제로 RPATH 보다 RUNPATH를 많이 사용한다.
예제
.
├── cmake-build-debug
├── CMakeLists.txt
├── library.cpp
├── library.h
└── main.cpp
위 디렉토리 구조로 파일을 만들어 준다.
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0.0)
# 라이브러리 빌드
add_library(mylib SHARED library.cpp)
# 실행 파일 빌드
add_executable(myapp main.cpp)
# 실행파일이 라이브러리를 링크하도록
target_link_libraries(myapp PRIVATE mylib)
# RUNPATH 설정
# cmake에서는 기본적으로 RUNPATH를 우선시 함
set_target_properties(myapp PROPERTIES
INSTALL_RPATH "$ORIGIN/../lib"
BUILD_WITH_INSTALL_RPATH TRUE
)
# RPATH로 설정하고 싶으면 아래와 같이 설정
# set_target_properties(myapp PROPERTIES
# INSTALL_RPATH "$ORIGIN/../lib"
# BUILD_WITH_INSTALL_RPATH TRUE
# SKIP_BUILD_RPATH FALSE
# BUILD_RPATH_USE_ORIGIN TRUE
# SKIP_INSTALL_RPATH FALSE
#)
# 설치 설정
install(TARGETS mylib
LIBRARY DESTINATION lib
)
install(TARGETS myapp
RUNTIME DESTINATION bin
)
빌드 디렉토리로 이동하여 아래 커맨드를 통해 install 해줌
cmake .. -DCMAKE_INSTALL_PREFIX=../install
cmake --build .
cmake --install .
$ readelf -d myapp
Dynamic section at offset 0xd60 contains 30 entries:
Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libmylib.so]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/../lib] << runpath가 아래와 같이 설정됨을 확인
...
라이브러리가 실행 프로그램 기준 상대 경로로 설정되어 있기 때문에 따로 라이브러리 설정을 안해줘도 정상적으로 프로그램이 실행됨
'프로그래밍 언어 > Cmake' 카테고리의 다른 글
CMake EXPORT (0) | 2025.04.25 |
---|---|
Conan 패키지 매니저: 시작하기 (0) | 2023.09.21 |
cmake (0) | 2023.04.05 |
Makefile (0) | 2020.05.25 |
GCC (0) | 2020.05.12 |