# 빌드 설정

#### 프로젝트 이름과 최소 요구 CMake 버전 설정

CMakeLists.txt 파일의 가장 첫 부분에는 프로젝트 이름과 최소 요구되는 CMake 버전을 설정할 수 있다.

```cmake
cmake_minimum_required(VERSION 3.10)
project(MyProject)
```

`cmake_minimum_required`는 CMake의 최소 버전을 지정한다. `project` 명령어는 프로젝트의 이름을 지정하며, 이후 프로젝트 이름이 변수로 사용될 수 있다.

#### 소스 파일과 헤더 파일 정의

프로젝트에서 사용될 소스 파일과 헤더 파일을 정의할 수 있다.

```cmake
set(SOURCES main.cpp file1.cpp file2.cpp)
set(HEADERS file1.h file2.h)
```

`set` 명령어를 사용하여 파일들을 변수로 지정할 수 있다. 이러한 변수는 이후 빌드 과정에서 사용된다.

#### 실행 파일 생성

CMakeLists.txt에서는 컴파일 후 생성될 실행 파일을 정의할 수 있다.

```cmake
add_executable(MyExecutable ${SOURCES}${HEADERS})
```

`add_executable` 명령어는 실행 파일을 생성하며, 첫 번째 인자로 실행 파일의 이름을, 두 번째 인자로 소스 파일과 헤더 파일을 지정한다.

#### 라이브러리 추가

프로젝트에서 사용하는 라이브러리를 추가할 수 있다. 외부 라이브러리를 사용하거나 직접 작성한 라이브러리를 추가할 수 있다.

```cmake
add_library(MyLibrary STATIC library.cpp library.h)
```

`add_library` 명령어를 사용하여 정적 라이브러리 또는 동적 라이브러리를 생성할 수 있다. 이때, `STATIC`은 정적 라이브러리, `SHARED`는 동적 라이브러리를 의미한다.

#### 라이브러리 링크

생성된 실행 파일이나 라이브러리에 다른 라이브러리를 링크할 수 있다.

```cmake
target_link_libraries(MyExecutable MyLibrary)
```

`target_link_libraries` 명령어는 특정 타겟(실행 파일이나 라이브러리)에 다른 라이브러리를 연결한다. 이 명령어는 CMakeLists.txt에서 매우 중요한 역할을 하며, 외부 라이브러리나 내부 라이브러리를 타겟에 연결하는 데 사용된다.

#### 컴파일러 옵션 설정

CMake는 컴파일러 옵션을 설정하는 기능도 제공한다. 이 옵션은 코드 최적화, 디버깅 정보 포함, 경고 제어 등을 위해 설정할 수 있다.

```cmake
target_compile_options(MyExecutable PRIVATE -Wall -Wextra -O2)
```

`target_compile_options` 명령어는 타겟에 대해 컴파일러 옵션을 설정한다. `PRIVATE`, `PUBLIC`, `INTERFACE` 중 하나를 사용하여 옵션의 가시성을 결정할 수 있다.

#### 디버그 및 릴리즈 설정

CMake에서는 디버그와 릴리즈 설정을 분리할 수 있다.

```cmake
set(CMAKE_BUILD_TYPE Debug)
```

`CMAKE_BUILD_TYPE`을 설정하여 디버그(`Debug`), 릴리즈(`Release`), 또는 기타 사용자 정의 빌드 유형을 지정할 수 있다.

#### 외부 패키지 찾기

CMake는 외부 패키지를 찾는 기능도 제공한다. 이를 통해 타사 라이브러리나 패키지를 쉽게 통합할 수 있다.

```cmake
find_package(OpenCV REQUIRED)
```

`find_package` 명령어는 외부 패키지를 찾고, 해당 패키지의 경로와 설정을 자동으로 구성한다. `REQUIRED` 옵션은 패키지가 필수적임을 의미하며, 찾지 못할 경우 에러를 발생시킨다.

#### 조건부 설정

프로젝트의 조건에 따라 설정을 달리할 수 있다.

```cmake
if(WIN32)
    set(OS_DEFINES "-D_WINDOWS")
elseif(UNIX)
    set(OS_DEFINES "-D_LINUX")
endif()
```

`if`, `elseif`, `endif` 명령어를 사용하여 특정 조건에 따라 다른 설정을 적용할 수 있다. 예를 들어, 운영 체제에 따라 다른 정의를 설정할 수 있다.

#### 설치 규칙 정의

프로젝트의 설치 규칙을 정의할 수 있다.

```cmake
install(TARGETS MyExecutable DESTINATION bin)
install(FILES "${PROJECT_SOURCE_DIR}/config.cfg" DESTINATION etc)
```

`install` 명령어를 사용하여 타겟 또는 파일을 특정 디렉토리에 설치할 수 있다. 이는 빌드된 파일을 적절한 위치에 배포하기 위해 사용된다.

#### 사용자 정의 명령어와 타겟

CMake는 사용자 정의 명령어나 타겟을 정의하는 기능도 제공한다.

```cmake
add_custom_command(TARGET MyExecutable POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy$<TARGET_FILE:MyExecutable> ${CMAKE_BINARY_DIR}/bin)
```

`add_custom_command` 명령어를 사용하여 빌드 후 특정 작업을 수행할 수 있다. 여기서는 빌드된 실행 파일을 특정 위치로 복사하는 예시이다.

***

관련 자료:

* [CMake Documentation](https://cmake.org/documentation/)
* [CMake Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/index.html)
