From 6aae7ae5289011948b154574f150ce65c016cb6a Mon Sep 17 00:00:00 2001
From: David Li
Date: Tue, 28 Jul 2026 16:31:04 +0900
Subject: [PATCH 1/2] feat(c): require C++20 as the baseline
---
c/CMakeLists.txt | 2 +-
c/cmake_modules/AdbcDefines.cmake | 2 +-
c/cmake_modules/BuildUtils.cmake | 10 +-
c/driver/common/CMakeLists.txt | 2 +-
c/driver/flightsql/CMakeLists.txt | 2 +-
c/driver/framework/CMakeLists.txt | 2 +-
c/driver/postgresql/CMakeLists.txt | 4 +-
c/driver/sqlite/CMakeLists.txt | 2 +-
c/driver_manager/CMakeLists.txt | 4 +-
c/driver_manager/adbc_driver_manager.cc | 94 ++++++++++++++++
.../adbc_driver_manager_driver_loading.cc | 8 +-
c/driver_manager/adbc_driver_manager_test.cc | 6 +-
c/driver_manager/current_arch.h | 101 +-----------------
c/integration/duckdb/CMakeLists.txt | 2 +-
c/validation/CMakeLists.txt | 4 +-
ci/r_makevars_cxx20 | 23 ++++
compose.yaml | 1 +
go/adbc/drivermgr/adbc_driver_manager.cc | 94 ++++++++++++++++
.../adbc_driver_manager_driver_loading.cc | 8 +-
go/adbc/drivermgr/current_arch.h | 101 +-----------------
r/adbcdrivermanager/src/Makevars | 2 +-
r/adbcdrivermanager/src/Makevars.win | 2 +-
r/adbcdrivermanager/src/radbc.cc | 7 +-
r/adbcpostgresql/src/Makevars.in | 2 +-
r/adbcpostgresql/src/Makevars.ucrt | 2 +-
r/adbcpostgresql/src/Makevars.win | 2 +-
r/adbcsqlite/src/Makevars.in | 2 +-
27 files changed, 258 insertions(+), 233 deletions(-)
create mode 100644 ci/r_makevars_cxx20
diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt
index 89c31cd25b..76c2a1410b 100644
--- a/c/CMakeLists.txt
+++ b/c/CMakeLists.txt
@@ -23,7 +23,7 @@ project(adbc
VERSION "${ADBC_BASE_VERSION}"
LANGUAGES C CXX)
set(CMAKE_C_STANDARD 99)
-set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(AdbcDefines)
include(BuildUtils)
diff --git a/c/cmake_modules/AdbcDefines.cmake b/c/cmake_modules/AdbcDefines.cmake
index 12b593759f..df8230af2f 100644
--- a/c/cmake_modules/AdbcDefines.cmake
+++ b/c/cmake_modules/AdbcDefines.cmake
@@ -172,7 +172,7 @@ if(ADBC_BUILD_TESTS)
if(NOT GTest_FOUND)
message(STATUS "Building googletest from source")
# Required for GoogleTest
- set(CMAKE_CXX_STANDARD 17)
+ set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
fetchcontent_declare(googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
diff --git a/c/cmake_modules/BuildUtils.cmake b/c/cmake_modules/BuildUtils.cmake
index d7f4c20406..b76184b0e5 100644
--- a/c/cmake_modules/BuildUtils.cmake
+++ b/c/cmake_modules/BuildUtils.cmake
@@ -183,7 +183,7 @@ function(ADD_ARROW_LIB LIB_NAME)
${ARG_STATIC_LINK_LIBS})
adbc_configure_target(${LIB_NAME}_objlib)
# https://github.com/apache/arrow-adbc/issues/81
- target_compile_features(${LIB_NAME}_objlib PRIVATE cxx_std_11)
+ target_compile_features(${LIB_NAME}_objlib PRIVATE cxx_std_20)
else()
# Prepare arguments for separate compilation of static and shared libs below
# TODO: add PCH directives
@@ -199,7 +199,7 @@ function(ADD_ARROW_LIB LIB_NAME)
if(BUILD_SHARED)
add_library(${LIB_NAME}_shared SHARED ${LIB_DEPS})
- target_compile_features(${LIB_NAME}_shared PRIVATE cxx_std_17)
+ target_compile_features(${LIB_NAME}_shared PRIVATE cxx_std_20)
set_property(TARGET ${LIB_NAME}_shared PROPERTY CXX_STANDARD_REQUIRED ON)
adbc_configure_target(${LIB_NAME}_shared)
if(EXTRA_DEPS)
@@ -253,7 +253,7 @@ function(ADD_ARROW_LIB LIB_NAME)
endif()
# https://github.com/apache/arrow-adbc/issues/81
- target_compile_features(${LIB_NAME}_shared PRIVATE cxx_std_11)
+ target_compile_features(${LIB_NAME}_shared PRIVATE cxx_std_20)
target_link_libraries(${LIB_NAME}_shared
LINK_PUBLIC
@@ -317,7 +317,7 @@ function(ADD_ARROW_LIB LIB_NAME)
if(BUILD_STATIC)
add_library(${LIB_NAME}_static STATIC ${LIB_DEPS})
- target_compile_features(${LIB_NAME}_static PRIVATE cxx_std_11)
+ target_compile_features(${LIB_NAME}_static PRIVATE cxx_std_20)
set_property(TARGET ${LIB_NAME}_static PROPERTY CXX_STANDARD_REQUIRED ON)
adbc_configure_target(${LIB_NAME}_static)
if(EXTRA_DEPS)
@@ -352,7 +352,7 @@ function(ADD_ARROW_LIB LIB_NAME)
OUTPUT_NAME ${LIB_NAME_STATIC})
# https://github.com/apache/arrow-adbc/issues/81
- target_compile_features(${LIB_NAME}_static PRIVATE cxx_std_11)
+ target_compile_features(${LIB_NAME}_static PRIVATE cxx_std_20)
if(ARG_STATIC_INSTALL_INTERFACE_LIBS)
target_link_libraries(${LIB_NAME}_static LINK_PUBLIC
diff --git a/c/driver/common/CMakeLists.txt b/c/driver/common/CMakeLists.txt
index 07b9a50ad6..7275e94739 100644
--- a/c/driver/common/CMakeLists.txt
+++ b/c/driver/common/CMakeLists.txt
@@ -47,7 +47,7 @@ if(ADBC_BUILD_TESTS)
utils_test.cc
EXTRA_LINK_LIBS
adbc_driver_common)
- target_compile_features(adbc-driver-common-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-common-test PRIVATE cxx_std_20)
target_include_directories(adbc-driver-common-test
PRIVATE "${REPOSITORY_ROOT}/c/include")
adbc_configure_target(adbc-driver-common-test)
diff --git a/c/driver/flightsql/CMakeLists.txt b/c/driver/flightsql/CMakeLists.txt
index 3008334103..37c17efeea 100644
--- a/c/driver/flightsql/CMakeLists.txt
+++ b/c/driver/flightsql/CMakeLists.txt
@@ -75,7 +75,7 @@ if(ADBC_BUILD_TESTS)
endif()
endif()
- target_compile_features(adbc-driver-flightsql-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-flightsql-test PRIVATE cxx_std_20)
target_include_directories(adbc-driver-flightsql-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/ ${REPOSITORY_ROOT}/c/include/
${REPOSITORY_ROOT}/c/driver)
diff --git a/c/driver/framework/CMakeLists.txt b/c/driver/framework/CMakeLists.txt
index 464f3640cf..7c6e9ddac1 100644
--- a/c/driver/framework/CMakeLists.txt
+++ b/c/driver/framework/CMakeLists.txt
@@ -50,7 +50,7 @@ if(ADBC_BUILD_TESTS)
base_driver_test.cc
EXTRA_LINK_LIBS
adbc_driver_framework)
- target_compile_features(adbc-driver-framework-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-framework-test PRIVATE cxx_std_20)
target_include_directories(adbc-driver-framework-test
PRIVATE "${REPOSITORY_ROOT}/c/"
"${REPOSITORY_ROOT}/c/include"
diff --git a/c/driver/postgresql/CMakeLists.txt b/c/driver/postgresql/CMakeLists.txt
index b18dab6d4a..980c3e80da 100644
--- a/c/driver/postgresql/CMakeLists.txt
+++ b/c/driver/postgresql/CMakeLists.txt
@@ -89,7 +89,7 @@ if(ADBC_BUILD_TESTS)
adbc_driver_common
adbc_validation
${TEST_LINK_LIBS})
- target_compile_features(adbc-driver-postgresql-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-postgresql-test PRIVATE cxx_std_20)
target_compile_definitions(adbc-driver-postgresql-test
PRIVATE ADBC_POSTGRESQL_TESTDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/testdata"
)
@@ -110,7 +110,7 @@ if(ADBC_BUILD_TESTS)
adbc_driver_common
adbc_validation
${TEST_LINK_LIBS})
- target_compile_features(adbc-driver-postgresql-copy-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-postgresql-copy-test PRIVATE cxx_std_20)
target_include_directories(adbc-driver-postgresql-copy-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/
${REPOSITORY_ROOT}/c/include/
diff --git a/c/driver/sqlite/CMakeLists.txt b/c/driver/sqlite/CMakeLists.txt
index fcaf74488c..9147d5d6e9 100644
--- a/c/driver/sqlite/CMakeLists.txt
+++ b/c/driver/sqlite/CMakeLists.txt
@@ -110,7 +110,7 @@ if(ADBC_BUILD_TESTS)
${TEST_LINK_LIBS})
target_compile_definitions(adbc-driver-sqlite-test
PRIVATE ${ADBC_SQLITE_COMPILE_DEFINES})
- target_compile_features(adbc-driver-sqlite-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-sqlite-test PRIVATE cxx_std_20)
target_include_directories(adbc-driver-sqlite-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/ ${REPOSITORY_ROOT}/c/include/
${LIBPQ_INCLUDE_DIRS} ${REPOSITORY_ROOT}/c/driver)
diff --git a/c/driver_manager/CMakeLists.txt b/c/driver_manager/CMakeLists.txt
index 52c3fe46aa..b13ad91614 100644
--- a/c/driver_manager/CMakeLists.txt
+++ b/c/driver_manager/CMakeLists.txt
@@ -108,7 +108,7 @@ if(ADBC_BUILD_TESTS)
adbc_driver_common
adbc_validation
${TEST_LINK_LIBS})
- target_compile_features(adbc-driver-manager-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-driver-manager-test PRIVATE cxx_std_20)
add_dependencies(adbc-driver-manager-test adbc_driver_entrypoint
adbc_driver_no_entrypoint)
@@ -153,7 +153,7 @@ if(ADBC_BUILD_TESTS)
EXTRA_LINK_LIBS
adbc_validation_util
${TEST_LINK_LIBS})
- target_compile_features(adbc-version-100-compatibility-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-version-100-compatibility-test PRIVATE cxx_std_20)
target_include_directories(adbc-version-100-compatibility-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/ ${REPOSITORY_ROOT}/c/include/
${LIBPQ_INCLUDE_DIRS} ${REPOSITORY_ROOT}/c/driver)
diff --git a/c/driver_manager/adbc_driver_manager.cc b/c/driver_manager/adbc_driver_manager.cc
index b3acca942b..1a9fe7f368 100644
--- a/c/driver_manager/adbc_driver_manager.cc
+++ b/c/driver_manager/adbc_driver_manager.cc
@@ -104,6 +104,100 @@ std::string CheckNonPrintableLibraryName(const std::string& name) {
return error_message;
}
+const std::string& InternalAdbcCurrentArch() {
+#if defined(_WIN32)
+ static const std::string platform = "windows";
+#elif defined(__APPLE__)
+ static const std::string platform = "macos";
+#elif defined(__FreeBSD__)
+ static const std::string platform = "freebsd";
+#elif defined(__OpenBSD__)
+ static const std::string platform = "openbsd";
+#elif defined(__linux__)
+ static const std::string platform = "linux";
+#else
+ static const std::string platform = "unknown";
+#endif
+
+#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64)
+ static const std::string arch = "amd64";
+#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__ARM_ARCH_ISA_A64)
+#ifdef ADBC_LITTLE_ENDIAN
+ static const std::string arch = "arm64";
+#else
+ static const std::string arch = "arm64be";
+#endif
+#elif defined(__i386__) || defined(_M_IX86) || defined(_M_X86)
+ static const std::string arch = "x86";
+#elif defined(__arm__) || defined(_M_ARM)
+#ifdef ADBC_LITTLE_ENDIAN
+ static const std::string arch = "arm";
+#else
+ static const std::string arch = "armbe";
+#endif
+#elif defined(__riscv) || defined(_M_RISCV)
+#if defined(__riscv_xlen) && __riscv_xlen == 64
+ static const std::string arch = "riscv64";
+#else
+ static const std::string arch = "riscv";
+#endif
+#elif defined(__ppc64__) || defined(__powerpc64__)
+#ifdef ADBC_LITTLE_ENDIAN
+ static const std::string arch = "powerpc64le";
+#else
+ static const std::string arch = "powerpc64";
+#endif
+#elif defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
+ static const std::string arch = "powerpc";
+#elif defined(__s390x__) || defined(_M_S390)
+ static const std::string arch = "s390x";
+#elif defined(__sparc__) || defined(__sparc)
+#if defined(_LP64) || defined(__LP64__)
+ static const std::string arch = "sparc64";
+#else
+ static const std::string arch = "sparc";
+#endif
+#elif defined(__wasm32__)
+ static const std::string arch = "wasm32";
+#elif defined(__wasm64__)
+ static const std::string arch = "wasm64";
+#else
+ static const std::string arch = "unknown";
+#endif
+
+// musl doesn't actually define any preprocessor macro for itself
+// but apparently it doesn't define __USE_GNU inside of features.h
+// while gcc DOES define that.
+// see https://stackoverflow.com/questions/58177815/how-to-actually-detect-musl-libc
+#if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
+#else
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#include // NOLINT [build/include]
+#ifndef __USE_GNU
+#define __MUSL__
+#endif
+#undef _GNU_SOURCE /* don't contaminate other includes unnecessarily */
+#else
+#include // NOLINT [build/include]
+#ifndef __USE_GNU
+#define __MUSL__
+#endif
+#endif
+#endif
+
+#if defined(__MINGW32__) || defined(__MINGW64__)
+ static const std::string target = "_mingw";
+#elif defined(__MUSL__)
+ static const std::string target = "_musl";
+#else
+ static const std::string target = "";
+#endif
+
+ static const std::string result = platform + "_" + arch + target;
+ return result;
+}
+
// Platform-specific helpers
#if defined(_WIN32)
diff --git a/c/driver_manager/adbc_driver_manager_driver_loading.cc b/c/driver_manager/adbc_driver_manager_driver_loading.cc
index 632184b580..c179560578 100644
--- a/c/driver_manager/adbc_driver_manager_driver_loading.cc
+++ b/c/driver_manager/adbc_driver_manager_driver_loading.cc
@@ -195,12 +195,12 @@ AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
auto driver = config.at_path("Driver.shared");
if (toml::table* platforms = driver.as_table()) {
- auto view = platforms->at_path(adbc::CurrentArch());
+ auto view = platforms->at_path(InternalAdbcCurrentArch());
if (!view) {
std::string message = "Driver path not found in manifest '";
message += driver_manifest.string();
message += "' for current architecture '";
- message += adbc::CurrentArch();
+ message += InternalAdbcCurrentArch();
message += "'. Architectures found:";
for (const auto& [key, val] : *platforms) {
message += " ";
@@ -213,7 +213,7 @@ AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
std::string message = "Driver path is an empty string in manifest '";
message += driver_manifest.string();
message += "' for current architecture '";
- message += adbc::CurrentArch();
+ message += InternalAdbcCurrentArch();
message += "'";
SetError(error, std::move(message));
return ADBC_STATUS_INVALID_ARGUMENT;
@@ -225,7 +225,7 @@ AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
std::string message = "Driver path not found in manifest '";
message += driver_manifest.string();
message += "' for current architecture '";
- message += adbc::CurrentArch();
+ message += InternalAdbcCurrentArch();
message += "'. Value was not a string";
SetError(error, std::move(message));
return ADBC_STATUS_INVALID_ARGUMENT;
diff --git a/c/driver_manager/adbc_driver_manager_test.cc b/c/driver_manager/adbc_driver_manager_test.cc
index 823b862bb1..3417b90c81 100644
--- a/c/driver_manager/adbc_driver_manager_test.cc
+++ b/c/driver_manager/adbc_driver_manager_test.cc
@@ -716,7 +716,7 @@ class DriverManifest : public ::testing::Test {
toml::table{
{"shared",
toml::table{
- {adbc::CurrentArch(), driver_path.string()},
+ {InternalAdbcCurrentArch(), driver_path.string()},
}},
}},
};
@@ -829,7 +829,7 @@ TEST_F(DriverManifest, ConfigEntrypoint) {
{"entrypoint", "BadEntrypointSymbolName"},
{"shared",
toml::table{
- {adbc::CurrentArch(), driver_path.string()},
+ {InternalAdbcCurrentArch(), driver_path.string()},
}},
});
@@ -2166,7 +2166,7 @@ class DriverUriProfileTest : public ConnectionProfiles,
toml::table{
{"shared",
toml::table{
- {adbc::CurrentArch(), driver_path.string()},
+ {InternalAdbcCurrentArch(), driver_path.string()},
}},
}},
};
diff --git a/c/driver_manager/current_arch.h b/c/driver_manager/current_arch.h
index e6b475ec02..6c30094253 100644
--- a/c/driver_manager/current_arch.h
+++ b/c/driver_manager/current_arch.h
@@ -19,6 +19,8 @@
#include
+#include "arrow-adbc/adbc.h"
+
#if defined(_WIN32)
#define ADBC_LITTLE_ENDIAN 1
#else
@@ -40,100 +42,5 @@
#endif
#endif
-namespace adbc {
-
-inline const std::string& CurrentArch() {
-#if defined(_WIN32)
- static const std::string platform = "windows";
-#elif defined(__APPLE__)
- static const std::string platform = "macos";
-#elif defined(__FreeBSD__)
- static const std::string platform = "freebsd";
-#elif defined(__OpenBSD__)
- static const std::string platform = "openbsd";
-#elif defined(__linux__)
- static const std::string platform = "linux";
-#else
- static const std::string platform = "unknown";
-#endif
-
-#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64)
- static const std::string arch = "amd64";
-#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__ARM_ARCH_ISA_A64)
-#ifdef ADBC_LITTLE_ENDIAN
- static const std::string arch = "arm64";
-#else
- static const std::string arch = "arm64be";
-#endif
-#elif defined(__i386__) || defined(_M_IX86) || defined(_M_X86)
- static const std::string arch = "x86";
-#elif defined(__arm__) || defined(_M_ARM)
-#ifdef ADBC_LITTLE_ENDIAN
- static const std::string arch = "arm";
-#else
- static const std::string arch = "armbe";
-#endif
-#elif defined(__riscv) || defined(_M_RISCV)
-#if defined(__riscv_xlen) && __riscv_xlen == 64
- static const std::string arch = "riscv64";
-#else
- static const std::string arch = "riscv";
-#endif
-#elif defined(__ppc64__) || defined(__powerpc64__)
-#ifdef ADBC_LITTLE_ENDIAN
- static const std::string arch = "powerpc64le";
-#else
- static const std::string arch = "powerpc64";
-#endif
-#elif defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
- static const std::string arch = "powerpc";
-#elif defined(__s390x__) || defined(_M_S390)
- static const std::string arch = "s390x";
-#elif defined(__sparc__) || defined(__sparc)
-#if defined(_LP64) || defined(__LP64__)
- static const std::string arch = "sparc64";
-#else
- static const std::string arch = "sparc";
-#endif
-#elif defined(__wasm32__)
- static const std::string arch = "wasm32";
-#elif defined(__wasm64__)
- static const std::string arch = "wasm64";
-#else
- static const std::string arch = "unknown";
-#endif
-
-// musl doesn't actually define any preprocessor macro for itself
-// but apparently it doesn't define __USE_GNU inside of features.h
-// while gcc DOES define that.
-// see https://stackoverflow.com/questions/58177815/how-to-actually-detect-musl-libc
-#if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
-#else
-#if !defined(_GNU_SOURCE)
-#define _GNU_SOURCE
-#include // NOLINT [build/include]
-#ifndef __USE_GNU
-#define __MUSL__
-#endif
-#undef _GNU_SOURCE /* don't contaminate other includes unnecessarily */
-#else
-#include // NOLINT [build/include]
-#ifndef __USE_GNU
-#define __MUSL__
-#endif
-#endif
-#endif
-
-#if defined(__MINGW32__) || defined(__MINGW64__)
- static const std::string target = "_mingw";
-#elif defined(__MUSL__)
- static const std::string target = "_musl";
-#else
- static const std::string target = "";
-#endif
-
- static const std::string result = platform + "_" + arch + target;
- return result;
-}
-
-} // namespace adbc
+ADBC_EXPORT
+const std::string& InternalAdbcCurrentArch();
diff --git a/c/integration/duckdb/CMakeLists.txt b/c/integration/duckdb/CMakeLists.txt
index 1db2575d6c..d4b3db0c05 100644
--- a/c/integration/duckdb/CMakeLists.txt
+++ b/c/integration/duckdb/CMakeLists.txt
@@ -65,7 +65,7 @@ if(ADBC_BUILD_TESTS)
adbc_validation
duckdb)
add_dependencies(adbc-integration-duckdb-test duckdb)
- target_compile_features(adbc-integration-duckdb-test PRIVATE cxx_std_17)
+ target_compile_features(adbc-integration-duckdb-test PRIVATE cxx_std_20)
target_include_directories(adbc-integration-duckdb-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/ ${REPOSITORY_ROOT}/c/include/
${REPOSITORY_ROOT}/c/driver)
diff --git a/c/validation/CMakeLists.txt b/c/validation/CMakeLists.txt
index 02362259f5..8f6d989071 100644
--- a/c/validation/CMakeLists.txt
+++ b/c/validation/CMakeLists.txt
@@ -17,7 +17,7 @@
add_library(adbc_validation_util STATIC adbc_validation_util.cc)
adbc_configure_target(adbc_validation_util)
-target_compile_features(adbc_validation_util PRIVATE cxx_std_17)
+target_compile_features(adbc_validation_util PRIVATE cxx_std_20)
target_include_directories(adbc_validation_util SYSTEM
PRIVATE "${REPOSITORY_ROOT}/c/include/"
"${REPOSITORY_ROOT}/c/driver/")
@@ -28,7 +28,7 @@ add_library(adbc_validation OBJECT
adbc_validation.cc adbc_validation_connection.cc adbc_validation_database.cc
adbc_validation_statement.cc)
adbc_configure_target(adbc_validation)
-target_compile_features(adbc_validation PRIVATE cxx_std_17)
+target_compile_features(adbc_validation PRIVATE cxx_std_20)
target_include_directories(adbc_validation SYSTEM PRIVATE "${REPOSITORY_ROOT}/c/include/"
"${REPOSITORY_ROOT}/c/driver/")
target_link_libraries(adbc_validation PUBLIC adbc_driver_common adbc_validation_util
diff --git a/ci/r_makevars_cxx20 b/ci/r_makevars_cxx20
new file mode 100644
index 0000000000..2d030a4490
--- /dev/null
+++ b/ci/r_makevars_cxx20
@@ -0,0 +1,23 @@
+# 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.
+
+# conda-forge's R package doesn't define C++20 compiler settings, even though
+# its compiler supports C++20; define the flags to get the docs build to work
+CXX20 = $(CXX17)
+CXX20FLAGS = $(CXX17FLAGS)
+CXX20PICFLAGS = $(CXX17PICFLAGS)
+CXX20STD = -std=gnu++20
diff --git a/compose.yaml b/compose.yaml
index 4b67f755a9..4a978f560c 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -100,6 +100,7 @@ services:
ADBC_USE_ASAN: "0"
ADBC_USE_UBSAN: "0"
CGO_ENABLED: "1"
+ R_MAKEVARS_USER: "/adbc/ci/r_makevars_cxx20"
command: |
/bin/bash -c 'git config --global --add safe.directory /adbc && source /opt/conda/etc/profile.d/conda.sh && mamba create -y -n adbc -c conda-forge go --file /adbc/ci/conda_env_cpp.txt --file /adbc/ci/conda_env_docs.txt --file /adbc/ci/conda_env_java.txt --file /adbc/ci/conda_env_python.txt && conda activate adbc && /adbc/ci/scripts/cpp_build.sh /adbc /adbc/build && /adbc/ci/scripts/go_build.sh /adbc /adbc/build && /adbc/ci/scripts/python_build.sh /adbc /adbc/build && /adbc/ci/scripts/r_build.sh /adbc && /adbc/ci/scripts/make_manifests.sh /adbc/build/local && /adbc/ci/scripts/docs_build.sh /adbc'
diff --git a/go/adbc/drivermgr/adbc_driver_manager.cc b/go/adbc/drivermgr/adbc_driver_manager.cc
index b3acca942b..1a9fe7f368 100644
--- a/go/adbc/drivermgr/adbc_driver_manager.cc
+++ b/go/adbc/drivermgr/adbc_driver_manager.cc
@@ -104,6 +104,100 @@ std::string CheckNonPrintableLibraryName(const std::string& name) {
return error_message;
}
+const std::string& InternalAdbcCurrentArch() {
+#if defined(_WIN32)
+ static const std::string platform = "windows";
+#elif defined(__APPLE__)
+ static const std::string platform = "macos";
+#elif defined(__FreeBSD__)
+ static const std::string platform = "freebsd";
+#elif defined(__OpenBSD__)
+ static const std::string platform = "openbsd";
+#elif defined(__linux__)
+ static const std::string platform = "linux";
+#else
+ static const std::string platform = "unknown";
+#endif
+
+#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64)
+ static const std::string arch = "amd64";
+#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__ARM_ARCH_ISA_A64)
+#ifdef ADBC_LITTLE_ENDIAN
+ static const std::string arch = "arm64";
+#else
+ static const std::string arch = "arm64be";
+#endif
+#elif defined(__i386__) || defined(_M_IX86) || defined(_M_X86)
+ static const std::string arch = "x86";
+#elif defined(__arm__) || defined(_M_ARM)
+#ifdef ADBC_LITTLE_ENDIAN
+ static const std::string arch = "arm";
+#else
+ static const std::string arch = "armbe";
+#endif
+#elif defined(__riscv) || defined(_M_RISCV)
+#if defined(__riscv_xlen) && __riscv_xlen == 64
+ static const std::string arch = "riscv64";
+#else
+ static const std::string arch = "riscv";
+#endif
+#elif defined(__ppc64__) || defined(__powerpc64__)
+#ifdef ADBC_LITTLE_ENDIAN
+ static const std::string arch = "powerpc64le";
+#else
+ static const std::string arch = "powerpc64";
+#endif
+#elif defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
+ static const std::string arch = "powerpc";
+#elif defined(__s390x__) || defined(_M_S390)
+ static const std::string arch = "s390x";
+#elif defined(__sparc__) || defined(__sparc)
+#if defined(_LP64) || defined(__LP64__)
+ static const std::string arch = "sparc64";
+#else
+ static const std::string arch = "sparc";
+#endif
+#elif defined(__wasm32__)
+ static const std::string arch = "wasm32";
+#elif defined(__wasm64__)
+ static const std::string arch = "wasm64";
+#else
+ static const std::string arch = "unknown";
+#endif
+
+// musl doesn't actually define any preprocessor macro for itself
+// but apparently it doesn't define __USE_GNU inside of features.h
+// while gcc DOES define that.
+// see https://stackoverflow.com/questions/58177815/how-to-actually-detect-musl-libc
+#if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
+#else
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#include // NOLINT [build/include]
+#ifndef __USE_GNU
+#define __MUSL__
+#endif
+#undef _GNU_SOURCE /* don't contaminate other includes unnecessarily */
+#else
+#include // NOLINT [build/include]
+#ifndef __USE_GNU
+#define __MUSL__
+#endif
+#endif
+#endif
+
+#if defined(__MINGW32__) || defined(__MINGW64__)
+ static const std::string target = "_mingw";
+#elif defined(__MUSL__)
+ static const std::string target = "_musl";
+#else
+ static const std::string target = "";
+#endif
+
+ static const std::string result = platform + "_" + arch + target;
+ return result;
+}
+
// Platform-specific helpers
#if defined(_WIN32)
diff --git a/go/adbc/drivermgr/adbc_driver_manager_driver_loading.cc b/go/adbc/drivermgr/adbc_driver_manager_driver_loading.cc
index 632184b580..c179560578 100644
--- a/go/adbc/drivermgr/adbc_driver_manager_driver_loading.cc
+++ b/go/adbc/drivermgr/adbc_driver_manager_driver_loading.cc
@@ -195,12 +195,12 @@ AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
auto driver = config.at_path("Driver.shared");
if (toml::table* platforms = driver.as_table()) {
- auto view = platforms->at_path(adbc::CurrentArch());
+ auto view = platforms->at_path(InternalAdbcCurrentArch());
if (!view) {
std::string message = "Driver path not found in manifest '";
message += driver_manifest.string();
message += "' for current architecture '";
- message += adbc::CurrentArch();
+ message += InternalAdbcCurrentArch();
message += "'. Architectures found:";
for (const auto& [key, val] : *platforms) {
message += " ";
@@ -213,7 +213,7 @@ AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
std::string message = "Driver path is an empty string in manifest '";
message += driver_manifest.string();
message += "' for current architecture '";
- message += adbc::CurrentArch();
+ message += InternalAdbcCurrentArch();
message += "'";
SetError(error, std::move(message));
return ADBC_STATUS_INVALID_ARGUMENT;
@@ -225,7 +225,7 @@ AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
std::string message = "Driver path not found in manifest '";
message += driver_manifest.string();
message += "' for current architecture '";
- message += adbc::CurrentArch();
+ message += InternalAdbcCurrentArch();
message += "'. Value was not a string";
SetError(error, std::move(message));
return ADBC_STATUS_INVALID_ARGUMENT;
diff --git a/go/adbc/drivermgr/current_arch.h b/go/adbc/drivermgr/current_arch.h
index e6b475ec02..6c30094253 100644
--- a/go/adbc/drivermgr/current_arch.h
+++ b/go/adbc/drivermgr/current_arch.h
@@ -19,6 +19,8 @@
#include
+#include "arrow-adbc/adbc.h"
+
#if defined(_WIN32)
#define ADBC_LITTLE_ENDIAN 1
#else
@@ -40,100 +42,5 @@
#endif
#endif
-namespace adbc {
-
-inline const std::string& CurrentArch() {
-#if defined(_WIN32)
- static const std::string platform = "windows";
-#elif defined(__APPLE__)
- static const std::string platform = "macos";
-#elif defined(__FreeBSD__)
- static const std::string platform = "freebsd";
-#elif defined(__OpenBSD__)
- static const std::string platform = "openbsd";
-#elif defined(__linux__)
- static const std::string platform = "linux";
-#else
- static const std::string platform = "unknown";
-#endif
-
-#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64)
- static const std::string arch = "amd64";
-#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__ARM_ARCH_ISA_A64)
-#ifdef ADBC_LITTLE_ENDIAN
- static const std::string arch = "arm64";
-#else
- static const std::string arch = "arm64be";
-#endif
-#elif defined(__i386__) || defined(_M_IX86) || defined(_M_X86)
- static const std::string arch = "x86";
-#elif defined(__arm__) || defined(_M_ARM)
-#ifdef ADBC_LITTLE_ENDIAN
- static const std::string arch = "arm";
-#else
- static const std::string arch = "armbe";
-#endif
-#elif defined(__riscv) || defined(_M_RISCV)
-#if defined(__riscv_xlen) && __riscv_xlen == 64
- static const std::string arch = "riscv64";
-#else
- static const std::string arch = "riscv";
-#endif
-#elif defined(__ppc64__) || defined(__powerpc64__)
-#ifdef ADBC_LITTLE_ENDIAN
- static const std::string arch = "powerpc64le";
-#else
- static const std::string arch = "powerpc64";
-#endif
-#elif defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
- static const std::string arch = "powerpc";
-#elif defined(__s390x__) || defined(_M_S390)
- static const std::string arch = "s390x";
-#elif defined(__sparc__) || defined(__sparc)
-#if defined(_LP64) || defined(__LP64__)
- static const std::string arch = "sparc64";
-#else
- static const std::string arch = "sparc";
-#endif
-#elif defined(__wasm32__)
- static const std::string arch = "wasm32";
-#elif defined(__wasm64__)
- static const std::string arch = "wasm64";
-#else
- static const std::string arch = "unknown";
-#endif
-
-// musl doesn't actually define any preprocessor macro for itself
-// but apparently it doesn't define __USE_GNU inside of features.h
-// while gcc DOES define that.
-// see https://stackoverflow.com/questions/58177815/how-to-actually-detect-musl-libc
-#if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
-#else
-#if !defined(_GNU_SOURCE)
-#define _GNU_SOURCE
-#include // NOLINT [build/include]
-#ifndef __USE_GNU
-#define __MUSL__
-#endif
-#undef _GNU_SOURCE /* don't contaminate other includes unnecessarily */
-#else
-#include // NOLINT [build/include]
-#ifndef __USE_GNU
-#define __MUSL__
-#endif
-#endif
-#endif
-
-#if defined(__MINGW32__) || defined(__MINGW64__)
- static const std::string target = "_mingw";
-#elif defined(__MUSL__)
- static const std::string target = "_musl";
-#else
- static const std::string target = "";
-#endif
-
- static const std::string result = platform + "_" + arch + target;
- return result;
-}
-
-} // namespace adbc
+ADBC_EXPORT
+const std::string& InternalAdbcCurrentArch();
diff --git a/r/adbcdrivermanager/src/Makevars b/r/adbcdrivermanager/src/Makevars
index 9fb3d05c27..5476c6e35f 100644
--- a/r/adbcdrivermanager/src/Makevars
+++ b/r/adbcdrivermanager/src/Makevars
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-CXX_STD = CXX17
+CXX_STD = CXX20
CONDA_BUILD ?= "0"
PKG_CPPFLAGS=-I../src/c/include -I../src/c -I../src/c/vendor -DADBC_EXPORT="" -DADBC_CONDA_BUILD=$(CONDA_BUILD)
diff --git a/r/adbcdrivermanager/src/Makevars.win b/r/adbcdrivermanager/src/Makevars.win
index 908b9439b0..6a086d3691 100644
--- a/r/adbcdrivermanager/src/Makevars.win
+++ b/r/adbcdrivermanager/src/Makevars.win
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-CXX_STD = CXX17
+CXX_STD = CXX20
CONDA_BUILD ?= "0"
PKG_CPPFLAGS=-I../src/c/include -I../src/c -I../src/c/vendor -DADBC_EXPORT="" -DADBC_CONDA_BUILD=$(CONDA_BUILD)
PKG_LIBS=-lshell32 -ladvapi32 -luuid
diff --git a/r/adbcdrivermanager/src/radbc.cc b/r/adbcdrivermanager/src/radbc.cc
index 22565cde69..a81e47cb2e 100644
--- a/r/adbcdrivermanager/src/radbc.cc
+++ b/r/adbcdrivermanager/src/radbc.cc
@@ -102,12 +102,11 @@ static void finalize_database_xptr(SEXP database_xptr) {
adbc_xptr_default_finalize(database_xptr);
}
-namespace adbc {
-const std::string& CurrentArch();
-}
+// Forward declared from the driver manager; we can't use its internal header here
+const std::string& InternalAdbcCurrentArch();
extern "C" SEXP RAdbcCurrentArch(void) {
- auto current_arch = adbc::CurrentArch();
+ auto current_arch = InternalAdbcCurrentArch();
return Rf_mkString(current_arch.c_str());
}
diff --git a/r/adbcpostgresql/src/Makevars.in b/r/adbcpostgresql/src/Makevars.in
index 45320aa7d5..b35a4dc85b 100644
--- a/r/adbcpostgresql/src/Makevars.in
+++ b/r/adbcpostgresql/src/Makevars.in
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-CXX_STD = CXX17
+CXX_STD = CXX20
PKG_CPPFLAGS=-I../src/c -I../src/c/include -I../src/c/vendor/ -I../src/c/vendor/portable-snippets/include/ -I../src/c/vendor/fmt/include @cppflags@ -DADBC_EXPORT="" -DFMT_HEADER_ONLY=1
PKG_LIBS=@libs@
diff --git a/r/adbcpostgresql/src/Makevars.ucrt b/r/adbcpostgresql/src/Makevars.ucrt
index 3a14f02dcd..77ec9c666a 100644
--- a/r/adbcpostgresql/src/Makevars.ucrt
+++ b/r/adbcpostgresql/src/Makevars.ucrt
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-CXX_STD = CXX17
+CXX_STD = CXX20
PKG_CPPFLAGS = -I../src/c -I../src/c/include -I../src/c/vendor/ -I../src/c/vendor/portable-snippets/include/ -I../src/c/vendor/fmt/include -DADBC_EXPORT="" -D__USE_MINGW_ANSI_STDIO -DFMT_HEADER_ONLY=1
PKG_LIBS = -lpq -lpgcommon -lpgport -lssl -lcrypto -lz -lsecur32 -lws2_32 -lwldap32 -lcrypt32
diff --git a/r/adbcpostgresql/src/Makevars.win b/r/adbcpostgresql/src/Makevars.win
index 077a69ea10..aaba18ecfc 100644
--- a/r/adbcpostgresql/src/Makevars.win
+++ b/r/adbcpostgresql/src/Makevars.win
@@ -17,7 +17,7 @@
VERSION = 13.2.0
RWINLIB = ../windows/libpq-$(VERSION)
-CXX_STD = CXX17
+CXX_STD = CXX20
PKG_CPPFLAGS = -I$(RWINLIB)/include -I../src/c -I../src/c/include -I../src/c/vendor/ -I../src/c/vendor/portable-snippets/include/ -I../src/c/vendor/fmt/include -DADBC_EXPORT="" -D__USE_MINGW_ANSI_STDIO -DFMT_HEADER_ONLY=1
PKG_LIBS = -L$(RWINLIB)/lib${R_ARCH}${CRT} \
-lpq -lpgport -lpgcommon -lssl -lcrypto -lwsock32 -lsecur32 -lws2_32 -lgdi32 -lcrypt32 -lwldap32
diff --git a/r/adbcsqlite/src/Makevars.in b/r/adbcsqlite/src/Makevars.in
index 675ff8cd2d..53a68c0cf7 100644
--- a/r/adbcsqlite/src/Makevars.in
+++ b/r/adbcsqlite/src/Makevars.in
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-CXX_STD = CXX17
+CXX_STD = CXX20
PKG_CPPFLAGS=-I../src/c -I../src/c/include -I../src/c/vendor/ -I../src/c/vendor/fmt/include @cppflags@ -DADBC_EXPORT="" -DFMT_HEADER_ONLY=1
PKG_LIBS=@libs@
From 95a2216432ab09cde39b038991bd2abc1c4f5813 Mon Sep 17 00:00:00 2001
From: David Li
Date: Thu, 30 Jul 2026 11:40:56 +0900
Subject: [PATCH 2/2] update docs
---
docs/source/cpp/recipe/quickstart.cc | 4 ++--
docs/source/cpp/recipe_driver/driver_example.cc | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/source/cpp/recipe/quickstart.cc b/docs/source/cpp/recipe/quickstart.cc
index 36a5e19d68..0148094d65 100644
--- a/docs/source/cpp/recipe/quickstart.cc
+++ b/docs/source/cpp/recipe/quickstart.cc
@@ -18,7 +18,7 @@
// RECIPE STARTS HERE
/// Here we'll briefly tour basic features of ADBC with the SQLite
-/// driver in C++17.
+/// driver in C++20.
/// Installation
/// ============
@@ -27,7 +27,7 @@
/// the repository, build the sample, and follow along.
///
/// We'll assume you're using conda-forge_ for dependencies. CMake, a
-/// C++17 compiler, and the ADBC libraries are required. They can be
+/// C++20 compiler, and the ADBC libraries are required. They can be
/// installed as follows:
///
/// .. code-block:: shell
diff --git a/docs/source/cpp/recipe_driver/driver_example.cc b/docs/source/cpp/recipe_driver/driver_example.cc
index 5b4685ba8f..bba7d280ad 100644
--- a/docs/source/cpp/recipe_driver/driver_example.cc
+++ b/docs/source/cpp/recipe_driver/driver_example.cc
@@ -36,7 +36,7 @@
/// the repository, build the sample, and follow along.
///
/// We'll assume you're using conda-forge_ for dependencies. CMake, a
-/// C++17 compiler, and the ADBC libraries are required. They can be
+/// C++20 compiler, and the ADBC libraries are required. They can be
/// installed as follows:
///
/// .. code-block:: shell
@@ -193,7 +193,7 @@ class DriverExampleDatabase : public adbc::driver::Database {