# find\_package() 사용법

#### find\_package()의 기본 개념

`find_package()`는 CMake에서 외부 라이브러리나 패키지를 찾아서 프로젝트에 포함시키기 위해 사용되는 명령어이다. 이 명령어는 주로 CMake 프로젝트에서 필요한 외부 종속성을 자동으로 탐지하고, 필요한 설정을 구성하는 데 사용된다.

#### find\_package()의 사용법

`find_package()` 명령어는 다음과 같은 형식을 갖는다:

```cmake
find_package(<PackageName> [version] [REQUIRED] [COMPONENTS components...])
```

* `<PackageName>`: 찾고자 하는 패키지의 이름이다. CMake는 이 이름을 기반으로 해당 패키지를 찾는다.
* `[version]`: 특정 버전을 지정할 수 있다. 지정된 버전 이상의 패키지를 찾도록 한다.
* `[REQUIRED]`: 이 옵션이 사용되면, 패키지를 찾지 못할 경우 CMake는 에러를 발생시킨다. 이 옵션이 없으면 패키지를 찾지 못해도 CMake는 계속 진행한다.
* `[COMPONENTS components...]`: 패키지 내에서 필요한 특정 컴포넌트를 지정할 수 있다.

#### Module 모드와 Config 모드

`find_package()`는 두 가지 모드로 동작할 수 있다: Module 모드와 Config 모드.

**Module 모드**

Module 모드는 CMake가 자체적으로 제공하거나 사용자가 정의한 Find 모듈을 사용하여 패키지를 찾는 방식이다. 예를 들어, `Find<PackageName>.cmake` 파일을 통해 패키지를 찾는다.

```cmake
find_package(Foo)
```

이 명령어는 `FindFoo.cmake` 파일을 CMake 모듈 경로에서 찾아 실행한다. 이 파일은 보통 환경 변수를 사용하여 패키지를 찾고, CMake 변수들을 설정한다.

**Config 모드**

Config 모드는 패키지 자체가 제공하는 `<PackageName>Config.cmake` 파일을 사용하는 방식이다. 이 방식은 보통 패키지 설치 과정에서 함께 설치되는 설정 파일을 사용한다.

```cmake
find_package(Foo CONFIG)
```

이 명령어는 `FooConfig.cmake` 파일을 패키지 설치 경로에서 찾아 실행한다. Config 모드는 보통 패키지의 버전 정보와 구성 설정이 포함된 파일을 제공한다.

#### REQUIRED 옵션

`REQUIRED` 옵션은 패키지가 반드시 필요할 때 사용된다. 이 옵션을 지정하면 패키지를 찾지 못할 경우 CMake는 오류를 발생시키고, 빌드가 중단된다.

```cmake
find_package(Foo REQUIRED)
```

이 명령어는 `Foo` 패키지가 시스템에 설치되어 있지 않으면 빌드를 중단시킨다.

#### COMPONENTS 옵션

`COMPONENTS` 옵션은 특정 패키지 내에서 필요한 구성 요소만을 선택적으로 불러올 수 있도록 한다.

```cmake
find_package(Foo COMPONENTS Bar Baz)
```

이 경우, `Foo` 패키지에서 `Bar`와 `Baz`라는 구성 요소만을 찾아 설정한다. 필요한 구성 요소가 모두 발견되지 않으면 CMake는 오류를 발생시킬 수 있다.

#### QUIET 및 NO\_MODULE 옵션

`QUIET` 옵션은 패키지를 찾지 못했을 때 경고 메시지를 억제한다. `NO_MODULE` 옵션은 Module 모드를 사용하지 않도록 강제한다.

```cmake
find_package(Foo QUIET NO_MODULE)
```

이 명령어는 `Foo` 패키지를 조용히 찾아보되, Module 모드는 사용하지 않도록 설정한다.

#### find\_package() 사용 시 변수 설정

`find_package()`는 패키지를 찾을 때 다양한 CMake 변수를 설정한다. 대표적인 변수는 다음과 같다:

* `<PackageName>_FOUND`: 패키지가 성공적으로 발견되었는지 여부를 나타낸다.
* `<PackageName>_INCLUDE_DIRS`: 패키지의 헤더 파일이 위치한 디렉터리 경로.
* `<PackageName>_LIBRARIES`: 패키지에 링크할 라이브러리 목록.

예를 들어, `find_package(Foo)`를 사용하면 `Foo_FOUND`, `Foo_INCLUDE_DIRS`, `Foo_LIBRARIES` 등의 변수가 설정될 수 있다.

#### Custom Find 모듈 작성

CMake가 제공하지 않는 패키지를 찾기 위해 사용자 정의 Find 모듈을 작성할 수 있다. 이 파일은 `Find<PackageName>.cmake` 형식을 따르며, CMake 모듈 경로에 위치시킨다.

```cmake

find_path(FOO_INCLUDE_DIR Foo.h)
find_library(FOO_LIBRARY NAMES foo)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo DEFAULT_MSG FOO_INCLUDE_DIR FOO_LIBRARY)

mark_as_advanced(FOO_INCLUDE_DIR FOO_LIBRARY)
```

이 예제는 `Foo.h` 헤더 파일과 `foo` 라이브러리를 찾아서 CMake 변수로 설정하는 간단한 Find 모듈이다.

#### 경로 설정 및 패키지 검색 순서

CMake는 `CMAKE_PREFIX_PATH` 등의 변수를 사용하여 패키지를 검색할 경로를 지정할 수 있다. 이 경로 변수는 패키지가 설치된 디렉토리를 지정하는 데 사용된다.

```cmake
set(CMAKE_PREFIX_PATH "/path/to/custom/dir")
```

이 경로에 따라 `find_package()`는 지정된 디렉토리에서 패키지를 찾는다. CMake는 기본적으로 시스템의 표준 경로를 먼저 검색하고, 그 후 사용자 정의 경로를 검색한다.

***

관련 자료:

* [CMake Documentation on find\_package](https://cmake.org/cmake/help/latest/command/find_package.html)
* \[Professional CMake: A Practical Guide by Craig Scott]
