cmake - 2

2021. 9. 8. 23:31

1)
CMake
 - Makefile을(정확히는 Makefile과 같은 빌드 파일을) 자동으로 생성하는 프로그램
   즉, 최종 빌드는 Makefile을 기반으로 make 명령으로 수행해야 한다
 - 의존성 정보를 일일이 기술하지 않아도 Makefile을 생성한다
   즉, CMake는 소스파일 내부까지 분석하여 의존성 정보를 스스로 파악한다
 - CMake를 이용하기 위해서는 빌드 스크립트(CMakeList.txt)를 작성해야한다
    ** Makefile은 바이너리를 생성하기 위한 빌드 스크립트, CMakeList.txt는 Makefile을 생성하기 위한 빌드 스크립트
 - 범용 IDE(이클립스, 비주얼 등)에서 기타 설정파일로 등록하여 사용할 수 있다.
 - cmake 또한 make처럼 역사가 오래되었는 만큼 cmake 버전에 따른 사용문법의 차이가 있다


2)
cmake 실행 시 명령어를 실행한 장소에 생성되는 파일들
 - 파일: Makefile, CMakeCache.txt, cmake_install.cmake
 - 디렉터리: CMakeFiles


----- CMakeList.txt 리스트 만들기 -----
3)
프로젝트 기본 선언
 - cmake_minimum_required(VERSION 버전)
   : cmake의 버전에 따른 문법차이가 있기 때문에(즉, 의존성이 있기 때문에) cmake스크립트를 실행시키기 위한 최소버전을 명기해야한다
     보통 CMakeLists.txt의 최상단에 선언한다
     버전의 경우 메이저 버전인 정수(소수점 앞)는 반드시 적어야하고 마이너 버전인 소수점이하는 생략이 가능하다

 - project(프로젝트명)
   : 프로젝트명 설정, 해당 프로젝트명은 CMAKE_PROJECT_NAME 예약변수에 저장된다

 - CMAKE_BUILD_TYPE 
   : cmake 스크립트를 실행하여 make파일을 빌드하기 위한 빌드 형상 정보가 저장된 예약변수
      = Debug : 디버깅, Release : 배포, RelWithDebInfo : 배포설정+디버깅정보, MinSizeRel : 최소 크기로 빌드


4)
변수 정의
 - '값'을 선언 시 공백이 있으면 ""로 묶는다
 - set(변수명 값)
 - set(목록명 목록구성항목1 목록구성항목2 목록구성항목3 ...)

변수 참조(변수 사용)
 - $변수명, ${변수명}

** 예약변수
 - cmake에 미리 설정되어 있는 예약변수들의 값을 set() 명령으로 변경이 가능하다


메세지 출력
 - message(타입 메세지)
   : 스크립트를 실행하며 해당 라인에 왔을 때 해당정보를 출력한다
      = STATUS : 상태메세지 출력('--'와 함께 메세지가 출력됨)
      = WARNING : 경고 메세지
      = AUTHOR_WARNING : 스크립트 개발자용 경고 메세지
      = SEND_ERROR : 오류 메세지, 오류가 나도 계속 진행하지만 결과물(Makefile)은 생성하지 않음
      = FATAL_ERROR : 오류 메세지, 빌드작업을 즉시 중단
  ** 타입 생략시 중요 정보를 나타내는 메세지로 구분하여 출력
  ** 주의사항 : Makefile 실행 시가 아닌 cmake로 Makefile을 생성할 때 출력되는 메세지이다

주석 
 - #
   : Makefile과 같다

