pick changes from Debian patch

PiperOrigin-RevId: 816113304
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml
index a653ad9..d1cb80f 100644
--- a/.github/workflows/build_test.yml
+++ b/.github/workflows/build_test.yml
@@ -28,18 +28,36 @@
       fail-fast: false
       matrix:
         include:
+          - name: cmake:gcc
+            build_system: cmake
+            c_compiler: gcc
+            cxx_compiler: g++
+
           - name: cmake:gcc-old
             build_system: cmake
             c_compiler: gcc
             cxx_compiler: g++
             os: ubuntu-22.04
 
+          - name: cmake:clang
+            build_system: cmake
+            c_compiler: clang
+            cxx_compiler: clang
+
           - name: cmake:clang-old
             build_system: cmake
             c_compiler: clang
             cxx_compiler: clang
             os: ubuntu-22.04
 
+          - name: cmake:package
+            build_system: cmake
+            cmake_args: -DBROTLI_BUILD_FOR_PACKAGE=ON
+
+          - name: cmake:static
+            build_system: cmake
+            cmake_args: -DBUILD_SHARED_LIBS=OFF
+
           - name: cmake:clang:asan
             build_system: cmake
             sanitizer: address
@@ -192,7 +210,7 @@
       if: ${{ matrix.build_system == 'cmake' }}
       run: |
         export ASAN_OPTIONS=detect_leaks=0
-        declare -a CMAKE_OPTIONS=()
+        declare -a CMAKE_OPTIONS=(${{ matrix.cmake_args || '' }})
         CMAKE_OPTIONS+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
         [ ! -z '${{ matrix.c_compiler || '' }}' ] && CMAKE_OPTIONS+=(-DCMAKE_C_COMPILER='${{ matrix.c_compiler }}')
         [ ! -z '${{ matrix.cxx_compiler || '' }}' ] && CMAKE_OPTIONS+=(-DCMAKE_CXX_COMPILER='${{ matrix.cxx_compiler }}')
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1dfac68..634990b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,10 +10,16 @@
 cmake_policy(SET CMP0048 NEW)
 project(brotli C)
 
+# Reflect CMake variable as a build option.
 option(BUILD_SHARED_LIBS "Build shared libraries" ON)
 set(BROTLI_BUILD_TOOLS ON CACHE BOOL "Build/install CLI tools")
+set(BROTLI_BUILD_FOR_PACKAGE OFF CACHE BOOL "Build/install both shared and static libraries")
 
-if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+if (BROTLI_BUILD_FOR_PACKAGE AND NOT BUILD_SHARED_LIBS)
+  message(FATAL_ERROR "Both BROTLI_BUILD_FOR_PACKAGE and BUILD_SHARED_LIBS are set.")
+endif()
+
+if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
   message(STATUS "Setting build type to Release as none was specified.")
   set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
 else()
@@ -38,15 +44,15 @@
 # we'll use the BROTLI_BUNDLED_MODE variable to let them do that; just
 # set it to OFF in your project before you add_subdirectory(brotli).
 get_directory_property(BROTLI_PARENT_DIRECTORY PARENT_DIRECTORY)
-if(NOT DEFINED BROTLI_BUNDLED_MODE)
+if (NOT DEFINED BROTLI_BUNDLED_MODE)
   # Bundled mode hasn't been set one way or the other, set the default
   # depending on whether or not we are the top-level project.
-  if(BROTLI_PARENT_DIRECTORY)
+  if (BROTLI_PARENT_DIRECTORY)
     set(BROTLI_BUNDLED_MODE ON)
   else()
     set(BROTLI_BUNDLED_MODE OFF)
   endif()
-endif()
+endif()  # BROTLI_BUNDLED_MODE
 mark_as_advanced(BROTLI_BUNDLED_MODE)
 
 include(GNUInstallDirs)
@@ -81,62 +87,79 @@
 include(CheckLibraryExists)
 set(LIBM_LIBRARY)
 CHECK_LIBRARY_EXISTS(m log2 "" HAVE_LIB_M)
