티스토리 뷰

CMake는 make파일을 좀 더 쉽게 만들어 줍니다.

모든 툴이 그러하듯이 처음에는 문법이 낯설다가 익숙해지면 편해지고 개발 속도도 빨라지는데요,

CMake도 그런 종류 중 하나라고 생각됩니다.

 

Sample App 작성을 해보고, CMake 문법 관련 설명을 드리겠습니다.

 

※cmake가 설치되어 있어야 합니다. ($sudo apt-get install cmake)

※Sample Code 위치입니다. (https://github.com/z-wony/c_tutorial/tree/master/Tutorial2_CMake_build)



CMake Example (hello-cmake)

  1. hello-cmake-0.1 폴더를 생성 후 하위에 아래와 같이 디렉토리 구성을 해보았습니다.

    1. CMakeLists.txt : 작성하게 될 CMake 파일입니다.
    2. include/test.h.in : 사용할 헤더인데 CMake를 이용해 test.h로 변환할 예정입니다.
    3. src/main.c : hello를 print 하며, test.h에 있는 define들도 print합니다.
    4. tools/*.sh.in : 각자 색깔별로 test 구문을 print합니다.
      CMake에서 조건을 걸어 셋중에 하나만 hello-configuire.sh 로 변환하겠습니다.

  2. tools/ 의 shell 파일 작성
    1. hello-configure-red.sh.in
      #!/bin/sh
      echo '\033[31mHi! This is Red!\033[0m'
    2. hello-configure-blue.sh.in
      #!/bin/sh
      echo '\033[34mHi! This is Blue!\033[0m'
    3. hello-configure-green.sh.in
      #!/bin/sh
      echo '\033[32mHi! This is Green!\033[0m'
    4. 각각 자기만의 색깔로 문구를 출력하는 shell을 작성해 보았습니다.
      1. \033[32m 등은 bash에서 폰트 색깔을 바꿔줍니다.
      2. 색깔 예제 : http://misc.flogisoft.com/bash/tip_colors_and_formatting

  3. include/test.h.in 작성
    1. #ifndef __MY_TEST_HEADER__
      
      #define MY_PROJECT_NAME     "@PROJECT_NAME@"
      #define MY_COLOR_CONFIG     "@FONT_COLOR@"
      #define MY_AUTHOR_NAME      "@AUTHOR_NAME@"
      
      #endif /* __MY_TEST_HEADER__ */
      
    2. @어쩌구@ 로 붙은 값들은 cmake에서 configure 라는 동작을 수행하게 되면 CMake의 안에 있는 변수가 저 자리에 채워집니다.
      1. CMake 안에 AUTHOR_NAME 이라는 변수에 "z-wony"라는 값을 넣어 놓았다면 configure를 거쳐서 저 헤더 안의 @AUTHOR_NAME@ 은 z-wony 로 치환됩니다.
      2. 흔히들 configure를 이용할 파일들은 <파일명>.in 으로 네이밍한 후 cmake에서 configure 동작 시 <파일명> 으로 새 파일을 생성합니다.
      3. 문법은 뒤쪽에서 다시 설명하겠습니다.
    3. @PROJECT_NAME@ : 얘는 CMake가 자동으로 만들어준 변수입니다.
    4. @FONT_COLOR@ : 얘는 잠시 후 cmake 명령을 칠 때, 직접 -D<변수> 옵션으로 넣어주겠습니다.
    5. @AUTHOR_NAME@ : 얘는 CMakeLists.txt 파일 안에서 변수를 선언해 보겠습니다.

  4. src/main.c 작성
    1. #include <stdio.h>
      #include <test.h>
      
      int main(int argc, char *argv[])
      {
          printf("Hello CMake!\n");
          printf("definition 'MY_PROJECT_NAME' : %s\n", MY_PROJECT_NAME);
          printf("definition 'MY_COLOR_CONFIG' : %s\n", MY_COLOR_CONFIG);
          printf("definition 'MY_AUTHOR_NAME' : %s\n", MY_AUTHOR_NAME);
          printf("definition 'BLOG_ADDRESS' : %s\n", BLOG_ADDRESS);
      
          return 0;
      }
      
    2. #include <test.h> : 위의 test.h.in을 CMake로 configuration 해서 test.h로 변환 후 include하였습니다.
    3. BLOG_ADDRESS : 이 difine은 header파일(test.h)에 존재하지 않는데, CMake에서 define을 선언하였습니다.
      1. 이런 류는 CMake에서 필요 시 특정 log level을 출력하지 않게 하거나,
      2. 다수 architecture를 대상으로 cross-compile 시 달라질 수 있는 부분을 handling 하는 데에 사용할 수 있습니다.
  5. CMakeLists.txt 작성
    1. cmake_minimum_required(VERSION 2.6)
      project(hello-cmake C)
      
      set(BINDIR  "/usr/bin")
      set(AUTHOR_NAME "z-wony")
      add_definitions(-DBLOG_ADDRESS="z-wony.tistory.com")
      
      include_directories(${CMAKE_SOURCE_DIR}/include)
      file(GLOB SRCS src/*.c)
      
      add_executable(${PROJECT_NAME} ${SRCS})
      
      install(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
      
      if(FONT_COLOR STREQUAL "RED")
          configure_file(${CMAKE_SOURCE_DIR}/tools/hello-configure-red.sh.in ${CMAKE_SOURCE_DIR}/hello-configure.sh)
      elseif(FONT_COLOR STREQUAL "BLUE")
          configure_file(${CMAKE_SOURCE_DIR}/tools/hello-configure-blue.sh.in ${CMAKE_SOURCE_DIR}/hello-configure.sh)
      else(FONT_COLOR STREQUAL "RED")
          configure_file(${CMAKE_SOURCE_DIR}/tools/hello-configure-green.sh.in ${CMAKE_SOURCE_DIR}/hello-configure.sh)
      endif(FONT_COLOR STREQUAL "RED")
      
      configure_file(${CMAKE_SOURCE_DIR}/include/test.h.in ${CMAKE_SOURCE_DIR}/include/test.h)
      
      install(PROGRAMS hello-configure.sh DESTINATION ${BINDIR})
      
    2. CMake의 문법 중 간단하게 필요한 부분만 사용했습니다.
      1. 나머지는 https://cmake.org/cmake/help/v3.0/manual/cmake-commands.7.html 에서 보실 수 있습니다.
    3. project : 프로젝트명을 지정합니다.
    4. set : 필요한 변수를 지정할 수 있습니다.
      1. 여기서 지정한 AUTHOR_NAME 변수를 include/test.h.in 에서 사용하였는데, cmake configuration을 통해 변수가 값으로 치환됩니다.
    5. add_definitions : global한 define을 선언합니다. -D<define문> 으로 띄어쓰기 없이 -D 바로 뒤에 붙여서 사용합니다.
      1. 이 값도 src/main.c에서 바로 참조해서 print문 으로 출력했습니다.
    6. include_directories : 포함할 헤더의 디렉토리를 지정합니다. 여러 경로를 한칸씩 띄어 이어붙일 수 있습니다.)
    7. file  : 사용할 파일들을 한개 변수에 포함시키는 정도 기능으로 보입니다.
      1. GLOB 키워드를 이용하면 *.c 와 같은 편리한 키워드를 사용 가능합니다.
      2. SRCS는 제가 사용한 변수입니다. 변경하셔도 됩니다.
    8. add_executable : 실행 파일을 만듭니다.
      1. <실행파일명> <소스> 순서로 파라미터에 넣습니다.
    9. install : 생성된 파일을 실제 install 시점에 어디에 놓을 지를 지정합니다.
      1. 실행 파일이므로 /usr/bin에 넣어 보았습니다.
      2. 앞에 TARGET 키워드가 붙는 것은 제가 의미 파악이 아직 잘 안되었습니다. 일단 빌드 결과물 앞에 붙여봤습니다.
      3. 앞에 PROGRAM 키워드가 붙으면 install 시 파일에 execute permission이 주어집니다.
      4. 앞에 LIBRARY 키워드가 붙으면 install 시 파일에 execute 없이, read permission이 주어집니다.
    10. if, elseif, else, endif
      1. 조금 생소한 형태의 if문입니다. 문법을 참조하며 작성하여야 합니다.
      2. 마지막 endif에도 처음 if에 사용한 것과 같은 조건문을 넣어줘야 합니다.
      3. 여기서 사용한 동작은 cmake 에서 사용자가 준 옵션 flag에 따라 다른 파일을 설치하게 해보았습니다.
    11. configure_file : 파일을 build 시점에 configuration 합니다.
      1. 지정된 변수를 값으로 치환하거나, 약속된 특정 파일을 빌드하거나 하는 등을 할 수 있습니다.
      2. 보통은 원본 파일에 .in 확장자를 붙여 놓았다가 configuration한 결과물에는 .in을 제거합니다.

  6. CMake 수행
    1. 보통은 "cmake ." 만 수행하면 되지만, 위에 configuration 동작을 보기 위해 변수를 입력하겠습니다.
    2. $cmake . -DFONT_COLOR="RED"
    3. 수행하면 configuration된 결과물들과 자동 생성된 Makefile 등을 볼 수 있습니다.

  7. make로 빌드
    1. $make

  8. make로 설치
    1. $sudo make install

  9. 결과 확인


  10. 결과물 삭제
    1. CMake는 아쉽게도 uninstall에 대한 설정을 제공하지 않습니다.
    2. 직접 지워줘야합니다.
    3. $sudo rm /usr/bin/hello-cmake /usr/bin/hello-configure



 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함