Commit fa0178608699ce23c942f719c47eaada645db409

Edward Thomson 2021-01-05T12:06:52

Merge pull request #5748 from lhchavez/chromium-zlib zlib: Add support for building with Chromium's zlib implementation

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 05ad1ba..6556979 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,7 +50,7 @@ OPTION(USE_STANDALONE_FUZZERS		"Enable standalone fuzzers (compatible with gcc)"
 OPTION(USE_LEAK_CHECKER			"Run tests with leak checker"				OFF)
 OPTION(DEBUG_POOL			"Enable debug pool allocator"				OFF)
 OPTION(ENABLE_WERROR			"Enable compilation with -Werror"			OFF)
-OPTION(USE_BUNDLED_ZLIB    		"Use the bundled version of zlib"			OFF)
+OPTION(USE_BUNDLED_ZLIB    		"Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL"			OFF)
    SET(USE_HTTP_PARSER			"" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")
 OPTION(DEPRECATE_HARD			"Do not include deprecated functions in the library"	OFF)
    SET(REGEX_BACKEND			"" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.")
diff --git a/deps/chromium-zlib/CMakeLists.txt b/deps/chromium-zlib/CMakeLists.txt
new file mode 100644
index 0000000..bbb35d4
--- /dev/null
+++ b/deps/chromium-zlib/CMakeLists.txt
@@ -0,0 +1,101 @@
+# CMake build script for the bundled Chromium zlib implementation. So far, it
+# is only supported for x86_64 processors with CLMUL, SSE3, SSE4.2.
+#
+# TODO: The Chromium build file (in deps/chromium-zlib/zlib/BUILD.gn) supports
+# more platforms (like ARM with NEON), more can be enabled as needed.
+
+CMAKE_MINIMUM_REQUIRED(VERSION 3.11)
+
+include(FetchContent)
+include(FindGit)
+
+# Ensure that the git binary is present to download the sources.
+find_package(Git)
+IF(NOT Git_FOUND)
+	message(FATAL_ERROR "git is required to download the Chromium zlib sources")
+ENDIF()
+
+FetchContent_Populate(chromium_zlib_src
+	GIT_REPOSITORY https://chromium.googlesource.com/chromium/src/third_party/zlib.git
+	GIT_TAG 2c183c9f93a328bfb3121284da13cf89a0f7e64a
+	QUIET
+)
+
+# The Chromium build globally disables some warnings.
+disable_warnings(implicit-fallthrough)
+disable_warnings(unused-function)
+disable_warnings(unused-parameter)
+disable_warnings(sign-compare)
+disable_warnings(declaration-after-statement)
+disable_warnings(missing-declarations)
+
+# -O3 is also set by the Chromium configuration and has been deemed safe enough
+# for them.
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG")
+SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
+
+# Common definitions.
+add_definitions(
+	-DSTDC
+	-DNO_GZIP
+	-DZLIB_IMPLEMENTATION
+)
+list(APPEND SRC_ZLIB
+	"${chromium_zlib_src_SOURCE_DIR}/adler32.c"
+	"${chromium_zlib_src_SOURCE_DIR}/chromeconf.h"
+	"${chromium_zlib_src_SOURCE_DIR}/compress.c"
+	"${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/insert_string.h"
+	"${chromium_zlib_src_SOURCE_DIR}/cpu_features.c"
+	"${chromium_zlib_src_SOURCE_DIR}/cpu_features.h"
+	"${chromium_zlib_src_SOURCE_DIR}/crc32.c"
+	"${chromium_zlib_src_SOURCE_DIR}/crc32.h"
+	"${chromium_zlib_src_SOURCE_DIR}/deflate.c"
+	"${chromium_zlib_src_SOURCE_DIR}/deflate.h"
+	"${chromium_zlib_src_SOURCE_DIR}/gzclose.c"
+	"${chromium_zlib_src_SOURCE_DIR}/gzguts.h"
+	"${chromium_zlib_src_SOURCE_DIR}/gzlib.c"
+	"${chromium_zlib_src_SOURCE_DIR}/gzread.c"
+	"${chromium_zlib_src_SOURCE_DIR}/gzwrite.c"
+	"${chromium_zlib_src_SOURCE_DIR}/infback.c"
+	"${chromium_zlib_src_SOURCE_DIR}/inffast.c"
+	"${chromium_zlib_src_SOURCE_DIR}/inffast.h"
+	"${chromium_zlib_src_SOURCE_DIR}/inffixed.h"
+	"${chromium_zlib_src_SOURCE_DIR}/inflate.h"
+	"${chromium_zlib_src_SOURCE_DIR}/inftrees.c"
+	"${chromium_zlib_src_SOURCE_DIR}/inftrees.h"
+	"${chromium_zlib_src_SOURCE_DIR}/trees.c"
+	"${chromium_zlib_src_SOURCE_DIR}/trees.h"
+	"${chromium_zlib_src_SOURCE_DIR}/uncompr.c"
+	"${chromium_zlib_src_SOURCE_DIR}/zconf.h"
+	"${chromium_zlib_src_SOURCE_DIR}/zlib.h"
+	"${chromium_zlib_src_SOURCE_DIR}/zutil.c"
+	"${chromium_zlib_src_SOURCE_DIR}/zutil.h"
+)
+
+# x86_64-specific optimizations
+string(APPEND CMAKE_C_FLAGS " -mssse3 -msse4.2 -mpclmul")
+add_definitions(
+  -DCHROMIUM_ZLIB_NO_CHROMECONF
+	-DX86_NOT_WINDOWS
+	-DADLER32_SIMD_SSSE3
+	-DCRC32_SIMD_SSE42_PCLMUL
+	-DDEFLATE_FILL_WINDOW_SSE2
+	-DINFLATE_CHUNK_READ_64LE
+	-DINFLATE_CHUNK_SIMD_SSE2
+)
+list(APPEND SRC_ZLIB
+	"${chromium_zlib_src_SOURCE_DIR}/adler32_simd.c"
+	"${chromium_zlib_src_SOURCE_DIR}/adler32_simd.h"
+	"${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/chunkcopy.h"
+	"${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c"
+	"${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h"
+	"${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/inflate.c"
+	"${chromium_zlib_src_SOURCE_DIR}/crc32_simd.c"
+	"${chromium_zlib_src_SOURCE_DIR}/crc32_simd.h"
+	"${chromium_zlib_src_SOURCE_DIR}/crc_folding.c"
+	"${chromium_zlib_src_SOURCE_DIR}/fill_window_sse.c"
+)
+
+list(SORT SRC_ZLIB)
+include_directories("${chromium_zlib_src_SOURCE_DIR}")
+add_library(chromium_zlib OBJECT ${SRC_ZLIB})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d01cc64..4fde16d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,6 +7,7 @@ ENDIF()
 ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator")
 
 INCLUDE(PkgBuildConfig)
+INCLUDE(SanitizeBool)
 
 # This variable will contain the libraries we need to put into
 # libgit2.pc's Requires.private. That is, what we're linking to or
@@ -186,7 +187,12 @@ ELSE()
 ENDIF()
 
 # Optional external dependency: zlib
-IF(NOT USE_BUNDLED_ZLIB)
+SanitizeBool(USE_BUNDLED_ZLIB)
+IF(USE_BUNDLED_ZLIB STREQUAL ON)
+	SET(USE_BUNDLED_ZLIB "Bundled")
+ENDIF()
+
+IF(USE_BUNDLED_ZLIB STREQUAL "OFF")
 	FIND_PACKAGE(ZLIB)
 	IF(ZLIB_FOUND)
 		LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS})
@@ -201,7 +207,12 @@ IF(NOT USE_BUNDLED_ZLIB)
 		MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." )
 	ENDIF()
 ENDIF()
-IF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND)
+IF(USE_BUNDLED_ZLIB STREQUAL "Chromium")
+	ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib")
+	LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib")
+	LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:chromium_zlib>)
+	ADD_FEATURE_INFO(zlib ON "using (Chromium) bundled zlib")
+ELSEIF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND)
 	ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib")
 	LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib")
 	LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:zlib>)