= Including Third Party Library
:toc:
:toc-placement!:

toc::[]

# Introduction

Nearly all non-trivial projects will have a requirement for including third party
libraries, headers, or programs. CMake has support for finding the path to these tools using
the `find_package()` function. This will search for CMake modules in the format
"FindXXX.cmake" from the list of folders in `CMAKE_MODULE_PATH`. On linux the
default search path will include `/usr/share/cmake/Modules`. On my system this
includes support for approximately 142 common third party libraries.


The files in this tutorial are below:

```
$ tree
.
├── CMakeLists.txt
├── main.cpp
```

  * CMakeLists.txt - Contains the CMake commands you wish to run
  * main.cpp - The source file with main

# Requirements

This example requires the boost libraries to be installed in a default system
location.

# Concepts

## Finding a Package

As mentioned above the `find_package()` function will search for CMake modules in the formant
"FindXXX.cmake" from the list of folders in `CMAKE_MODULE_PATH`. The exact
format of the arguments to `find_package` will depend on the module you are looking
for. This is typically documented at the top of the `FindXXX.cmake` file.

A basic example of finding boost is below:

[source,cmake]
----
find_package(Boost 1.54.0 REQUIRED COMPONENTS filesystem system)
----

The arguments are:

  * Boost - Name of the library. This is part of used to find the module file FindBoost.cmake
  * 1.54.0 - The minimum version of boost to find
  * REQUIRED - Tells the module that this is required and to fail it it cannot be found
  * COMPONENTS - The list of libraries to find.

Boost includes can take more arguments and also make use of other variables.
More complex setups are provided in later examples.


## Checking if the package is found

Most included packages will set a variable `XXX_FOUND`, which can used to check
if the package is available on the system.

In this example the variable is `Boost_FOUND`:

[source,cmake]
----
if(Boost_FOUND)
    message ("boost found")
    include_directories(${Boost_INCLUDE_DIRS})
else()
    message (FATAL_ERROR "Cannot find Boost")
endif()
----

## Exported Variables

After a package is found it will often export variables which can inform the user
where to find the library, header, or executable files. Similar to the `XXX_FOUND`
variable, these are package specific and are typically documented at the top of the
`FindXXX.cmake` file.

The variables exported in this example include:

  * `Boost_INCLUDE_DIRS` - The path to the boost header files.
  * `Boost_SYSTEM_LIBRARY` - The path to the boost system library.
  * `Boost_FILESYSTEM_LIBRARY` - The path to the boost filesystem library.

In some cases you can also check these variables by examining the cache using
ccmake or cmake-gui.

# Building the Example

[source,bash]
----
$ mkdir build

$ cd build/

$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.54.0
-- Found the following Boost libraries:
--   filesystem
--   system
boost found
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/H-third-party-library/build

$ make
Scanning dependencies of target third_party_include
[100%] Building CXX object CMakeFiles/third_party_include.dir/main.cpp.o
Linking CXX executable third_party_include
[100%] Built target third_party_include
matrim@freyr:~/workspace/cmake-examples/01-basic/H-third-party-library/build$ ./
CMakeFiles/          third_party_include
matrim@freyr:~/workspace/cmake-examples/01-basic/H-third-party-library/build$ ./third_party_include
Hello Third Party Include!
Path is not relative
$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.54.0
-- Found the following Boost libraries:
--   filesystem
--   system
boost found
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/H-third-party-library/build

$ make
Scanning dependencies of target third_party_include
[100%] Building CXX object CMakeFiles/third_party_include.dir/main.cpp.o
Linking CXX executable third_party_include
[100%] Built target third_party_include

$ ./third_party_include
Hello Third Party Include!
Path is not relative

----
