CMake
Definition : What is CMake
- this is a tool or language (not compiler) that create commands of compiler based on what OS is and what kind of Generator (build system) we use.
Terms
Term | Meaning |
---|---|
configure | CmakeList.txt를 읽으며, 프로젝트 설정들을 확인하여, build 에 필요한 재료들을 만드는 과정 및 행동 |
build | .. |
target | configure or build 대상들 |
linking | target들을 연결하는 과정. 빌드를 한다고하면, 각 target들로부터 개별적인 object 파일들을 만들며, 이 object 파일들을 연결해줘야한다. |
configurations | First off Debug/Release are called configurations |
.dll | 동적 라이브러리 : 라이브러리 인데, 런타임에 포함되는 라이브러리임 + .lib 사용될때 같이 사용됨 |
.lib | 정적 라이브러리 : 라이버리리 인데, 컴파일 때 포함되는 라이버리임 + 모든 코드가 다 들어있음 |
[ .dll / .lib 언제 사용 ? ]
빌드 방식 | 필요 파일 | 설명 |
---|---|---|
정적 라이브러리 | .lib | 실행 파일에 라이브러리 코드가 포함. .dll 파일 불필요. |
동적 라이브러리 | .lib + .dll 컴파일 시 | .lib, 실행 시 .dll 필요. 실행 파일 배포 시 .dll 포함. |
Install list of CMake dev env
Windows
- install several software
- Visual Studio 2022
- CMake
- Git
- Doxygen
- Python 3.8 or newer
- install wsl :
wsl --install
- install package on linux (ubuntu)
sudo apt-get update sudo apt-get upgrade # Mandatory sudo apt-get install gcc g++ gdb sudo apt-get install make cmake sudo apt-get install git sudo apt-get install doxygen sudo apt-get install python3 python3-pip # Optional sudo apt-get install lcov gcovr sudo apt-get install ccache sudo apt-get install cppcheck sudo apt-get install llvm clang-format clang-tidy sudo apt-get install curl zip unzip tar sudo apt-get install graphviz
- install several extentions of vscode
- C/C++ Extension Pack
- Coding Tools extension Pack
- WSL
- set global setting on VScode (User tab)
optional
———————-
- separator
How to start
- generate C/C++ config files (vscode - command pallate)
> C/C++ Config: Generate C++ config Files
- open vscode in workspace directory and turn it into wsl workspace
> wsl: reopen folder in wsl
- move to exact folder where you want to work in
ctrl+k ctrl+o # open folder
Build after coding
```
0.) Create Source and CMakeFile
1.) mkdir build
2.) cd build
3.) cmake .. - Generting the Build Files / Configure the Project
4.) cmake --build .
5.) ./Executable
```
———————-
- separator
[ 실행파일 더하기 - Basic (project / add_executable) ]
cmake_minimum_required(VERSION 3.22)
# projectName projectVersion projectLanguage (CXX stands for C++)
# v v v
project(CppProjectTemplate VERSION 1.0.0 LANGUAGES C CXX)
# User defined name
# v
add_executable(Executable main.cc)
[ 변수 추가 - set ]
- set(변수명 변수값) or set(변수명 “변수값”) -> 선호에 따라서
set(LIBRARY_SOURCES
my_lib.cc)
set(LIBRARY_HEADERS
my_lib.h)
or
set(LIBRARY_SOURCES
"my_lib.cc")
set(LIBRARY_HEADERS
"my_lib.h")
[ os 환경변수 (외부환경변수) 사용 ]
- set(CMAKE변수명 $ENV{컴퓨터환경변수})
- bring os env variable in cmake. and then use it as a local variable
[ local 라이브러리 추가 - add library ]
- 이건 하나의 CMakeList.txt로 다 해결하려고 할때.
-
prerequisites
- we have to know c++ syntax in advance.
- create header file
- include the header file in target source file
set(EXECUTABLE_NAME Executable)
set(LIBRARY_NAME Library)
add_library(${LIBRARY_NAME} my_lib.cc) # library 파일들 리스트업
add_executable(${EXECUTABLE_NAME} main.cc) # execuatable 하게 만들 파일 targeting
target_link_libraries(${EXECUTABLE_NAME} ${LIBRARY_NAME}) # library하고 target파일을 연결관계 정의
[ local 라이브러리 추가 2 ]
- 폴더 구조를 만들고, library 를 위한 코드들이 다른 공간으로 분리되어있을 때,
- header 파일을 추가하고싶을때, 사용
# - root
# |-- app
# | |-- main.cc
# | |-- CMakeList.txt :
# add_executable(${EXECUTABLE_NAME} "main.cc")
# target_link_libraries(${EXECUTABLE_NAME} PUBLIC ${LIBRARY_NAME})
# |-- src
# |-- CMakeList.txt : add_subdirectory(my_lib)
# |-- my_lib
# |-- CMakeList.txt : add_library / target_include_directories 사용 ----------
# |-- CMakeList.txt |
# cmake_minimum_required(VERSION 3.22) |
# project(CppProjectTemplate VERSION 1.0.0 LANGUAGES C CXX) |
# set(EXECUTABLE_NAME Executable) |
# set(LIBRARY_NAME Library) |
# add_subdirectory(src) |
# add_subdirectory(app) |
# ---------------------------------------------------------
# |
set(LIBRARY_SOURCES
my_lib.cc)
set(LIBRARY_HEADERS
my_lib.h)
add_library(${LIBRARY_NAME} STATIC
${LIBRARY_SOURCES}
${LIBRARY_HEADERS})
# Include dir to header files
# This does not have to be set, to be able to compile the program
# However, for MSVC builds this is needed, to have the headers listed in VS.
target_include_directories(${LIBRARY_NAME} PUBLIC
"./")
[ Debug / release 지정하는법 ]
-
First off Debug/Release are called configurations in cmake (nitpick). If you are using a single configuration generator (Ninja/Unix-Makefiles) you must specify the CMAKE_BUILD_TYPE.
-
Like this:
# Configure the build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug
# Actually build the binaries
cmake --build build/
# Configure a release build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Release
# Build release binaries
cmake --build build/
For multi-configuration generators it's slightly different (Ninja Multi-Config, Visual Studio)
# Configure the build
cmake -S . -B build
# Build debug binaries
cmake --build build --config Debug
# Build release binaries
cmake --build build --config Release
- If you are wondering why this is necessary it’s because cmake isn’t a build system. It’s a meta-build system (IE a build system that build’s build systems). This is basically the result of handling build systems that support multiple-configurations in 1 build. If you’d like a deeper understanding I’d suggest reading a bit about cmake in Craig Scott’s book “Professional CMake: A Practical Guide
[ External library 사용 - Imath]
- Imath build 먼저
- CMakeList.txt 에 아래의 conditions 들 추가
- set Imath_DIR to ImathConfig.cmake directory.
- put include directory in target_include_directories() function
- put .lib file path in target_link_libraries() function to link in between source code and libraries.
... set(Imath_ROOT ...) set(Imath_LIB ${Imath_ROOT}/lib/Imath-3_1.lib) set(Imath_DIR ${Imath_ROOT}/lib/cmake/Imath) set(Imath_INCLUDE_DIR ${Imath_ROOT}/include/Imath) find_package(Katana PATHS "${KATANA_ROOT}/plugin_apis/cmake" REQUIRED) find_package(Imath REQUIRED) add_library( ${LIBRARY_NAME} MODULE code.cpp ) target_include_directories( ${LIBRARY_NAME} PUBLIC ${Imath_INCLUDE_DIR} ) target_link_libraries(${LIBRARY_NAME} PRIVATE Katana::FnGeolibPluginApis::Shared ${Imath_LIB} ) set_target_properties(${LIBRARY_NAME} PROPERTIES PREFIX "")