전문 복사해옴

출처 : http://neodelicious.tistory.com/232



Autotools보다 cMake가 얼마나 좋을까?
CMake는 Linux 외에 다른 OS에서도 범용적으로 build 환경을 제공한다는 점에서 분명히 장점이 있을 것 같다.

그런데 아직 CMake를 많이 안 써봐서 모르겠지만,
Autotools 에서는 기본값으로 되어 있는 'build command 보이기' 나 '-g 옵션을 추가' 등이
CMake에는 기본값으로 되어 있지 않은 등 분명 사용함에 있어서 차이가 있어 보인다.

KDE의 CMake 선정을 비롯한 사례로 볼 때 아마도 아직 내가 모를 뿐,
CMake에서도 Autotools의 기능을 대부분 지원하지 않을까 싶다.

아무튼 개인적으로 CMake의 소위 build template을 만들면서 공부한 것을 정리해서 올린다. 

아래 링크에서 source code를 download 할 수 있으며, 이하 글은 이 source code를 설명한다.

http://www.neodelicious.com/repos/cmake_example.tar.bz2


Assumption
1. Linux 환경을 기준으로 설명하며, '$'는 Linux Shell Prompt 를 의미함
2. 각 module 별로 CMakeLists.txt 파일을 생성하지 않고, (top directory)/CMakeLists.txt 에 모두 기술함을 기본으로 함
  2.1 원하면 (top directory)/CMakeLists.txt 파일에서 하위 directory 별로 CMakeLists.txt 파일로 분리하고 상위 directory의 CMakeLists.txt 에서 add_subdirectory 명령어를 통해 재귀적으로 호출할 수 있음
3. Top directory가 아닌 build directory에 build metadata를 생성하는 것을 기본(희망)으로 함
  3.1 Top directory에서 'cmake .'를 실행하면 top directory에 build metadata를 생성함

Reference
1. http://www.cmake.org/cmake/help/documentation.html
  1.1 http://www.cmake.org/cmake/help/cmake_tutorial.html
  1.2 http://www.cmake.org/cmake/help/cmake-2-8-docs.html


Note

1. 한 번 cmake build 하면 CMakeCache.txt 파일에 cmake build 결과의 설정값이 저장되는데, 이를 삭제하지 않고 CMakeLists.txt 파일을 수정하고 cmake build 하면 반영되지 않으니 주의해야 함


Preparation

1. $ tar xvjf cmake_example.tar.bz2
2. $ cd make_example


Build

1. Method 0 - CMakeLists.txt의 default 옵션으로 cmake build 하고, make 까지 진행하는 shell script를 이용 할 때
  1.1 $ ./start_build.sh
2. Method 1 - CMakeLists.txt의 default 옵션으로 cmake build르 직접 할 때
  2.1 $ mkdir build ; cd build
  2.2 $ cmake ..
  2.3 $ make
3. Method 2 - interactive 방식(wizard mode)으로 CMakeLists.txt의 옵션을 변경하여 make build 할 때
  3.1 $ mkdir build ; cd build
  3.2 $ cmake -i ..
  3.3 make
4. Method 3 - Curses Interface 로 CMakeLists.txt의 옵션을 변경하여 cmake build 할 때
  4.1 $ mkdir build ; cd build
  4.2 $ ccmake ..
  4.3 $ make


Run

1. build directory에 실행파일 example과 shared library인 libshow.so 파일이 있음
2. build directory에서 아래를 실행함
  2.1 $ ./example


CMakeLists.txt 파일 설명

# project
1. cmake_minimum_required (VERSION 2.6)
  1.1 cmake의 최소 버전을 명시함, 없으면 경고 메시지가 출력됨
2. project (cmake_example)
  2.1 새 project의 이름을 명시함
# user selectable variables
1. option (ENABLE_SHARED "Select OFF to build libararies as static" ON)
   option (DEBUG "Select ON to define DEBUG" ON)
   option (DEBUG2 "Select ON to define DEBUG2" ON)
  1.1 사용자가 선택할 수 있는 옵션에 대해서 이름, 설명, 기본값 순으로 설정함
2. message ("ENABLE_SHARED - ${ENABLE_SHARED}")
   message ("DEBUG - ${DEBUG}")
   message ("DEBUG2 - ${DEBUG2}")
  2.1 사용자 편의를 위한 화면 출력용으로 사용자가 선택한 값을 화면에 출력함
