# 재사용 가능한 CMake 코드 작성 방법

#### CMake 코드의 재사용성 이해

CMake에서 재사용 가능한 코드를 작성하는 것은 프로젝트의 유지보수성과 확장성을 높이는 데 매우 중요하다. 특히 대규모 프로젝트에서 여러 번 사용될 수 있는 코드를 모듈화하고 재사용할 수 있는 방법을 알면 전체 프로젝트의 구조를 더 간결하고 관리하기 쉽게 만들 수 있다.

#### 함수와 매크로를 사용한 코드 재사용

CMake에서는 코드 재사용성을 높이기 위해 함수와 매크로를 사용할 수 있다. 이 둘의 차이점을 이해하는 것이 중요하다.

**함수 정의 및 사용**

CMake 함수는 로컬 스코프를 가지며, 호출이 끝나면 로컬 변수는 파괴된다. 따라서, 함수는 다른 곳에 영향을 미치지 않고 안전하게 사용할 수 있다.

```cmake
function(print_message MESSAGE)
    message(STATUS "${MESSAGE}")
endfunction()

print_message("Hello, World!")
```

**매크로 정의 및 사용**

매크로는 텍스트 치환 방식으로 작동한다. 매크로는 함수와 달리 전역 변수의 스코프에 영향을 미칠 수 있으므로 주의가 필요하다.

```cmake
macro(print_message MESSAGE)
    message(STATUS "${MESSAGE}")
endmacro()

print_message("Hello, World!")
```

#### 변수와 옵션의 정의 및 재사용

변수와 옵션은 CMakeLists.txt 파일에서 설정을 중앙집중화하고 쉽게 재사용할 수 있게 한다.

**변수 사용**

변수는 프로젝트 내에서 반복적으로 사용되는 값들을 중앙에서 관리하기 위해 사용한다.

```cmake
set(PROJECT_NAME "MyProject")
project(${PROJECT_NAME})
```

**옵션 사용**

옵션은 사용자가 프로젝트를 구성하는 동안 특정 기능을 켜거나 끌 수 있게 한다.

```cmake
option(ENABLE_TESTS "Enable the tests" ON)

if(ENABLE_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()
```

#### 코드 모듈화와 `include()` 사용

코드 모듈화는 CMakeLists.txt 파일을 여러 개의 독립적인 파일로 나누어, 각 파일이 특정 작업을 수행하도록 하는 방법이다. 이는 `include()` 명령을 통해 구현할 수 있다.

```cmake
include(cmake/functions.cmake)
include(cmake/options.cmake)

project(MyProject)
```

```cmake
function(print_message MESSAGE)
    message(STATUS "${MESSAGE}")
endfunction()
```

```cmake
option(ENABLE_TESTS "Enable the tests" ON)
```

#### 패키지 및 모듈 검색

CMake는 `find_package()`를 사용해 외부 라이브러리나 모듈을 검색할 수 있다. 이를 통해 다른 프로젝트에서 사용되는 라이브러리를 쉽게 통합할 수 있다.

```cmake
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(MyExecutable ${OpenCV_LIBS})
```

#### 타겟 프로퍼티와 인터페이스 라이브러리

타겟 프로퍼티를 사용하면 특정 타겟에 속하는 빌드 설정이나 컴파일 옵션을 중앙에서 관리할 수 있다. 또한, 인터페이스 라이브러리를 사용해 다른 타겟에 영향을 미치는 설정을 관리할 수 있다.

```cmake
add_library(MyLib INTERFACE)
target_include_directories(MyLib INTERFACE include/)
target_compile_definitions(MyLib INTERFACE MYLIB_EXPORT)
```

#### 조건부 로직과 플랫폼 의존성 처리

조건부 로직을 사용해 특정 플랫폼이나 조건에 따라 다른 설정을 적용할 수 있다.

```cmake
if(WIN32)
    set(OS_SPECIFIC_LIBS ws2_32)
elseif(UNIX)
    set(OS_SPECIFIC_LIBS pthread)
endif()

target_link_libraries(MyExecutable ${OS_SPECIFIC_LIBS})
```

#### CMake 모듈 경로 설정

프로젝트 내에서 사용자 정의 모듈을 사용하려면 `CMAKE_MODULE_PATH`를 설정해 모듈을 찾을 경로를 지정할 수 있다.

```cmake
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
find_package(MyCustomModule REQUIRED)
```

***

관련 자료:

* [CMake Documentation](https://cmake.org/documentation/)
* [Mastering CMake](https://cmake.org/cmake/help/latest/manual/cmake.1.html)