-if(HAVE_LIB_M)
+if (HAVE_LIB_M)
   set(LIBM_LIBRARY "m")
 endif()
 
 set(BROTLI_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/c/include")
 mark_as_advanced(BROTLI_INCLUDE_DIRS)
 
-set(BROTLI_LIBRARIES_CORE brotlienc brotlidec brotlicommon)
-set(BROTLI_LIBRARIES ${BROTLI_LIBRARIES_CORE} ${LIBM_LIBRARY})
+if (BROTLI_BUILD_FOR_PACKAGE)
+  set(BROTLI_SHARED_LIBRARIES brotlienc brotlidec brotlicommon)
+  set(BROTLI_STATIC_LIBRARIES brotlienc-static brotlidec-static brotlicommon-static)
+  set(BROTLI_LIBRARIES ${BROTLI_SHARED_LIBRARIES} ${LIBM_LIBRARY})
+else()  # NOT BROTLI_BUILD_FOR_PACKAGE
+  if (BUILD_SHARED_LIBS)
+    set(BROTLI_SHARED_LIBRARIES brotlienc brotlidec brotlicommon)
+    set(BROTLI_STATIC_LIBRARIES)
+  else()  # NOT BUILD_SHARED_LIBS
+    set(BROTLI_SHARED_LIBRARIES)
+    set(BROTLI_STATIC_LIBRARIES brotlienc brotlidec brotlicommon)
+  endif()
+  set(BROTLI_LIBRARIES ${BROTLI_SHARED_LIBRARIES} ${BROTLI_STATIC_LIBRARIES} ${LIBM_LIBRARY})
+endif()  # BROTLI_BUILD_FOR_PACKAGE
 mark_as_advanced(BROTLI_LIBRARIES)
 
-if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
   add_definitions(-DOS_LINUX)
-elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
   add_definitions(-DOS_FREEBSD)
-elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   add_definitions(-DOS_MACOSX)
-endif()
+endif()  # CMAKE_SYSTEM_NAME
 
-if(BROTLI_EMSCRIPTEN)
+if (BROTLI_EMSCRIPTEN)
   set(BUILD_SHARED_LIBS OFF)
 endif()
 
 file(GLOB_RECURSE BROTLI_COMMON_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} c/common/*.c)
-add_library(brotlicommon ${BROTLI_COMMON_SOURCES})
-
 file(GLOB_RECURSE BROTLI_DEC_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} c/dec/*.c)
-add_library(brotlidec ${BROTLI_DEC_SOURCES})
-
 file(GLOB_RECURSE BROTLI_ENC_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} c/enc/*.c)
+
+add_library(brotlicommon ${BROTLI_COMMON_SOURCES})
+add_library(brotlidec ${BROTLI_DEC_SOURCES})
 add_library(brotlienc ${BROTLI_ENC_SOURCES})
 
+if (BROTLI_BUILD_FOR_PACKAGE)
+  add_library(brotlicommon-static STATIC ${BROTLI_COMMON_SOURCES})
+  add_library(brotlidec-static STATIC ${BROTLI_DEC_SOURCES})
+  add_library(brotlienc-static STATIC ${BROTLI_ENC_SOURCES})
+endif()
+
 # Older CMake versions does not understand INCLUDE_DIRECTORIES property.
 include_directories(${BROTLI_INCLUDE_DIRS})
 
-if(BUILD_SHARED_LIBS)
-  foreach(lib ${BROTLI_LIBRARIES_CORE})
+if (BUILD_SHARED_LIBS)
+  foreach(lib ${BROTLI_SHARED_LIBRARIES})
     target_compile_definitions(${lib} PUBLIC "BROTLI_SHARED_COMPILATION" )
     string(TOUPPER "${lib}" LIB)
     set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION")
   endforeach()
-endif()
+endif()  # BUILD_SHARED_LIBS
 
-foreach(lib ${BROTLI_LIBRARIES_CORE})
+foreach(lib ${BROTLI_SHARED_LIBRARIES} ${BROTLI_STATIC_LIBRARIES})
   target_link_libraries(${lib} ${LIBM_LIBRARY})
   set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS})
   set_target_properties(${lib} PROPERTIES
     VERSION "${BROTLI_ABI_COMPATIBILITY}.${BROTLI_ABI_AGE}.${BROTLI_ABI_REVISION}"
     SOVERSION "${BROTLI_ABI_COMPATIBILITY}")
-  if(NOT BROTLI_EMSCRIPTEN)
+  if (NOT BROTLI_EMSCRIPTEN)
     set_target_properties(${lib} PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
   endif()
   set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${BROTLI_INCLUDE_DIRS}>")
-endforeach()
+endforeach()  # BROTLI_xxx_LIBRARIES
 
-if(NOT BROTLI_EMSCRIPTEN)
+if (NOT BROTLI_EMSCRIPTEN)
   target_link_libraries(brotlidec brotlicommon)
   target_link_libraries(brotlienc brotlicommon)
 endif()
@@ -147,19 +170,19 @@
 #
 #   include_directories(${BROTLI_INCLUDE_DIRS})
 #   target_link_libraries(foo ${BROTLI_LIBRARIES})
-if(BROTLI_PARENT_DIRECTORY)
+if (BROTLI_PARENT_DIRECTORY)
   set(BROTLI_INCLUDE_DIRS "${BROTLI_INCLUDE_DIRS}" PARENT_SCOPE)
   set(BROTLI_LIBRARIES "${BROTLI_LIBRARIES}" PARENT_SCOPE)
 endif()
 
 # Build the brotli executable
-if(BROTLI_BUILD_TOOLS)
+if (BROTLI_BUILD_TOOLS)
   add_executable(brotli c/tools/brotli.c)
   target_link_libraries(brotli ${BROTLI_LIBRARIES})
 endif()
 
 # Installation
-if(NOT BROTLI_BUNDLED_MODE)
+if (NOT BROTLI_BUNDLED_MODE)
   if (BROTLI_BUILD_TOOLS)
     install(
       TARGETS brotli
@@ -168,7 +191,7 @@
   endif()
 
   install(
-    TARGETS ${BROTLI_LIBRARIES_CORE}
+    TARGETS ${BROTLI_SHARED_LIBRARIES} ${BROTLI_STATIC_LIBRARIES}
     ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
     LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
     RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
@@ -183,17 +206,21 @@
 # Tests
 
 # Integration tests, those depend on `brotli` binary
-if(NOT BROTLI_DISABLE_TESTS AND BROTLI_BUILD_TOOLS)
+if (NOT BROTLI_DISABLE_TESTS AND BROTLI_BUILD_TOOLS)
   # If we're targeting Windows but not running on Windows, we need Wine
   # to run the tests...
-  if(WIN32 AND NOT CMAKE_HOST_WIN32)
+  if (WIN32 AND NOT CMAKE_HOST_WIN32)
     find_program(BROTLI_WRAPPER NAMES wine)
 
-    if(NOT BROTLI_WRAPPER)
+    if (NOT BROTLI_WRAPPER)
       message(STATUS "wine not found, disabling tests")
       set(BROTLI_DISABLE_TESTS TRUE)
     endif()
   endif()
+endif()  # BROTLI_DISABLE_TESTS
+
+# NB: BROTLI_DISABLE_TESTS might have changed.
+if (NOT BROTLI_DISABLE_TESTS AND BROTLI_BUILD_TOOLS)
   # If our compiler is a cross-compiler that we know about (arm/aarch64),
   # then we need to use qemu to execute the tests.
   if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabihf-.*$")
@@ -286,19 +313,19 @@
     get_filename_component(value_full "${value}" ABSOLUTE)
     string(LENGTH "${value}" value_length)
 
-    if(path_length EQUAL value_length AND path STREQUAL value)
+    if (path_length EQUAL value_length AND path STREQUAL value)
       set("${outvar}" "\${${name}}")
       break()
-    elseif(path_length GREATER value_length)
+    elseif (path_length GREATER value_length)
       # We might be in a subdirectory of the value, but we have to be
       # careful about a prefix matching but not being a subdirectory
       # (for example, /usr/lib64 is not a subdirectory of /usr/lib).
       # We'll do this by making sure the next character is a directory
       # separator.
       string(SUBSTRING "${path}" ${value_length} 1 sep)
-      if(sep STREQUAL "/")
+      if (sep STREQUAL "/")
         string(SUBSTRING "${path}" 0 ${value_length} s)
-        if(s STREQUAL value)
+        if (s STREQUAL value)
           string(SUBSTRING "${path}" "${value_length}" -1 suffix)
           set("${outvar}" "\${${name}}${suffix}")
           break()
@@ -337,7 +364,7 @@
 
 transform_pc_file("scripts/libbrotlienc.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc" "${BROTLI_VERSION}")
 
-if(NOT BROTLI_BUNDLED_MODE)
+if (NOT BROTLI_BUNDLED_MODE)
   install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlicommon.pc"
     DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
   install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlidec.pc"
diff --git a/c/include/brotli/port.h b/c/include/brotli/port.h
index 0c486d9..11cefd7 100644
--- a/c/include/brotli/port.h
+++ b/c/include/brotli/port.h
@@ -269,20 +269,20 @@
 #if defined(_WIN32)
 #if defined(BROTLICOMMON_SHARED_COMPILATION)
 #define BROTLI_COMMON_API __declspec(dllexport)
-#else
+#else  /* !BROTLICOMMON_SHARED_COMPILATION */
 #define BROTLI_COMMON_API __declspec(dllimport)
 #endif  /* BROTLICOMMON_SHARED_COMPILATION */
 #if defined(BROTLIDEC_SHARED_COMPILATION)
 #define BROTLI_DEC_API __declspec(dllexport)
-#else
+#else   /* !BROTLIDEC_SHARED_COMPILATION */
 #define BROTLI_DEC_API __declspec(dllimport)
 #endif  /* BROTLIDEC_SHARED_COMPILATION */
 #if defined(BROTLIENC_SHARED_COMPILATION)
 #define BROTLI_ENC_API __declspec(dllexport)
-#else
+#else  /* !BROTLIENC_SHARED_COMPILATION */
 #define BROTLI_ENC_API __declspec(dllimport)
 #endif  /* BROTLIENC_SHARED_COMPILATION */
-#else  /* _WIN32 */
+#else  /* !_WIN32 */
 #define BROTLI_COMMON_API BROTLI_PUBLIC
 #define BROTLI_DEC_API BROTLI_PUBLIC
 #define BROTLI_ENC_API BROTLI_PUBLIC