# dependency check
1. include (FindPkgConfig)
2. pkg_check_modules (pkgs x11>= 1.2.2 xrender)
  2.1 pkg-config tool을 이용해서 system의 library 정보를 확인할 수 있음
  2.2 아래와 같이 REQUIRED 옵션을 추가하여 조건에 부합하지 않으면 cmake build를 중단할 수 있음
    2.2.1 pkg_check_module (pkgs REQUIRED x11>=1.2.2 xrender)
3. foreach (flag ${pkg_CFLAGS})
     set (EXTRA_LIBS ${EXTRA_LIBS} ${flag})
   endforeach (flag)
   foreach (flag ${pkg_LDFLAGS})
     set (EXTRA_LIBS ${EXTRA_LIBS} ${flag})
   endforeach (flag)
 3.1 위의 pkg-config를 통해 얻은 CFLAGS, LDFLAGS 정보를 cmake 변수에 저장함
#global CMake variables
1. if (ENABLE_SHARED)
     set (BUILD_SHARED_LIBS true)
   endif (ENABLE_SHARED)
  1.1 명시적으로 static 혹은 shared 등을 명시하지 않은 add_library 명령에 대해서 기본 값인 static이 아닌 shared로 library를 build 하도록 설정함
  1.2. 이때 if 를 통해 위의 option에서 설정항 사용자의 선택에 따라 static일 경우 적용하지 않도록 함
2. set (CMAKE_VERBOSE_MAKEFILE ture)
  2.1 make build 할 때 build command를 화면에 출력하도록 함
3. set (CMAKE_BUILDTYPE debug)
  3.1 build 옵션에 -g를 포함하도록 함
4. set (CMAKE_INSTALL_PREFIX /usr)
  4.1 make install 을 통해 설치할 directory의 기준 path를 기본값이 아닌 /usr로 설정함
# global build variables
1. include_directories ("${PROJECT_SOURCE_DIR}/include")
  1.1 make build -I 로 설정하여 header file 을 찾을 path를 추가함
  1.2 PROJECT 는 최근 project 명을 대신하며, PROJECT_SOURCE_DIR 대신 여기서는 cmake_example_SOURCE_DIR 을 사용해도 됨
  1.3 PROJECT_BINARY_DIR 변수도 있는데, 이는 cmake를 실행한 path로서 여기에서는 build directory path임
# variables to the configuration file
1. configure_file ("${PROJECT_SOURCE_DIR}/include/config.h.in" "${PROJECT_SOURCE_DIR}/include/config.h")
  1.1 Source code에서 참조할 값을 반영한 config.h 파일을 config.h.in 파일을 수정해서 생성함
# build library
1. add_library (show lib/show.c)
  1.1 libshow.so 파일을 build 함
# build source
1. add_executable (example src/main.c)
  1.1 실행 파일 example 파일을 build 함
2. target_link_libraries (example show ${EXTRA_LIBS})
  2.1 실행 파일에 link할 library를 명시함
  2.2 이때 위에서 pkg-config를 통해 찾은 system 상의 library 정보를 추가함
# install
1. install (TARGETS show DESTINATION lib)
   install (TARGETS example DESTINATION bin)
   install (FILES ${PROJECT_SOURCE_DIR}/include/show.h DESTINATION include)
  1.1 기본적으로 make install을 위한 install target이 Makefile에 기술되지 않음
  1.2 위의 CMAKE_INSTALL_PREFIX 변수를 기준으로 make install에서 복사할 실행 파일, library 파일, header 파일을 명시함

include/config.h.in 파일 설명
1. #define ENABLE_SHARED "@ENABLE_SHARED@"
  1.1 cmake 내 EANBLE_SHARED 변수를 설정하면 @ENABLE_SHARED@ 값을 ON으로 변경하고, 비설정시 OFF로 설정함
2. #cmakedefine DEBUG
  2.1 cmake 내 DEBUG 변수를 설정하면 #define DEBUG를 설정하고, 비설정시 #undef DEBUG를 설정함
3. #cmakedefine01 DEBUG2
  3.1 cmake 내 DEBUG2 변수를 설정하면 #define DEBUG2 1를 설정하고, 비설정싱 #define DEBUG2 0를 설정함

+ Recent posts