Sometimes a developer wants to make sure compilation of a program doesn't fail even if user hasn't installed all the dependencies... With cmake it is easy to add optional packages that will only be built if the dependency hasn't been installed.
As an example, I will use ```libqrencode```, which uses header ```qrencode.h``` and shared library ```libqrencode.so```.
In your ```CMakeLists.txt```:
```
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(QRencode)
if(QRENCODE_FOUND)
include_directories(SYSTEM ${QRENCODE_INCLUDE_DIRS})
else()
include_directories(libqrencode)
set(WITH_TESTS NO)
set(WITH_TOOLS NO)
add_subdirectory(libqrencode)
endif()
```
```CMAKE_MODULE_PATH``` tells cmake where to find custom cmake modules. ```find_package()``` loads ```FindQRencode.cmake``` from directory specified in ```CMAKE_MODULE_PATH```.
```QRENCODE_FOUND``` is set if ```FindQRencode.cmake``` finds ```libqrencode```. If it is not found, the ```else()``` block will add embedded ```libqrencode``` sources from directory ```libqrencode``` under ```CMAKE_CURRENT_SOURCE_DIR```. Any unnecessary build steps can be disabled before calling ```add_subdirectory()```. In this example we disabled building "tests" and "tools".
In ```cmake/FindQRencode.cmake```:
```
find_path(QRENCODE_ROOT_DIR
NAMES include/qrencode.h
)
find_library(QRENCODE_LIBRARIES
NAMES qrencode
HINTS ${QRENCODE_ROOT_DIR}/lib
)
find_path(QRENCODE_INCLUDE_DIRS
NAMES qrencode.h
HINTS ${QRENCODE_ROOT_DIR}/include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(QRencode DEFAULT_MSG
QRENCODE_LIBRARIES
QRENCODE_INCLUDE_DIRS
)
mark_as_advanced(
QRENCODE_ROOT_DIR
QRENCODE_LIBRARIES
QRENCODE_INCLUDE_DIRS
)
```
```QRENCODE_ROOT``` is used to find both header and library. It can be specified in cmake command line if libqrencode is installed in non-standard location.
```QRENCODE_LIBRARIES``` contains full path of qrencode library (libqrencode.so.3 or libqrencode.so.4 on Linux).
```QRENCODE_INCLUDE_DIRS``` contains path for the header qrencode.h.
"QRencode" is the package name, as seen in ```find_package()``` and ```find_package_handle_standard_args()```.
"qrencode" is base name of the library... On Linux and most Unix-like systems it is usually prepended with "lib" and appended with ".so" (shared library) or ".a" (static library). Shared library name can also contain version number (.3 or .4 for ```libqrencode```).
```find_package_handle_standard_args()``` sets ```QRENCODE_FOUND``` variable if the specified variables have been set.
```mark_as_advanced()``` will hide the variable names unless user explicitly asks to show "advanced" variables.