How to add FindPackage() script for libraries not already supported by cmake.
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.