Start working on a CMake-based build to eventually replace SCons.

* CMakeLists.txt,
  build/feature.cmake, build/version.cmake,
  build/FindApr.cmake, build/FindApu.cmake: New files.


git-svn-id: https://svn.apache.org/repos/asf/serf/trunk@1834217 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..bbde0af
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,92 @@
+# ===================================================================
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+# ===================================================================
+
+cmake_minimum_required(VERSION 3.0.2)
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build")
+include(version)
+include(feature)
+
+project("Serf" VERSION ${SERF_VERSION} LANGUAGES C)
+message(WARNING
+        "Serf's CMake build is considered EXPERIMENTAL. "
+        "Some features are not supported and the build "
+        "has not been tested on many supported platforms.")
+
+
+set(HEADERS
+    "serf.h"
+    "serf_bucket_types.h"
+    "serf_bucket_util.h"
+)
+
+file(GLOB SOURCES "src/*.c" "auth/*.c" "buckets/*.c" "protocols/*.c")
+if(WINDOWS)
+  set(SHARED_SOURCES "serf.rc")
+else(WINDOWS)
+  set(SHARED_SOURCES)
+endif(WINDOWS)
+
+
+find_package(openssl)
+find_package(zlib)
+find_package(apr)
+find_package(apu)
+
+# Feature tests
+CheckNotFunction("BIO_set_init" "SERF_NO_SSL_BIO_WRAPPERS" ${OPENSSL_LIBRARIES})
+CheckNotFunction("X509_STORE_get0_param" "SERF_NO_SSL_X509_STORE_WRAPPERS" ${OPENSSL_LIBRARIES})
+CheckNotFunction("X509_get0_notBefore" "SERF_NO_SSL_X509_GET0_NOTBEFORE" ${OPENSSL_LIBRARIES})
+CheckNotFunction("X509_get0_notAfter" "SERF_NO_SSL_X509_GET0_NOTAFTER" ${OPENSSL_LIBRARIES})
+CheckNotFunction("X509_STORE_CTX_get0_chain" "SERF_NO_SSL_X509_GET0_CHAIN" ${OPENSSL_LIBRARIES})
+CheckNotFunction("ASN1_STRING_get0_data" "SERF_NO_SSL_ASN1_STRING_GET0_DATA" ${OPENSSL_LIBRARIES})
+CheckFunction("CRYPTO_set_locking_callback" "SERF_HAVE_SSL_LOCKING_CALLBACKS" ${OPENSSL_LIBRARIES})
+CheckFunction("OPENSSL_malloc_init" "SERF_HAVE_OPENSSL_MALLOC_INIT" ${OPENSSL_LIBRARIES})
+CheckFunction("SSL_library_init" "SERF_HAVE_OPENSSL_SSL_LIBRARY_INIT" ${OPENSSL_LIBRARIES})
+CheckFunction("OpenSSL_version_num" "SERF_HAVE_OPENSSL_VERSION_NUM" ${OPENSSL_LIBRARIES})
+CheckFunction("SSL_set_alpn_protos" "SERF_HAVE_OPENSSL_ALPN" ${OPENSSL_LIBRARIES})
+CheckHeader("openssl/applink.c" "SERF_HAVE_OPENSSL_APPLINK_C" ${OPENSSL_INCLUDE_DIR})
+CheckType("OSSL_HANDSHAKE_STATE" "openssl/ssl.h" "SERF_HAVE_OSSL_HANDSHAKE_STATE" ${OPENSSL_INCLUDE_DIR})
+
+set(DEPENDENCY_INCLUDE_DIRS
+    ${OPENSSL_INCLUDE_DIR}
+    ${ZLIB_INCLUDE_DIRS}
+    ${APR_INCLUDES}
+    ${APU_INCLUDES}
+)
+list(REMOVE_DUPLICATES DEPENDENCY_INCLUDE_DIRS)
+
+set(DEPENDENCY_LIBRARIES
+    ${OPENSSL_LIBRARIES}
+    ${ZLIB_LIBRARIES}
+    ${APR_LIBS}
+    ${APU_LIBS}
+)
+list(REMOVE_DUPLICATES DEPENDENCY_LIBRARIES)
+
+include_directories(BEFORE SYSTEM ${DEPENDENCY_INCLUDE_DIRS})
+include_directories(${CMAKE_SOURCE_DIR})
+add_library(SerfStatic STATIC ${SOURCES})
+add_library(SerfShared SHARED ${SOURCES} ${SHARED_SOURCES})
+target_link_libraries(SerfShared ${DEPENDENCY_LIBRARIES})
+set_target_properties(SerfStatic SerfShared
+                      PROPERTIES
+                      OUTPUT_NAME "serf-${SERF_MAJOR_VERSION}"
+                      VERSION ${SERF_VERSION}
+                      SOVERSION ${SERF_SOVERSION})
diff --git a/build/FindApr.cmake b/build/FindApr.cmake
new file mode 100644
index 0000000..6aa93ae
--- /dev/null
+++ b/build/FindApr.cmake
@@ -0,0 +1,51 @@
+# Source: http://svn.trolocsis.com/repos/projects/templates/apr/build/FindAPR.cmake
+# Locate APR include paths and libraries
+
+# This module defines
+# APR_INCLUDES, where to find apr.h, etc.
+# APR_LIBS, linker switches to use with ld to link against APR
+# APR_EXTRALIBS, additional libraries to link against
+# APR_CFLAGS, the flags to use to compile
+# APR_FOUND, set to TRUE if found, FALSE otherwise
+# APR_VERSION, the version of APR that was found
+
+set(APR_FOUND FALSE)
+
+find_program(APR_CONFIG_EXECUTABLE apr-1-config)
+mark_as_advanced(APR_CONFIG_EXECUTABLE)
+
+macro(_apr_invoke _varname _separate _regexp)
+    execute_process(
+        COMMAND ${APR_CONFIG_EXECUTABLE} ${ARGN}
+        OUTPUT_VARIABLE _apr_output
+        RESULT_VARIABLE _apr_failed
+    )
+
+    if(_apr_failed)
+        message(FATAL_ERROR "${APR_CONFIG_EXECUTABLE} ${ARGN} failed")
+    else()
+        string(REGEX REPLACE "[\r\n]"  "" _apr_output "${_apr_output}")
+        string(REGEX REPLACE " +$"     "" _apr_output "${_apr_output}")
+
+        if(NOT ${_regexp} STREQUAL "")
+            string(REGEX REPLACE "${_regexp}" " " _apr_output "${_apr_output}")
+        endif()
+
+        # XXX: We don't want to invoke separate_arguments() for APR_CFLAGS;
+        # just leave as-is
+        if(${_separate})
+            separate_arguments(_apr_output)
+        endif()
+
+        set(${_varname} "${_apr_output}")
+    endif()
+endmacro(_apr_invoke)
+
+_apr_invoke(APR_CFLAGS    FALSE ""        --cppflags --cflags)
+_apr_invoke(APR_INCLUDES  TRUE  "(^| )-I" --includes)
+_apr_invoke(APR_LIBS      TRUE  ""        --link-ld)
+_apr_invoke(APR_EXTRALIBS TRUE  "(^| )-l" --libs)
+_apr_invoke(APR_VERSION   TRUE  ""        --version)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(APR DEFAULT_MSG APR_INCLUDES APR_LIBS APR_VERSION)
diff --git a/build/FindApu.cmake b/build/FindApu.cmake
new file mode 100644
index 0000000..632544b
--- /dev/null
+++ b/build/FindApu.cmake
@@ -0,0 +1,51 @@
+# Locate apr-util include paths and libraries. Based on findapr.cmake;
+# simple modifications to apply to apr-util instead.
+
+# This module defines
+# APU_INCLUDES, where to find apu.h, etc.
+# APU_LIBS, linker switches to use with ld to link against apr-util
+# APU_EXTRALIBS, additional libraries to link against
+# APU_LDFLAGS, additional linker flags that must be used
+# APU_FOUND, set to TRUE if found, FALSE otherwise
+# APU_VERSION, set to the version of apr-util found
+
+set(APU_FOUND FALSE)
+
+find_program(APU_CONFIG_EXECUTABLE apu-1-config)
+mark_as_advanced(APU_CONFIG_EXECUTABLE)
+
+macro(_apu_invoke _varname _separate _regexp)
+    execute_process(
+        COMMAND ${APU_CONFIG_EXECUTABLE} ${ARGN}
+        OUTPUT_VARIABLE _apu_output
+        RESULT_VARIABLE _apu_failed
+    )
+
+    if(_apu_failed)
+        message(FATAL_ERROR "${APU_CONFIG_EXECUTABLE} ${ARGN} failed")
+    else()
+        string(REGEX REPLACE "[\r\n]"  "" _apu_output "${_apu_output}")
+        string(REGEX REPLACE " +$"     "" _apu_output "${_apu_output}")
+
+        if(NOT ${_regexp} STREQUAL "")
+            string(REGEX REPLACE "${_regexp}" " " _apu_output "${_apu_output}")
+        endif()
+
+        # XXX: We don't want to invoke separate_arguments() for APU_LDFLAGS;
+        # just leave as-is
+        if(${_separate})
+            separate_arguments(_apu_output)
+        endif()
+
+        set(${_varname} "${_apu_output}")
+    endif()
+endmacro(_apu_invoke)
+
+_apu_invoke(APU_INCLUDES  TRUE  "(^| )-I" --includes)
+_apu_invoke(APU_EXTRALIBS TRUE  "(^| )-l" --libs)
+_apu_invoke(APU_LIBS      TRUE  ""        --link-ld)
+_apu_invoke(APU_LDFLAGS   FALSE ""        --ldflags)
+_apu_invoke(APU_VERSION   TRUE  ""        --version)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(APU DEFAULT_MSG APU_INCLUDES APU_LIBS APU_VERSION)
diff --git a/build/feature.cmake b/build/feature.cmake
new file mode 100644
index 0000000..41a1ecf
--- /dev/null
+++ b/build/feature.cmake
@@ -0,0 +1,87 @@
+# ===================================================================
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+# ===================================================================
+
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckTypeSize)
+
+function(_CheckFunction var_ name_ libraries_)
+  set(CMAKE_REQUIRED_LIBRARIES "${libraries_}")
+  check_function_exists("${name_}" "serf_foundit_${name_}_")
+  if(${serf_foundit_${name_}_})
+    set("${var_}" TRUE PARENT_SCOPE)
+  else()
+    set("${var_}" FALSE PARENT_SCOPE)
+  endif()
+  unset(CMAKE_REQUIRED_LIBRARIES)
+endfunction(_CheckFunction)
+
+macro(CheckFunction name_ symbol_)
+  _CheckFunction("serf_feature_CheckFunction_${name}_" "${name_}" "${ARGN}")
+  if("${serf_feature_CheckFunction_${name}_}")
+    add_definitions("-D${symbol_}")
+  endif()
+endmacro(CheckFunction)
+
+macro(CheckNotFunction name_ symbol_)
+  _CheckFunction("serf_feature_CheckNotFunction_${name}_" "${name_}" "${ARGN}")
+  if(NOT "${serf_feature_CheckNotFunction_${name}_}")
+    add_definitions("-D${symbol_}")
+  endif()
+endmacro(CheckNotFunction)
+
+
+function(_CheckHeader var_ name_ includes_)
+  set(CMAKE_REQUIRED_INCLUDES "${includes_}")
+  check_include_file("${name_}" "serf_foundit_${name_}_")
+  if(${serf_foundit_${name_}_})
+    set("${var_}" TRUE PARENT_SCOPE)
+  else()
+    set("${var_}" FALSE PARENT_SCOPE)
+  endif()
+  unset(CMAKE_REQUIRED_INCLUDES)
+endfunction(_CheckHeader)
+
+macro(CheckHeader name_ symbol_)
+  _CheckHeader("serf_feature_CheckHeader_${name}_" "${name_}" "${ARGN}")
+  if("${serf_feature_CheckHeader_${name}_}")
+    add_definitions("-D${symbol_}")
+  endif()
+endmacro(CheckHeader)
+
+
+function(_CheckType var_ name_ header_ includes_)
+  set(CMAKE_REQUIRED_INCLUDES "${includes_}")
+  set(CMAKE_EXTRA_INCLUDE_FILES "${header_}")
+  check_type_size("${name_}" "serf_foundit_${name_}_")
+  if(${HAVE_serf_foundit_${name_}_})
+    set("${var_}" TRUE PARENT_SCOPE)
+  else()
+    set("${var_}" FALSE PARENT_SCOPE)
+  endif()
+  unset(CMAKE_REQUIRED_INCLUDES)
+  unset(CMAKE_EXTRA_INCLUDE_FILES)
+endfunction(_CheckType)
+
+macro(CheckType name_ header_ symbol_)
+  _CheckType("serf_feature_CheckType_${name}_" "${name_}" "${header_}" "${ARGN}")
+  if("${serf_feature_CheckType_${name}_}")
+    add_definitions("-D${symbol_}")
+  endif()
+endmacro(CheckType)
diff --git a/build/version.cmake b/build/version.cmake
new file mode 100644
index 0000000..c5d56a6
--- /dev/null
+++ b/build/version.cmake
@@ -0,0 +1,54 @@
+# ===================================================================
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+# ===================================================================
+
+# Find the version number in serf.h so that we don't keep it in two places.
+
+set(SERF_HEADER "${CMAKE_SOURCE_DIR}/serf.h")
+
+unset(SERF_VERSION)
+unset(SERF_SOVERSION)
+unset(SERF_MAJOR_VERSION)
+unset(SERF_MINOR_VERSION)
+unset(SERF_PATCH_VERSION)
+
+file(STRINGS "${SERF_HEADER}" SERF_VERSION_BITS
+     REGEX "^ *# *define +SERF_[A-Z]*_VERSION +[0-9]+ *$")
+foreach(STR ${SERF_VERSION_BITS})
+  if(STR MATCHES "^ *# *define +SERF_MAJOR_VERSION +([0-9])+ *$")
+    string(REGEX REPLACE "^ *# *define +SERF_MAJOR_VERSION +([0-9])+ *$"
+           "\\1" SERF_MAJOR_VERSION ${STR})
+  endif()
+  if(STR MATCHES "^ *# *define +SERF_MINOR_VERSION +([0-9])+ *$")
+    string(REGEX REPLACE "^ *# *define +SERF_MINOR_VERSION +([0-9])+ *$"
+           "\\1" SERF_MINOR_VERSION ${STR})
+  endif()
+  if(STR MATCHES "^ *# *define +SERF_PATCH_VERSION +([0-9])+ *$")
+    string(REGEX REPLACE "^ *# *define +SERF_PATCH_VERSION +([0-9])+ *$"
+           "\\1" SERF_PATCH_VERSION ${STR})
+  endif()
+endforeach()
+
+if(NOT DEFINED SERF_MAJOR_VERSION
+   OR NOT DEFINED SERF_MINOR_VERSION
+   OR NOT DEFINED SERF_PATCH_VERSION)
+  message(FATAL_ERROR "Could not find the version number in '${SERF_HEADER}'")
+endif()
+
+set(SERF_VERSION "${SERF_MAJOR_VERSION}.${SERF_MINOR_VERSION}.${SERF_PATCH_VERSION}")
+set(SERF_SOVERSION "${SERF_MAJOR_VERSION}.${SERF_MINOR_VERSION}.0")