5)
타겟 설정
 - 타겟(target)이란 스크립트 실행(CMakeList.txt)이 완료되고 최종적으로 생성되는 실행파일과 라이브러리들을 의미한다

 - add_executable(바이너리명 소스파일1 소스파일2 ..)
   : 빌드로 생성할 최종 결과물(타겟)로 바이너리를 추가
     '바이너리명'을 생성하기 위해 소스파일들이 필요하다

 - add_library(라이브러리명 옵션 소스파일1 소스파일2 ..)
   : 빌드로 생성할 최종 결과물(타겟)로 라이브러리를 추가
     '라이브러리명'을 생성하기 위해 소스파일들이 필요하다
   : 옵션으로 STATIC, SHARED, MODULE가 있다
     ** STATIC, SHARED, MODULE
        - 생성할 라이브러리의 종류를 명시하는 옵션
           STATIC : 정적라이브러리(.a)
           SHARED : 동적라이브러리(.so)
           MODULE : 동적으로 링크되지 않고, (dlopen()과 같은 함수를 사용하여)런타임 시 불러오는 라이브러리를 생성



 - add_custom_target(타겟이름 [ALL]
                     COMMENT 메세지
                     DEPENDS 의존대상목록
                     WORKING_DIRECTORY 디렉토리
                     COMMAND 명령
                     [VERATIM]
                     SOURCE 소스목록)
   : 통상적인 빌드 절차로 생성할 수 없는 Target을 추가
     (공식 메뉴얼에서는 현재 스크립트의 내용으로 생성할수 없는 타겟에 대해 정의한다고 되어있다)
     항상 'Outdated'로 간주되므로 해당 명령어는 매 빌드마다 실행된다
   ** SOURCE 옵션: 사용자 정의 타겟을 빌드하기 위한 추가 소스파일 지정

 - add_dependencies(타겟명 의존대상1 의존대상2 ..)
   : Top-Level Target간의 의존성을 지정
     '타겟명'을 빌드하기 위한 의존대상이 Outdated 조건일 경우 의존대상을 먼저 빌드한다
   : 해당 명령어는 보통 Top-Level Target을 정의하는 명령어에서 묵시적으로 수행하기 때문에
     cmake에서 파악 할 수 없는 의존대상을 명시할 때 사용한다
   ** Top-Level Target: ADD_EXECUTABLE, ADD_LIBRARY, ADD_CUSTOM_TARGET 명령으로 추가한 Target

 - install(TARGETS 타겟목록
           RUNTIME_DESTINATION 바이너리설치경로
           LIBRARY_DESTINATION 라이브러리설치경로
           ARCHIVE_DESTINATION 아카이브설치경로 )
   : Makefile을 사용해 make install명령을 실행할 때 동작하는 방식을 정의하는 명령어
   ** 리눅스에서 설치는 빌드된 바이너리와 파일들을 특정디렉터리에 위치시키는 동작이다
   ** CMAKE_INSTALL_PREFIX 
       make install(설치 매크로 명령)에서 타겟을 설치할 Base 디렉토리(정확히는 타겟을 복사할 디렉토리)를 지정.
       install 명령에서 상대경로 사용 시 './'에 해당하는 경로가 된다.(절대경로는 지정되어 있으니 사용하지 않겠지..)


6)
타겟 전체를 대상으로 하는 옵션
 - ADD_COMPILE_OPTIONS(옵션들)
   : 스크립트 전체에서(타겟 전체에서) 컴파일을 위한 컴파일러에 해당 옵션을 추가한다
   ** CMAKE_C_FLAGS_빌드옵션
    - '빌드 옵션'에 해당하는 컴파일을 진행할 때 사용하는 '컴파일' 옵션을 지정할 수 있는 매크로변수
      ex) SET(CMAKE_C_FLAGS_RELEASE "-g -Wall")

 - ADD_DEFINITIONS(-D매크로1 -D매크로2 ..)
   : 전처리기에 전달할 메크로를 정의하는 명령어(gcc의 -D옵션과 같다)

 - INCLUDE_DIRECTORIES(디렉토리1 디렉토리2 ..)
   : 헤더파일의 경로를 추가하는 명령어(gcc의 -I옵션과 같다)

 - LINK_DIRECTORIES(디렉토리1 디렉토리2 ..)
   : 라이브러리의 경로를 추가하는 명령어(gcc의 -L옵션과 같다)

 - LINK_LIBRARIES(라이브러리1 라이브러리2 ..)
   : 링크시 사용할 라이브러리 목록을 지정하는 명령어
     라이브러리 파일명의 Prefix 및 Postfix는 제외하고 라이브러리 이름만 입력한다
   ** CMAKE_EXE_LINKER_FLAGS_빌드옵션
      - 특정 빌드 옵션에서 사용할 '링크'옵션 지정할 수 있는 매크로 변수


