반응형
본 문서는 CMake에 패키지 관련 내용을 나열한 문서로,
주로 설치한 패키지를 받아서 사용하기 위해 사용합니다.
Package
Package의 구성
보통 패키지라고 하면 Chocolaty, NuGet, RPM, Brew처럼 Package Manager 소프트웨어를 통해 다운로드/설치/업데이트해서 사용하는 프로그램들(+ 문서)을 말하는데, C++ 프로그래머들에게 패키지란 개발에 필요한 Library + Manifest에 가까운 것 같습니다.
- 일반적인 패키지:
- 실행 프로그램(executable)
- 문서 파일(license, manual, readme 등)
- 프로그래밍 패키지: 일반 패키지 + 개발에 필요한 요소들
- 서브 프로그램(library)
- 실행 프로그램(test tools, script 등)
- 소스 코드(include, example 등)
C++ 프로젝트의 파일트리
지금은 많은 C++ 프로젝트들이 Unix Filesystem에서 표준 C 라이브러리를 배치할때 사용하던 파일트리 구조를 적용하고 있습니다.
굳이 이런 배치에 어떤 의미가 부여되어있다기 보다는, "CMake의 초창기부터 Unix 시스템에 빌드 된 라이브러리을 설치하면서 관례를 따르던 것이 이어지고 있다"정도로 생각하면 될 것 같습니다.
- bin : 실행 프로그램(executable)
- lib : 미리 빌드된 라이브러리(so, lib 등)
- include : 소스 코드(헤더)
- share : 기타 필요한 파일들. 주로 빌드 지원 파일
- docs : 문서가 (많이) 있는 경우 따로 두기도
CMake Package
CMake Package을 위한 CMake 구성
실행 파일 및 라이브러리 폴더 구성
실행 파일과 라이브러리 파일을 비롯하여 필요한 파일들의 위치를 /lib, /bin 폴더로 모아줍니다.
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Archive output dir. (.lib / .a)")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Library output dir. (.so / .dylib)")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "PDB (MSVC debug symbol)output dir.")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir. (.exe / .dll)")
You can also specify the output directories on a per-target basis:
set_target_properties( targets...
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
CMake Package 파일 구성
CMakeLists.txt
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "gmbdmr")
install(FILES
${CMAKE_SOURCE_DIR}/etc/Conf.json
${CMAKE_SOURCE_DIR}/etc/Conf.so.conf
DESTINATION conf
COMPONENT Conf)
install(DIRECTORY
${CMAKE_SOURCE_DIR}/db
DESTINATION .
COMPONENT Db)
install(TARGETS ${PROJECT_NAME} app.out
RUNTIME DESTINATION bin
COMPONENT Project
)
include(package.cmake)
- install: 빌드 완료된 실행 바이너리와 라이브러리 및 기타 부속물(헤더 파일, 리소스 등)들을 시스템의 적절한 위치로 복사하는 동작
package.cmake
SET(CMAKE_INSTALL_PREFIX "/opt/project")
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_FEATURE "${GIT_VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_RELEASE "${GIT_VERSION}")
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+" LIBRARY_VERSION "${GIT_VERSION}")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Project Server")
SET(CPACK_PACKAGE_VENDOR "DrawingProcess Inc.")
SET(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PROTO}.${VERSION_PATCH}")
# include(../cmake/GetGitRevisionDescription.cmake)
# git_describe(GIT_VERSION)
SET(CPACK_PACKAGING_INSTALL_PREFIX "/opt/project")
SET(CPACK_PACKAGE_FILE_NAME "Project-${GIT_VERSION}")
SET(CPACK_ARCHIVE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}")
SET(CPACK_PACKAGE_NAME "Project")
SET(CPACK_GENERATOR "TGZ;ZIP")
SET(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
MESSAGE( STATUS "CPACK_ARCHIVE_COMPONENT_INSTALL: " ${CPACK_ARCHIVE_COMPONENT_INSTALL} )
set(CPACK_COMPONENTS_ALL Conf Db Project)
include(CPack)
- CMAKE_INSTALL_PREFIX: 설치 매크로(make install)에서 실행 바이너리와 라이브러리 등의 최종 생성물을 복사할 설치 디렉토리를 지정합니다. INSTALL() 명령에서 상대 경로를 사용한 경우, 이 변수에 지정한 디렉토리가 Base 디렉토리가 됩니다.
- 이 변수를 별도로 지정하지 않으면 기본값은 /usr/local 입니다.
- 하단에 지정해준 set(CPACK_COMPONENTS_ALL ...) 명령을 통해 해당 컴포넌트 별 tgz.gz 형식의 압축파일을 구성합니다.
- 여기서 지정 가능한 컴포넌트는 ADD_SUBDIRECTORY로 지정해주어 해당 디렉토리에 정의된 컴포넌트, FetchContent로 불러와 해당 프로젝트에 정의된 컴포넌트 등 최상단의 CMakeLists.txt 파일이 읽어들인 모든 컴포넌트를 의미합니다.
CPACK_GENERATOR 옵션: 원하는 아카이브 형식으로 패키지를 생성
- 7Z: 7-Zip 파일 형식 (아카이브)
- IFW: Qt Installer 프레임 워크 (실행 파일)
- NSIS: 널 소프트 설치 프로그램 (실행 가능)
- NSIS64: 널 소프트 설치 프로그램 (64 비트, 실행 가능)
- STGZ: Tar GZip 자동 압축 풀기 (압축 파일)
- TBZ2: Tar BZip2 압축 (아카이브)
- TGZ: Tar GZip 압축 (아카이브)
- TXZ: Tar XZ 압축 (아카이브)
- TZ: Tar 압축 압축 (아카이브)
- WiX: 도구 (실행 가능한 아카이브)를 통한 WIX MSI 파일 형식
- ZIP: ZIP 파일 형식 (아카이브)
CMake의 Package 찾기 (find_package)
* 참고: 사용하는 라이브러리가 CMake를 지원하는 경우, find_package가 매끄럽게 사용되지 않을 때는 add_subdirectory를 사용하는 것이 '정확한' 해결책이 될 수 있습니다. Package export에 문제가 있는 경우 이를 찾아내기에도, Import하는 쪽에서 수정하기에도 어렵기 때문입니다.
CMake에서 find_package를 호출하면, 해당 함수는 Package를 찾고, 그 안에 있는 Target들을 가져옵니다.
# optional import
find_package(OpenCV 3.3)
if(OpenCV_FOUND)
# ...
# target_source: Add OpenCV related source codes ...
# target_compile_options: Enable RTTI for OpenCV ...
# ...
endif()
# mandatory import
find_package(OpenCV 3.3 REQUIRED)
- find_package:
- find_package는 이름과 버전을 인자로 사용합니다.
- 탐색에 성공하면 <name>_FOUND 변수가 생성되어, 패키지 탐색 여부는 _FOUND로 확인할 수 있습니다.
- CONFIG를 통해 상세한 옵션(path...)으로 패키지를 탐색할 수 있습니다.
CMake의 Package 내 Target 사용하기 (target_link_libraries)
find_package(gRPC CONFIG REQUIRED)
# ...
target_link_libraries(main
PRIVATE
gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc_cronet
)
- CMake에서 find_package를 호출하면, 해당 함수는 Package를 찾고, 그 안에 있는 Target들을 가져옵니다.
- executable과 링킹을 하지는 않기 때문에, 가져온 Target들은 add_library(INTERFACE) 혹은 add_library(SHARED)로 만들어진 결과물들입니다. 따라서 이들을 사용하기 위해 링킹하는 함수는 target_link_libraries입니다.
- 물론 여기에는 하나의 전제가 있습니다....
- 해당 라이브러리가 CMake에서 Import할 수 있도록 적절하게 Manifest를 작성해 놓았거나, CMake의 export함수를 사용해 CMake를 위한 Manifest를 생성해놓은 것입니다.
- *Manifest: 보통 Manifest이라고 하면 -config.cmake를 말하며, 이 문서 상에서만 "Package를 내보낸것과 같이 가져오기 위한 목록"이라는 의미로 사용하기에 웹에서 CMake관련 검색할 때 사용하면 오히려 방해가 될 수 있습니다.
- 해당 라이브러리가 CMake에서 Import할 수 있도록 적절하게 Manifest를 작성해 놓았거나, CMake의 export함수를 사용해 CMake를 위한 Manifest를 생성해놓은 것입니다.
참고
- CMake 튜토리얼 Lv.3: https://gist.github.com/dongbum/d1d49e38a20f9cf52ea39f9ce2702160#file-tutorial-p3-md
- CMake add_executable in another directory [duplicate]: https://stackoverflow.com/questions/50301919/cmake-add-executable-in-another-directory
- How do I make CMake output into a 'bin' dir?: https://stackoverflow.com/questions/6594796/how-do-i-make-cmake-output-into-a-bin-dir
- CMake 간단한 소개서: https://booiljung.github.io/technical_articles/c_language/simple_cmake_introduction.html
- [CMake 튜토리얼] 2. CMakeLists.txt 주요 명령과 변수 정리: https://www.tuwlab.com/ece/27260
반응형
'Study: DeveloperTools(DevTool) > DevTool: CMake' 카테고리의 다른 글
[CMake] Window에서 CMake 사용하여 프로젝트 만들기 (0) | 2023.05.23 |
---|---|
[IDE] VSCode C++ CMake 개발환경 세팅(MacOS, Linux) (0) | 2022.07.19 |
[CMake] 변수 및 이미 정의된 매크로 값들 (0) | 2022.07.07 |
[CMake] configure_file(): CMake 변수값을 소스코드에서 사용! (0) | 2022.07.04 |
[CMake] function: 반복되는 작업은 함수화하자! (0) | 2022.06.28 |