Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,12 @@ build for iOS, and have the user inform you of any build issues that come up.

Common system library dependencies for desktop:
* **Windows**: Common dependencies include `advapi32.lib`, `ws2_32.lib`,
`crypt32.lib`. Specific products might need others (e.g., Firestore:
`rpcrt4.lib`, `ole32.lib`, `shell32.lib`).
`crypt32.lib`, `bcrypt.lib`, `iphlpapi.lib`, `secur32.lib`. Specific
products might need others (e.g., Firestore: `rpcrt4.lib`, `ole32.lib`,
`shell32.lib`).
* **macOS**: Common dependencies include `pthread` (system library) and
frameworks like `CoreFoundation`, `Foundation`, and `Security`.
frameworks like `CoreFoundation`, `Foundation`, `Security`, and
`SystemConfiguration`.
* **Linux**: Common dependencies include `pthread` (system library). When
using GCC 5+, define `-D_GLIBCXX_USE_CXX11_ABI=0`.

Expand Down
90 changes: 74 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -428,29 +428,87 @@ endif()

# Some of the external libraries are not used for mobile.
if(DESKTOP)
# Build curl as a static library
# Configure libcurl before adding its subdirectory.
# Note: curl 8.23.0 requires CMake >= 3.18 (CMP0077=NEW), so plain set() of
# normal variables overrides curl's option() defaults without polluting the
# global CMake cache.

# Build only the static libcurl library (libcurl_static); skip the shared
# library, the curl CLI binary, and all generated manpages/documentation.
set(BUILD_SHARED_LIBS OFF)
set(BUILD_STATIC_LIBS ON)
set(BUILD_CURL_EXE OFF)
set(CURL_STATICLIB ON)
if (WIN32)
# Enable Windows native SSL/TLS in libcurl.
set(CMAKE_USE_SCHANNEL ON)
set(BUILD_LIBCURL_DOCS OFF)
set(BUILD_MISC_DOCS OFF)

# Disable curl's install targets and prevent curl's CMakeLists.txt from
# calling include(CPack), which would overwrite CPACK_GENERATOR ("ZIP") set by
# the SDK's cmake/cpp_pack.cmake.
set(CURL_DISABLE_INSTALL ON)

if(WIN32)
# Use Windows native Schannel/SSPI for TLS instead of OpenSSL/BoringSSL.
set(CURL_USE_SCHANNEL ON)
elseif(APPLE)
# Enable Apple Security.framework (SecTrust) native OS certificate
# verification alongside OpenSSL/BoringSSL, so macOS builds verify peers
# against the system Keychain rather than requiring a CA bundle file path.
set(USE_APPLE_SECTRUST ON)
# When curl detects static BoringSSL with a Clang toolchain, it appends
# ${_curl_stdlib_cxx} to its link interface. Override curl's default of
# "stdc++" (removed from modern Xcode SDKs) to Apple's "c++" (libc++).
set(_curl_stdlib_cxx "c++")
endif()

# Current Curl library defaults to requiring some dependencies we don't need, disable them.
set(CMAKE_USE_LIBSSH2 OFF)
set(HTTP_ONLY ON)
# Disable optional external libraries that curl 8.23.0 enables by default:
# - libssh2: SSH/SCP/SFTP protocol library (unused by Firebase REST).
# - libpsl: Public Suffix List cookie-domain library (unused).
# - nghttp2: HTTP/2 framing library (Firebase REST pins to HTTP/1.1).
# - libidn2: Internationalized Domain Names library (unused).
set(CURL_USE_LIBSSH2 OFF)
set(CURL_USE_LIBPSL OFF)
set(USE_NGHTTP2 OFF)
set(USE_LIBIDN2 OFF)