** 기타 매크로
 - RUNTIME_OUTPUT_DIRECTORY 
   : 빌드 이후 생성된 바이너리를 저장할 디렉토리 값(경로)이 저장되어 잇는 변수

 - LIBRARY_OUTPUT_DIRECTORY 
   : 빌드 이후 생성된 라이브러리를 저장할 디렉토리 값(경로)이 저장되어 잇는 변수

 - ARCHIVE_OUTPUT_DIRECTORY 
   : 빌드 이후 생성된 아카이브(=static라이브러리)를 저장할 디렉토리 값(경로)이 저장되어 잇는 변수


7)
특정 타겟을 대상으로 하는 옵션
 - TARGET_COMPILE_OPTIONS(타겟명 <INTERFACE|PUBLIC|PRIVATE> 옵션1 옵션2 ..)
   : 특정 타겟을 컴파일하기 위한 컴파일러에 옵션을 추가한다
   ** <INTERFACE|PUBLIC|PRIVATE>
       - 컴파일 옵션 변수는 뒤에 이어져오는 옵션들의 범위를 지정한다.
         보통 PUBLIC 을 사용하며, 그 외에 INTERFACE, PRIVATE이 있다.
       - PUBLIC과 PRIVATE의 차이 
         : '해당 옵션으로 생성한 라이브러리(A)'를 다른 타겟(B) 생성시 사용(참조)할 경우
           PUBLIC 옵션은 기존 라이브러리(A)의 컴파일 옵션과 헤더파일 탐색 디렉토리 목록을 사용하며,
           PRIVATE 옵션은 사용하지 않는다.
           (즉, PRIVATE 옵션의 경우 기존 라이브러리(A)를 생성하기 위해서만 사용하고 참조하는 타겟(B)에서는 해당 옵션들을 사용하지 않는다)
       - 참조1: https://cmake.org/cmake/help/v2.8.12/cmake.html#command:target_compile_options
         참조2: https://cmake.org/cmake/help/latest/command/target_compile_options.html

 - TARGET_COMPILE_DEFINITIONS(타겟명 <INTERFACE|PUBLIC|PRIVATE> 매크로1 매크로2 매크로3=값 ..)
   : 특정 타겟을 컴파일할 때 전처리기에 전달할 메크로를 정의하는 명령어(gcc의 -D옵션과 같다)
     ADD_DEFINITIONS()와는 달리, 매크로를 지정할 때 -D는 생략이 가능하다(없어도 자동으로 추가됨)

 - TARGET_INCLUDE_DIRECTORIES(타겟명 <INTERFACE|PUBLIC|PRIVATE> 디렉토리1 디렉토리2 ..)
   : 특정 타겟을 컴파일하기 위한 헤더파일의 경로를 추가하는 명령어(gcc의 -I옵션과 같다)

 - TARGET_LINK_LIBRARIES(타겟명 라이브러리1 라이브러리2 ..)
   : 특정 타겟을 생성하기 위한 링크시 사용할 라이브러리 목록을 지정하는 명령어
     라이브러리 파일명의 Prefix 및 Postfix는 제외하고 라이브러리 이름만 입력한다
     TARGET_COMPILE_DEFINITIONS와 같이 -l옵션이 없어도 자동으로 추가된다

** TARGET_LINK_LIBRARIES에서 <INTERFACE|PUBLIC|PRIVATE> 사용이 가능하다
 - PUBLIC : 참조하는 라이브러리를 헤더파일과 내부 구현에도 모두 사용한다
 - PRIVATE : 참조하는 라이브러리를 내부 구현에만 사용한다
 - INTERFACE :  참조하는 라이브러리를 헤더파일에만 사용한다


