CMake
CMake란 여러 환경(window , linux 등)에 맞는 build process를 작성한 것으로, CMakeLists.txt에 기술된 내용을 바탕으로 각 확경에 맞는 Makefile을 생성해 주는 빌드 프로그램이다.
CMake를 통해 Makefile을 만들게 되면, 추가적인 파일이 추가되지 않는 한 Makefile을 수정하지 않고, 자동으로 생성해준다는 장점이 있지만, 단순히 Makefile을 생성해 주는 것이기 때문에 Make를 추가로 해야한다.
이 포스트는 linux 기준으로 설명한다.
Install
linux에 CMake가 없을 경우 다음과 같이 설치할 수 있다.
sudo apt install cmake
CMakeLists.txt
앞에서 말했듯이 CMake는 CMakeLists.txt에 기술 된 것을 바탕으로 Makefile을 생성하기 때문에 이를 작성해 주어야 한다. 먼저, 작성한 코드의 파일 구조는 다음과 같다.
workspace |-CMakeLists.txt
|-main.cpp
이때, main.cpp를 build하여 example이라는 실행파일을 만들기 위한 CMakeLists.txt는 다음과 같다.
cmake_minimum_required(VERSION 3.0.1)
project(example)
add_executable(${PROJECT_NAME} main.cpp)
이제 cmake를 사용하는 방법은 다음과 같다.
cmake <CMakeLists.txt가 있는 파일 경로>
그러면 위의 파일구조에서의 cmake 예시는 아래와 같다.
~/workspace$ cmake .
그러면 다음과 같이 파일들이 생성된다.
workspace |-CMakeLists.txt
|-main.cpp
|-CMakeCache.txt
|-cmake_install.cmake
|-Makefile
|-CMakeFiles -| ...
이제 여기서 Make를 실행하면 실행파일인 example이 생성되고, 실행하면 기존 코드가 정상적으로 실행되는 걸 확인 할 수 있다.
Functions
cmake_minimum_required(VERSION 3.0.1)
project를 build하기 위해 필요한 최소한의 CMake의 버젼 명시
project(name)
project의 이름을 명시, 이 함수 실행 후 CMake내부 매크로로 ${PROJECT_NAME}으로 project이름을 호출할 수 있다.
add_library(library_name lib.cpp lib.h)
lib.cpp 와 lib.h로 정의된 library를 library_name으로 생성할 때 사용한다. 이때, 생성만 되고 프로젝트의 소스 코드를 빌드할 때는 자동 추가 되지 않으며, 뒤에 target_link_libraries를 통해 빌드에 추가 해 주어야 한다.
include_directories(dir ...)
.cpp파일에서 include의 기본 경로들을 추가해 준다.
add_executable(result src)
Makefile을 작성할 때 gcc -o result src와 같다. result라는 실행 파일을 src를 빌드하여 만드는 걸 명시 한다.
add_dependenciese(target depend1 ... )
target의 빌드 의존성을 추가해 준다.
target_link_libraries(target lib1 ... )
linker가 실행파일을 생성할 때 필요한 target에 대한 libraries를 명시해 준다.
message(msg)
CMake가 실행 될때 msg에 해당하는 문자들을 출력해 준다.
file(GLOB dst <type>)
<type>에는 모든 경로 & 파일을 의미하는 * 또는 특정 확장자를 명시하는 *.cpp 와 같은 구문이 들어갈 수 있으며, 이에 해당하는 파일경로 또는 파일 이름들을 dst에 저장하게 되며, 항목이 여러개일 경우 ;을 통해 구분되어 들어간다.
foreach(src srcs) / endforeach()
여러개의 항목이 정의 되고 ;으로 구분된 srcs를 하나 씩 src에 넣어서 foreach() 와 endforeach()사이의 구문을 반복하게 된다.
if(IS_DIRECTORY src) / endif()
간단한 if 구문에 옵션을 추가한 것으로 src에 오는 문자열이 파일경로를 의미하는지 아닌지 판단해 준다.
add_subdirectory(dir)
CMake를 하는 경로를 추가해 준다. 추가된 경로에 있는 CMakeLists.txt의 내용들도 반영하여 추가적인 Makefile을 생성한다.
응용
위의 함수들을 응용하여 CMakeLists.txt를 작성하면 다음과 같다.
cmake_minimum_required(VERSION 3.0.2)
project(robot_core)
add_compile_options(-std=c++11)
file(GLOB FILE_LISTS include/*)
set(INCLUDE_DIR "")
set(LIB_SRCS "")
set(LIB_HEADERS "")
foreach(FILE_LIST ${FILE_LISTS})
if(IS_DIRECTORY ${FILE_LIST})
list(APPEND INCLUDE_DIR ${FILE_LIST})
message("ADD INCLUDE DIRECTORY : ${FILE_LIST}")
file(GLOB LIB_SRC ${FILE_LIST}/*.cpp )
list(APPEND LIB_SRCS ${LIB_SRC})
file(GLOB LIB_HEADER ${FILE_LIST}/*.h )
list(APPEND LIB_HEADERS ${LIB_HEADER})
endif()
endforeach()
include_directories(
include
${INCLUDE_DIR}
)
message("LIB_SRCS : ${LIB_SRCS}")
message("LIB_HEADERS : ${LIB_HEADERS}")
add_library(my_lib ${LIB_SRCS} ${LIB_HEADERS})
target_include_directories(my_lib
PRIVATE include ${INCLUDE_DIR}
)
add_executable(robot_core src/main.cpp)
target_link_libraries(robot_core
${catkin_LIBRARIES} my_lib
)
이상 포스팅을 마친다.
틀린거나 모르는거 댓글로 알려주세요
'프로그램 언어' 카테고리의 다른 글
[ C / C++ ] make , Makefile (1) | 2021.01.30 |
---|---|
[ C / C ++ ] 프로그램하기전 지식 (1) | 2021.01.30 |