# Disable curl's built-in payload decompression libraries (zlib, brotli, zstd).
# Unlike option(), curl declares these three via set(... "AUTO" CACHE STRING)
# inside curl_dependency_option(), so a normal variable is ignored on the
# first configure (CMP0126 is OLD in curl's policy scope) and curl would
# auto-detect host libraries. Force them OFF in cache instead (Firebase's
# REST layer performs its own gzip compression via the bundled zlibstatic).
set(CURL_ZLIB OFF CACHE STRING "Build curl with ZLIB support" FORCE)
set(CURL_BROTLI OFF CACHE STRING "Build curl with brotli support" FORCE)
set(CURL_ZSTD OFF CACHE STRING "Build curl with zstd support" FORCE)

# curl 8.23.0 removed the legacy umbrella HTTP_ONLY option. Explicitly disable
# every non-HTTP(S) protocol so only HTTP and HTTPS are compiled into libcurl.
set(CURL_DISABLE_DICT ON)
set(CURL_DISABLE_FILE ON)
set(CURL_DISABLE_FTP ON)
set(CURL_DISABLE_GOPHER ON)
set(CURL_DISABLE_IMAP ON)
set(CURL_DISABLE_IPFS ON)
set(CURL_DISABLE_LDAP ON)
set(CURL_DISABLE_LDAPS ON)
set(CURL_DISABLE_MQTT ON)
set(CURL_DISABLE_POP3 ON)
set(CURL_DISABLE_RTSP ON)
set(CURL_DISABLE_SMTP ON)
set(CURL_DISABLE_TELNET ON)
set(CURL_DISABLE_TFTP ON)
set(CURL_DISABLE_WEBSOCKETS ON)

# Skip building curl's test suite and example binaries.
set(BUILD_TESTING OFF)
if(APPLE AND CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE)
# curl's CMake file checks for CMAKE_TOOLCHAIN_FILE rather than checking
# CMAKE_CROSSCOMPILING when determining whether we are cross-compiling.
# So if CMAKE_CROSSCOMPILING is set and we don't have a CMAKE_TOOLCHAIN_FILE,
# just add a null one now so curl is happy. This only happens on Mac when
# building for arm64/x86_64 on the opposite machine.
set(CMAKE_TOOLCHAIN_FILE /dev/null)
endif()
set(BUILD_EXAMPLES OFF)

add_external_library(curl)

# Clean up generic normal variables set specifically for curl so they do not
# leak into subsequent add_subdirectory() calls (libuv, zlib, firestore, etc.).
unset(BUILD_STATIC_LIBS)
unset(BUILD_EXAMPLES)

add_external_library(libuv)

add_external_library(zlib)
Expand Down
3 changes: 2 additions & 1 deletion analytics/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
set(ANALYTICS_WINDOWS_DLL "${FIREBASE_CPP_SDK_DIR}/analytics/windows/google_analytics.dll")