8)
빌드 관련 옵션
 - CONFIGURE_FILE(템플릿파일명 출력파일명)
   : 타겟 빌드 시작 전, 템플릿 파일의 내용에서 ${변수명}, @변수명@이라 정의된 변수명과 CMakeLists.txt에서 선언된 변수명을 비교하여,
     일치하는 변수를 CMakeLists.txt에 선언된 변수명의 값으로 치환하여 출력파일명으로 생성한다
   : 컴파일러를 실행하기 전 단계에서 수행된다(블로그에서는 전전처리과정이라고 표현한다..)
   : 보통 프로그램 버전 명시와 같이 빌드 직전에 파일내용의 최신화를 자동으로 수행하기 위해 사용한다

 - ADD_CUSTOM_COMMAND( OUTPUT 출력파일목록
                       COMMENT 출력메세지
                       DEPENDS 의존대상목록
                       WORKING_DIRECTORY 작업디렉토리
                       COMMAND 명령
                       ...)
   : ADD_CUSTOM_TARGET() 명령어에서 '타겟파일 목록이 최신이 아닐 경우에만 명령을 실행한다' 조건이 추가된 명령어
   : 명령어를 실행하기 위해 출력파일목록의 파일들 중 최소한 한 개 이상의 출력파일이 미리 생성되어야 한다.(그래야 최신인지를 확인하니까)

 - ADD_CUSTOM_COMMAND( TARGET 대상타겟명
                       <PRE_BUILD|PRE_LINK|POST_BUILD>
                       COMMENT 출력메세지
                       WORKING_DIRECTORY 작업디렉토리
                       COMMAND 명령
                       ...)
   : 특정 타겟의 빌드 시기에 따라 수행할 명령을 추가하는 명령어
   ** <PRE_BUILD|PRE_LINK|POST_BUILD>
      - PRE_BUILD : 타겟을 생성하는 모든 종속성보다 해당 명령어를 먼저 실행
      - PRE_LINK : 타겟을 생성하는 다른 종속성들이 생성된 이후에 명령어를 실행
      - POST_BUILD : 타겟이 빌드된 후 명령어 실행


9)
기타
 - FetchContent 모듈
   : 외부 콘텐츠(라이브러리)을 사용할 수 있는 기능을 제공하는 모듈
     CMake 를 실행하는 시점에 동작한다
   : 사용법
     - include(FetchContent) : FetchContent 모듈 호출
     - FetchContent_Declare(
                            콘텐츠이름
                            GIT_REPOSITORY "콘텐츠가있는깃경로"
                            GIT_TAG "해당콘텐츠의버전"
                           )
        : 사용할 콘텐츠 선언
     - FetchContent_MakeAvailable(콘텐츠이름) : 해당 콘텐츠 사용
   ** FetchContent를 사용하기 위해서는 적어도 3.11 이상 버전의 CMake를 사용해야 한다고 한다.
      (그 이전에는 ExternalProject 모듈을 사용하면 되며, ExternalProject 모듈은 타겟의 빌드 시점에 호출된다는 차이가 있다)
   ** 참조
      - https://cmake.org/cmake/help/latest/module/FetchContent.html


 - Make 이외의 빌드 시스템 사용하기
   : cmake는 기본적으로 make를 사용하여 빌드를 수행하며, 이를 바꾸기 위해서는 아래의 명령을 콘솔창(CLI)에서 사용한다
      > cmake .. -DCMAKE_GENERATOR=빌드프로그램명
   ** 빌드 프로그램의 예
      - "Unix Makefiles"
        -> 리눅스에서 사용하는 디폴트 빌드프로그램(빌드시스템)
      - "Visual Studio 16 2019"
   ** 참조
      - https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html


 - 그 밖에 if 문을 사용할 수 있으며, NOT, ANR 등을 지원한다
   ** 참조
      - https://cmake.org/cmake/help/v3.0/manual/cmake-language.7.html#control-structures

'Study > utilities' 카테고리의 다른 글

vscode 배우기  (0) 2023.03.24
cmake - 3(강의정리)  (0) 2023.02.21
cmake - 1  (0) 2021.09.01
make - 2  (0) 2021.08.22
make - 1  (0) 2021.08.22

+ Recent posts