cmake: add auto-detection, improve library search

Add auto-detection to the most important features (app, hpack, etc.).
Move options to a separate file for easier search.

Add cmake-based Libevent, jansson and CUnit search. Move pkg-config
handling for Libev and jemalloc to their cmake files.

Note: duplicates find_package before including CMakeOptions.txt and when
checking for features. Maybe that can be cleaned up later...
This commit is contained in:
Peter Wu 2016-02-15 01:12:07 +01:00
parent c96cf1b303
commit cc92ebf471
8 changed files with 321 additions and 69 deletions

View File

@ -42,26 +42,30 @@ HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR}
include(GNUInstallDirs)
# XXX "check" is treated as "OFF" now, consider detecting it first
option(ENABLE_WERROR "Turn on compile time warnings")
option(ENABLE_DEBUG "Turn on debug output")
option(ENABLE_THREADS "Turn on threading in apps" ON)
option(ENABLE_APP "Build applications (nghttp, nghttpd, nghttpx and h2load)"
check)
option(ENABLE_HPACK_TOOLS "Build HPACK tools" check)
option(ENABLE_ASIO_LIB "Build C++ libnghttp2_asio library")
option(ENABLE_EXAMPLES "Build examples" check)
option(ENABLE_PYTHON_BINDINGS "Build Python bindings" check)
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
# Auto-detection of features that can be toggled
find_package(OpenSSL 1.0.1 QUIET)
find_package(Libev 4.15 QUIET)
find_package(ZLIB 1.2.3 QUIET)
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
set(ENABLE_APP_DEFAULT ON)
else()
set(ENABLE_APP_DEFAULT OFF)
endif()
find_package(Jansson 2.5 QUIET)
set(ENABLE_HPACK_TOOLS_DEFAULT ${JANSSON_FOUND})
find_package(Libevent 2.0.8 QUIET COMPONENTS openssl)
set(ENABLE_EXAMPLES_DEFAULT ${LIBEVENT_OPENSSL_FOUND})
# XXX auto-detect python
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
option(WITH_LIBXML2 "Use libxml2" check)
option(WITH_JEMALLOC "Use jemalloc" check)
option(WITH_SPDYLAY "Use spdylay" check)
option(WITH_MRUBY "Use mruby")
option(WITH_NEVERBLEED "Use neverbleed")
set(CYTHON_PATH "" CACHE PATH "Use cython in given path")
set(CYTHON "" CACHE FILEPATH "The Cython executable")
find_package(LibXml2 QUIET)
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
find_package(Jemalloc QUIET)
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
find_package(SPDYLAY QUIET)
set(WITH_SPDYLAY_DEFAULT ${SPDYLAY_FOUND})
include(CMakeOptions.txt)
find_package(PkgConfig 0.20)
# For Python bindings and documentation
@ -153,19 +157,16 @@ endif()
# # android does not need -pthread, but needs followng 3 libs for C++
# APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
pkg_check_modules(ZLIB zlib>=1.2.3)
if(ZLIB_FOUND)
set(HAVE_ZLIB 1)
else()
set(HAVE_ZLIB 0)
endif()
# dl: openssl requires libdl when it is statically linked.
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
# APP_LIBRARIES if it is really specific to OpenSSL?
# XXX put this in FindCUNIT.cmake
pkg_check_modules(CUNIT cunit>=2.1)
find_package(CUnit 2.1)
if(CUNIT_FOUND)
set(HAVE_CUNIT 1)
else()
set(HAVE_CUNIT 0)
endif()
# # If pkg-config does not find cunit, check it using AC_CHECK_LIB. We
# # do this because Debian (Ubuntu) lacks pkg-config file for cunit.
# if test "x${have_cunit}" = "xno"; then
@ -193,35 +194,44 @@ pkg_check_modules(CUNIT cunit>=2.1)
#
# AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
if(ENABLE_APP)
find_package(OpenSSL 1.0.1 REQUIRED)
find_package(Libev 4.15 REQUIRED)
find_package(ZLIB 1.2.3 REQUIRED)
endif()
# openssl (for src)
if(OPENSSL_FOUND)
set(HAVE_OPENSSL 1)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
else()
set(HAVE_OPENSSL 0)
endif()
# libev (for src)
find_package(Libev)
if(Libev_FOUND)
if(LIBEV_FOUND)
set(HAVE_LIBEV 1)
else()
set(HAVE_LIBEV 0)
endif()
# openssl (for src)
pkg_check_modules(OPENSSL openssl>=1.0.1)
# for find_package, replace OPENSSL_INCLUDE_DIRS by OPENSSL_INCLUDE_DIR
#find_package(OpenSSL 1.0.1)
if(OPENSSL_FOUND)
set(HAVE_OPENSSL 1)
if(ZLIB_FOUND)
set(HAVE_ZLIB 1)
else()
set(HAVE_OPENSSL 0)
set(HAVE_ZLIB 0)
endif()
if(ENABLE_EXAMPLES)
# libevent_openssl (for examples)
# 2.0.8 is required because we use evconnlistener_set_error_cb()
pkg_check_modules(LIBEVENT_OPENSSL libevent_openssl>=2.0.8)
if(LIBEVENT_OPENSSL_FOUND)
find_package(Libevent 2.0.8 REQUIRED COMPONENTS libevent openssl)
set(LIBEVENT_OPENSSL_LIBRARIES ${LIBEVENT_LIBRARIES})
set(HAVE_LIBEVENT_OPENSSL 1)
else()
set(HAVE_LIBEVENT_OPENSSL 0)
endif()
if(ENABLE_HPACK_TOOLS)
# jansson (for src/nghttp, src/deflatehd and src/inflatehd)
pkg_check_modules(JANSSON jansson>=2.5)
if(JANSSON_FOUND)
find_package(Jansson 2.5 REQUIRED)
set(HAVE_JANSSON 1)
else()
set(HAVE_JANSSON 0)
@ -231,17 +241,13 @@ endif()
if(WITH_LIBXML2)
find_package(LibXml2 2.7.7 REQUIRED)
set(HAVE_LIBXML2 1)
# XXX fail if WITH_LIBXML2=ON
else()
set(HAVE_LIBXML2 0)
endif()
# jemalloc
if(WITH_JEMALLOC)
pkg_check_modules(JEMALLOC jemalloc)
if(NOT JEMALLOC_FOUND)
find_package(jemalloc REQUIRED)
endif()
find_package(Jemalloc REQUIRED)
if(JEMALLOC_FOUND)
set(HAVE_JEMALLOC 1)
else()
@ -281,7 +287,7 @@ endif()
# C++ library libnghttp2_asio
if(ENABLE_EXAMPLES AND NOT (OPENSSL_FOUND AND LIBEVENT_OPENSSL_FOUND))
message(FATAL_ERROR "examples were requested (--enable-examples) but dependencies are not met.")
message(FATAL_ERROR "examples were requested (ENABLE_EXAMPLES=1) but dependencies are not met.")
endif()
# third-party http-parser only be built when needed

