From 0b872fd4beee649103f0e737fca5838c2b6a1e88 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Wed, 1 Apr 2020 14:08:51 -0400
Subject: [PATCH] nghttp2: Build the library within CMake for use by our curl

Provide our own minimal `config.h` since the upstream one is much
larger to support other parts of its distribution.  Compile with
warnings disabled since this is third-party code.
---
 CMakeLists.txt                       | 14 +++++++-
 CTestCustom.cmake.in                 |  2 ++
 Utilities/cmnghttp2/CMakeLists.txt   | 52 ++++++++++++++++++++++++++++
 Utilities/cmnghttp2/cmakeconfig.h.in | 17 +++++++++
 4 files changed, 84 insertions(+), 1 deletion(-)
 create mode 100644 Utilities/cmnghttp2/CMakeLists.txt
 create mode 100644 Utilities/cmnghttp2/cmakeconfig.h.in

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b6ef543f57..32a483db13 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -154,7 +154,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
 
   # Allow the user to enable/disable all system utility library options by
   # defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
-  set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV ZLIB ZSTD)
+  set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV NGHTTP2 ZLIB ZSTD)
   foreach(util ${UTILITIES})
     if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
         AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@@ -192,6 +192,8 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
     "${CMAKE_USE_SYSTEM_LIBRARY_ZSTD}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
   CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_LIBLZMA "Use system-installed liblzma"
     "${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
+  CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_NGHTTP2 "Use system-installed nghttp2"
+    "${CMAKE_USE_SYSTEM_LIBRARY_NGHTTP2}" "NOT CMAKE_USE_SYSTEM_CURL" ON)
   option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
   option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}")
   option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}")
@@ -465,9 +467,19 @@ macro (CMAKE_BUILD_UTILITIES)
       set(CURL_CA_PATH "" CACHE PATH "Path to SSL CA Certificate Directory")
       mark_as_advanced(CURL_CA_BUNDLE CURL_CA_PATH)
     endif()
+    if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
+      # Tell curl's FindNGHTTP2 module to use our library.
+      set(NGHTTP2_LIBRARY cmnghttp2)
+      set(NGHTTP2_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmnghttp2/lib/includes)
+    endif()
     add_subdirectory(Utilities/cmcurl)
     CMAKE_SET_TARGET_FOLDER(cmcurl "Utilities/3rdParty")
     CMAKE_SET_TARGET_FOLDER(LIBCURL "Utilities/3rdParty")
+    if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
+      # Configure after curl to re-use some check results.
+      add_subdirectory(Utilities/cmnghttp2)
+      CMAKE_SET_TARGET_FOLDER(cmnghttp2 "Utilities/3rdParty")
+    endif()
   endif()
 
   #---------------------------------------------------------------------
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index fb8e099a6f..bd250e23aa 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -99,6 +99,8 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
   "liblzma/common/index_encoder.c:[0-9]+:[0-9]+: warning: Value stored to .* during its initialization is never read"
   "libuv/src/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
   "libuv/src/.*:[0-9]+:[0-9]+: warning: The left operand of '==' is a garbage value"
+  "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
+  "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Value stored to .* is never read"
   )
 
 if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt
new file mode 100644
index 0000000000..3a11acec60
--- /dev/null
+++ b/Utilities/cmnghttp2/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+    "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel)$")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
+# Re-use some check result cache entries from cmcurl:
+# * HAVE_ARPA_INET_H
+# * HAVE_NETINET_IN_H
+# * HAVE_SSIZE_T
+if(NOT HAVE_SSIZE_T)
+  set(ssize_t KWIML_INT_intptr_t)
+endif()
+configure_file(cmakeconfig.h.in config.h)
+
+add_library(cmnghttp2 STATIC
+  lib/nghttp2_buf.c
+  lib/nghttp2_callbacks.c
+  lib/nghttp2_debug.c
+  lib/nghttp2_frame.c
+  lib/nghttp2_hd.c
+  lib/nghttp2_hd_huffman.c
+  lib/nghttp2_hd_huffman_data.c
+  lib/nghttp2_helper.c
+  lib/nghttp2_http.c
+  lib/nghttp2_map.c
+  lib/nghttp2_mem.c
+  lib/nghttp2_npn.c
+  lib/nghttp2_option.c
+  lib/nghttp2_outbound_item.c
+  lib/nghttp2_pq.c
+  lib/nghttp2_priority_spec.c
+  lib/nghttp2_queue.c
+  lib/nghttp2_rcbuf.c
+  lib/nghttp2_session.c
+  lib/nghttp2_stream.c
+  lib/nghttp2_submit.c
+  lib/nghttp2_version.c
+  )
+
+target_compile_definitions(cmnghttp2
+  PUBLIC NGHTTP2_STATICLIB
+  PRIVATE HAVE_CONFIG_H
+  )
+target_include_directories(cmnghttp2 PRIVATE
+  ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/lib/includes
+  )
+
+install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmnghttp2)
diff --git a/Utilities/cmnghttp2/cmakeconfig.h.in b/Utilities/cmnghttp2/cmakeconfig.h.in
new file mode 100644
index 0000000000..d6693ee578
--- /dev/null
+++ b/Utilities/cmnghttp2/cmakeconfig.h.in
@@ -0,0 +1,17 @@
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+#endif
+
+#include <cm_kwiml.h>
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine ssize_t @ssize_t@
+
+/* sizeof(int *) */
+#define SIZEOF_INT_P KWIML_ABI_SIZEOF_DATA_PTR
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#cmakedefine HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine HAVE_NETINET_IN_H 1
-- 
GitLab