diff --git a/01-basic/H-third-party-library/CMakeLists.txt b/01-basic/H-third-party-library/CMakeLists.txt new file mode 100644 index 0000000..ef8b31a --- /dev/null +++ b/01-basic/H-third-party-library/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 2.8) + +# Set the project name +project (third_party_include) + + +# find a boost install with the libraries filesystem and system +find_package(Boost 1.54.0 REQUIRED COMPONENTS filesystem system) + +# check if boost was found +if(Boost_FOUND) + message ("boost found") + + # Include the boost headers + include_directories(${Boost_INCLUDE_DIRS}) +else() + message (FATAL_ERROR "Cannot find Boost") +endif() + +# Add an executable +add_executable(third_party_include main.cpp) + +# link against the boost libraries +target_link_libraries( third_party_include + ${Boost_SYSTEM_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} +) diff --git a/01-basic/H-third-party-library/README.adoc b/01-basic/H-third-party-library/README.adoc new file mode 100644 index 0000000..f2e9891 --- /dev/null +++ b/01-basic/H-third-party-library/README.adoc @@ -0,0 +1,178 @@ += Including Third Party Library + +:toc: +:toc-placement!: + +toc::[] + + +[[intro]] +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]] +Requirements +~~~~~~~~~~~~ + +This example requires the boost libraries to be installed in a default system +location. + +[[concepts]] +Concepts +~~~~~~~~ + +[[find_package]] +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. + + +[[include-found]] +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]] +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]] +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 + +---- diff --git a/01-basic/H-third-party-library/main.cpp b/01-basic/H-third-party-library/main.cpp new file mode 100644 index 0000000..c7b58af --- /dev/null +++ b/01-basic/H-third-party-library/main.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + std::cout << "Hello Third Party Include!" << std::endl; + + // use a shared ptr + boost::shared_ptr isp(new int(4)); + + // trivial use of boost filesystem + boost::filesystem::path path = "/usr/share/cmake/modules"; + if(path.is_relative()) + { + std::cout << "Path is relative" << std::endl; + } + else + { + std::cout << "Path is not relative" << std::endl; + } + + return 0; +}