29
CMakeOptions.txt Normal file
View File

@ -0,0 +1,29 @@
# Features that can be enabled for cmake (see CMakeLists.txt)
option(ENABLE_WERROR "Turn on compile time warnings")
option(ENABLE_DEBUG "Turn on debug output")
option(ENABLE_THREADS "Turn on threading in apps" ON)
option(ENABLE_APP "Build applications (nghttp, nghttpd, nghttpx and h2load)"
${ENABLE_APP_DEFAULT})
option(ENABLE_HPACK_TOOLS "Build HPACK tools"
${ENABLE_HPACK_TOOLS_DEFAULT})
option(ENABLE_ASIO_LIB "Build C++ libnghttp2_asio library")
option(ENABLE_EXAMPLES "Build examples"
${ENABLE_EXAMPLES_DEFAULT})
option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
${ENABLE_PYTHON_BINDINGS_DEFAULT})
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
option(WITH_LIBXML2 "Use libxml2"
${WITH_LIBXML2_DEFAULT})
option(WITH_JEMALLOC "Use jemalloc"
${WITH_JEMALLOC_DEFAULT})
option(WITH_SPDYLAY "Use spdylay"
${WITH_SPDYLAY_DEFAULT})
option(WITH_MRUBY "Use mruby")
option(WITH_NEVERBLEED "Use neverbleed")
set(CYTHON_PATH "" CACHE PATH "Use cython in given path")
set(CYTHON "" CACHE FILEPATH "The Cython executable")
# vim: ft=cmake:

40
cmake/FindCUnit.cmake Normal file
View File