# For Windows, check if the Analytics DLL exists, and copy it in if so.
Expand Down
3 changes: 2 additions & 1 deletion app/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
12 changes: 9 additions & 3 deletions app/rest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,12 @@ target_compile_definitions(firebase_rest_lib

set(FIREBASE_CURL_DEPENDENCY libcurl)
if (MSVC)
# libcurl on Windows depends on internal Windows SSL via its crypt32 library.
set(FIREBASE_CURL_DEPENDENCY ${FIREBASE_CURL_DEPENDENCY} crypt32)
# libcurl on Windows (Schannel/SSPI) depends on these Windows SDK libraries:
# crypt32 (certificate store), bcrypt (BCryptGenRandom), iphlpapi
# (if_nametoindex) and secur32 (InitSecurityInterface). These are also
# pulled in via #pragma comment(lib) in transport_curl.cc for consumers of
# the merged firebase_app.lib.
set(FIREBASE_CURL_DEPENDENCY ${FIREBASE_CURL_DEPENDENCY} crypt32 bcrypt iphlpapi secur32)
endif()

# firebase_rest_lib has a dependency on flatbuffers, which needs to be included.
Expand Down Expand Up @@ -131,7 +135,9 @@ if(FIREBASE_CPP_BUILD_TESTS)
endif()

cpp_pack_library(firebase_rest_lib "deps/app")
cpp_pack_library(libcurl "deps/app/external")
# libcurl is an ALIAS of libcurl_static, and install(TARGETS) used by
# cpp_pack_library does not accept ALIAS targets, so pack the real target.
cpp_pack_library(libcurl_static "deps/app/external")
cpp_pack_library(zlibstatic "deps/app/external")
cpp_pack_library_file(${OPENSSL_SSL_LIBRARY} "deps/app/external")
cpp_pack_library_file(${OPENSSL_CRYPTO_LIBRARY} "deps/app/external")
49 changes: 28 additions & 21 deletions app/rest/transport_curl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@

#if FIREBASE_PLATFORM_WINDOWS
#include "Winsock2.h"
#if defined(_MSC_VER)
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "bcrypt.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "secur32.lib")
#pragma comment(lib, "ws2_32.lib")
#endif // defined(_MSC_VER)
#else
#include <sys/select.h>
#endif // FIREBASE_PLATFORM_WINDOWS
Expand Down Expand Up @@ -446,8 +454,7 @@ bool BackgroundTransportCurl::PerformBackground(Request* request) {

// Ensure that we are only accepting HTTP(S) traffic.
// TODO(73540740): Remove support for HTTP.
CheckOk(curl_easy_setopt(curl_, CURLOPT_PROTOCOLS,
CURLPROTO_HTTP | CURLPROTO_HTTPS),
CheckOk(curl_easy_setopt(curl_, CURLOPT_PROTOCOLS_STR, "http,https"),
"set valid protocols");

// Verify SSL.
Expand Down Expand Up @@ -475,7 +482,11 @@ bool BackgroundTransportCurl::PerformBackground(Request* request) {
CheckOk(curl_easy_setopt(curl_, CURLOPT_TIMEOUT_MS, options.timeout_ms),
"set http timeout milliseconds");

// curl library is using http2 as default, so need to specify this.
// Force HTTP/1.1 even when linked against a libcurl build that defaults to
// HTTP/2 (e.g., system libcurl or internal builds with nghttp2 enabled):
// Response::ProcessHeader() parses status lines with "HTTP/%*d.%*d %d", which
// does not match HTTP/2's "HTTP/2 200" status line, and streaming POST
// uploads rely on HTTP/1.1 "Transfer-Encoding: chunked".
CheckOk(curl_easy_setopt(curl_, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1),
"set http version to http1");

Expand Down Expand Up @@ -837,40 +848,36 @@ void CurlThread::ProcessRequests() {
// Update transfer status.
CURLINFO transferred_getter;
CURLINFO size_getter;
// According to the documentation, CURLINFO_CONTENT_LENGTH_(UP|DOWN)LOAD
// is deprecated in favor of CURLINFO_CONTENT_LENGTH_(UP|DOWN)LOAD_T,
// but it looks like our version of libcurl doesn't support the newer _T
// versions.
switch (controller->direction()) {
case kTransferDirectionUpload:
size_getter = CURLINFO_CONTENT_LENGTH_UPLOAD;
transferred_getter = CURLINFO_SIZE_UPLOAD;
static_assert((CURLINFO_CONTENT_LENGTH_UPLOAD &
CURLINFO_TYPEMASK) == CURLINFO_DOUBLE,
size_getter = CURLINFO_CONTENT_LENGTH_UPLOAD_T;
transferred_getter = CURLINFO_SIZE_UPLOAD_T;
static_assert((CURLINFO_CONTENT_LENGTH_UPLOAD_T &
CURLINFO_TYPEMASK) == CURLINFO_OFF_T,
"Unexpected transfer_size type");
static_assert(
(CURLINFO_SIZE_UPLOAD & CURLINFO_TYPEMASK) == CURLINFO_DOUBLE,
(CURLINFO_SIZE_UPLOAD_T & CURLINFO_TYPEMASK) == CURLINFO_OFF_T,
"Unexpected bytes_transferred type");
break;
case kTransferDirectionDownload:
size_getter = CURLINFO_CONTENT_LENGTH_DOWNLOAD;
transferred_getter = CURLINFO_SIZE_DOWNLOAD;
static_assert((CURLINFO_CONTENT_LENGTH_DOWNLOAD &
CURLINFO_TYPEMASK) == CURLINFO_DOUBLE,
size_getter = CURLINFO_CONTENT_LENGTH_DOWNLOAD_T;
transferred_getter = CURLINFO_SIZE_DOWNLOAD_T;
static_assert((CURLINFO_CONTENT_LENGTH_DOWNLOAD_T &
CURLINFO_TYPEMASK) == CURLINFO_OFF_T,
"Unexpected transfer_size type");
static_assert(
(CURLINFO_SIZE_DOWNLOAD & CURLINFO_TYPEMASK) == CURLINFO_DOUBLE,
"Unexpected bytes_transferred type");
static_assert((CURLINFO_SIZE_DOWNLOAD_T & CURLINFO_TYPEMASK) ==
CURLINFO_OFF_T,
"Unexpected bytes_transferred type");
break;
}

CURLcode code;
double value = 0.0;
curl_off_t value = 0;
code = curl_easy_getinfo(transport->curl(), size_getter, &value);
if (code == CURLE_OK) {
controller->set_transfer_size(static_cast<int64_t>(value));
}
value = 0.0;
value = 0;
code = curl_easy_getinfo(transport->curl(), transferred_getter, &value);
if (code == CURLE_OK) {
controller->set_bytes_transferred(static_cast<int64_t>(value));
Expand Down
3 changes: 2 additions & 1 deletion app_check/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 iphlpapi psapi userenv shell32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32 psapi userenv shell32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
3 changes: 2 additions & 1 deletion auth/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
4 changes: 3 additions & 1 deletion cmake/external/curl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ if(TARGET curl OR NOT DOWNLOAD_CURL)
return()
endif()

set(version 7_73_0)
set(version 8_23_0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The version 8_23_0 (curl 8.23.0) does not exist. The SHA256 hash d0605d5883124ef5ae64c6d2b307e1417c482b362583b57491fdf37d9a99a792 corresponds to curl version 8.2.1 (8_2_1). Using 8_23_0 will cause the download URL to return a 404 Not Found error, which will break the build. Please update the version to 8_2_1.

set(version 8_2_1)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


ExternalProject_Add(
curl

DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR}
DOWNLOAD_NAME curl-${version}.tar.gz
URL https://github.com/curl/curl/archive/curl-${version}.tar.gz
URL_HASH SHA256=d0605d5883124ef5ae64c6d2b307e1417c482b362583b57491fdf37d9a99a792

PREFIX ${PROJECT_BINARY_DIR}

Expand Down
3 changes: 2 additions & 1 deletion database/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 iphlpapi psapi userenv shell32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32 psapi userenv shell32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
2 changes: 1 addition & 1 deletion firestore/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ else()
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 dbghelp bcrypt)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32 dbghelp)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
2 changes: 1 addition & 1 deletion firestore/integration_test_internal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ else()
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
3 changes: 2 additions & 1 deletion functions/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
3 changes: 2 additions & 1 deletion installations/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
3 changes: 2 additions & 1 deletion messaging/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,10 @@ else()
"-framework Foundation"
"-framework GSS"
"-framework Security"
"-framework SystemConfiguration"
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 bcrypt iphlpapi secur32)
else()
set(ADDITIONAL_LIBS pthread)
endif()
Expand Down
2 changes: 1 addition & 1 deletion release_build_files/NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ curl

COPYRIGHT AND PERMISSION NOTICE

Copyright (c) 1996 - 2020, Daniel Stenberg, <daniel@haxx.se>, and many
Copyright (c) 1996 - 2026, Daniel Stenberg, <daniel@haxx.se>, and many
contributors, see the THANKS file.

All rights reserved.
Expand Down
Loading
Loading