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 {