@ -0,0 +1,40 @@
# - Try to find cunit
# Once done this will define
# CUNIT_FOUND - System has cunit
# CUNIT_INCLUDE_DIRS - The cunit include directories
# CUNIT_LIBRARIES - The libraries needed to use cunit
find_package(PkgConfig QUIET)
pkg_check_modules(PC_CUNIT QUIET cunit)
find_path(CUNIT_INCLUDE_DIR
NAMES CUnit/CUnit.h
HINTS ${PC_CUNIT_INCLUDE_DIRS}
)
find_library(CUNIT_LIBRARY
NAMES cunit
HINTS ${PC_CUNIT_LIBRARY_DIRS}
)
if(CUNIT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+CU_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${CUNIT_INCLUDE_DIR}/CUnit/CUnit.h"
CUNIT_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
CUNIT_VERSION "${CUNIT_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set CUNIT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(CUnit REQUIRED_VARS
CUNIT_LIBRARY CUNIT_INCLUDE_DIR
VERSION_VAR CUNIT_VERSION)
if(CUNIT_FOUND)
set(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
set(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
endif()
mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)

40
cmake/FindJansson.cmake Normal file
View File

@ -0,0 +1,40 @@
# - Try to find jansson
# Once done this will define
# JANSSON_FOUND - System has jansson
# JANSSON_INCLUDE_DIRS - The jansson include directories
# JANSSON_LIBRARIES - The libraries needed to use jansson
find_package(PkgConfig QUIET)
pkg_check_modules(PC_JANSSON QUIET jansson)
find_path(JANSSON_INCLUDE_DIR
NAMES jansson.h
HINTS ${PC_JANSSON_INCLUDE_DIRS}
)
find_library(JANSSON_LIBRARY
NAMES jansson
HINTS ${PC_JANSSON_LIBRARY_DIRS}
)
if(JANSSON_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+JANSSON_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${JANSSON_INCLUDE_DIR}/jansson.h"
JANSSON_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
JANSSON_VERSION "${JANSSON_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JANSSON_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(jansson REQUIRED_VARS
JANSSON_LIBRARY JANSSON_INCLUDE_DIR
VERSION_VAR JANSSON_VERSION)
if(JANSSON_FOUND)
set(JANSSON_LIBRARIES ${JANSSON_LIBRARY})
set(JANSSON_INCLUDE_DIRS ${JANSSON_INCLUDE_DIR})
endif()
mark_as_advanced(JANSSON_INCLUDE_DIR JANSSON_LIBRARY)

View File

@ -4,16 +4,37 @@
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h)
find_library(JEMALLOC_LIBRARY NAMES jemalloc)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
find_path(JEMALLOC_INCLUDE_DIR
NAMES jemalloc/jemalloc.h
HINTS ${PC_PCJEMALLOC_INCLUDE_DIRS}
)
find_library(JEMALLOC_LIBRARY
NAMES jemalloc
HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
)
if(JEMALLOC_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc/jemalloc.h"
JEMALLOC_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
JEMALLOC_VERSION "${JEMALLOC_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(jemalloc DEFAULT_MSG
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR)
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(jemalloc REQUIRED_VARS
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR
VERSION_VAR JEMALLOC_VERSION)
if(JEMALLOC_FOUND)
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
endif()
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)

View File

@ -4,20 +4,35 @@
# LIBEV_INCLUDE_DIRS - The libev include directories
# LIBEV_LIBRARIES - The libraries needed to use libev
find_path(LIBEV_INCLUDE_DIR ev.h)
find_library(LIBEV_LIBRARY NAMES ev)
find_path(LIBEV_INCLUDE_DIR
NAMES ev.h
)
find_library(LIBEV_LIBRARY
NAMES ev
)
# Assume that the discovered "ev" library contains ev_time
#include(CheckLibraryExists)
#CHECK_LIBRARY_EXISTS(ev ev_time "" HAVE_LIBEV)
set(LIBEV_LIBRARIES ${LIBEV_LIBRARY})
set(LIBEV_INCLUDE_DIRS ${LIBEV_INCLUDE_DIR})
if(LIBEV_INCLUDE_DIR)
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
LIBEV_VERSION_MAJOR REGEX "^#define[ \t]+EV_VERSION_MAJOR[ \t]+[0-9]+")
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
LIBEV_VERSION_MINOR REGEX "^#define[ \t]+EV_VERSION_MINOR[ \t]+[0-9]+")
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MAJOR "${LIBEV_VERSION_MAJOR}")
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MINOR "${LIBEV_VERSION_MINOR}")
set(LIBEV_VERSION "${LIBEV_VERSION_MAJOR}.${LIBEV_VERSION_MINOR}")
unset(LIBEV_VERSION_MINOR)
unset(LIBEV_VERSION_MAJOR)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEV_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(Libev DEFAULT_MSG
LIBEV_LIBRARY LIBEV_INCLUDE_DIR)
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libev REQUIRED_VARS
LIBEV_LIBRARY LIBEV_INCLUDE_DIR
VERSION_VAR LIBEV_VERSION)
if(LIBEV_FOUND)
set(LIBEV_LIBRARIES ${LIBEV_LIBRARY})
set(LIBEV_INCLUDE_DIRS ${LIBEV_INCLUDE_DIR})
endif()
mark_as_advanced(LIBEV_INCLUDE_DIR LIBEV_LIBRARY)

100
cmake/FindLibevent.cmake Normal file
View File

@ -0,0 +1,100 @@
# - Try to find libevent
#.rst
# FindLibevent
# ------------
#
# Find Libevent include directories and libraries. Invoke as::
#
# find_package(Libevent
# [version] [EXACT] # Minimum or exact version
# [REQUIRED] # Fail if Libevent is not found
# [COMPONENT <C>...]) # Libraries to look for
#
# Valid components are one or more of:: libevent core extra pthreads openssl.
# Note that 'libevent' contains both core and extra. You must specify one of
# them for the other components.
#
# This module will define the following variables::
#
# LIBEVENT_FOUND - True if headers and requested libraries were found
# LIBEVENT_INCLUDE_DIRS - Libevent include directories
# LIBEVENT_LIBRARIES - Libevent libraries to be linked
# LIBEVENT_<C>_FOUND - Component <C> was found (<C> is uppercase)
# LIBEVENT_<C>_LIBRARY - Library to be linked for Libevent omponent <C>.
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBEVENT QUIET libevent)
# Look for the Libevent 2.0 or 1.4 headers
find_path(LIBEVENT_INCLUDE_DIR
NAMES
event2/event-config.h
event-config.h
HINTS
${PC_LIBEVENT_INCLUDE_DIRS}
)
set(_LIBEVENT_REQUIRED_VARS LIBEVENT_INCLUDE_DIR)
if(LIBEVENT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
if(EXISTS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h")
# Libevent 2.0
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
else()
# Libevent 1.4
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
endif()
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBEVENT_VERSION "${LIBEVENT_VERSION}")
unset(_version_regex)
endif()
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
set(_LIBEVENT_LIBNAME libevent)
# Note: compare two variables to avoid a CMP0054 policy warning
if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
set(_LIBEVENT_LIBNAME event)
else()
set(_LIBEVENT_LIBNAME "event_${COMPONENT}")
endif()
string(TOUPPER "${COMPONENT}" COMPONENT)
find_library(LIBEVENT_${COMPONENT}_LIBRARY
NAMES ${_LIBEVENT_LIBNAME}
HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
)
if(LIBEVENT_${COMPONENT}_LIBRARY)
set(LIBEVENT_${COMPONENT}_FOUND 1)
endif()
list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT}_LIBRARY)
endforeach()
unset(_LIBEVENT_LIBNAME)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(LIBEVENT REQUIRED_VARS
${_LIBEVENT_REQUIRED_VARS}
VERSION_VAR LIBEVENT_VERSION
HANDLE_COMPONENTS)
if(LIBEVENT_FOUND)
set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
set(LIBEVENT_LIBRARIES)
if(NOT Libevent_FIND_QUIETLY)
message(STATUS "Found the following Libevent components:")
endif()
foreach(_COMPONENT ${Libevent_FIND_COMPONENTS})
string(TOUPPER "${_COMPONENT}" COMPONENT)
if(LIBEVENT_${COMPONENT}_FOUND)
if(NOT Libevent_FIND_QUIETLY)
message(STATUS " ${_COMPONENT}")
endif()
list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT}_LIBRARY})
endif()
endforeach()
endif()
mark_as_advanced(${_LIBEVENT_REQUIRED_VARS})
unset(_LIBEVENT_REQUIRED_VARS)

View File

@ -15,6 +15,7 @@ include_directories(
"${CMAKE_SOURCE_DIR}/src/includes"
"${CMAKE_SOURCE_DIR}/third-party"
${JEMALLOC_INCLUDE_DIRS}
${LIBSPDYLAY_INCLUDE_DIRS}
${LIBXML2_INCLUDE_DIR}
${LIBEV_INCLUDE_DIRS}