This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 22b954ddb fix(c): Generate versioned DLLs and import LIBs when
building with MSVC (#2858)
22b954ddb is described below
commit 22b954ddb53267e7a70ca0b6521522ddc2f1f312
Author: Ali Alamiri <[email protected]>
AuthorDate: Fri Dec 26 07:41:25 2025 +0000
fix(c): Generate versioned DLLs and import LIBs when building with MSVC
(#2858)
Hi.
This is to address building binaries and LIBs on Windows. The PR is
mainly for consideration purposes, as it's my first PR against this repo
so not necessarily a complete one. Following are the changes I needed to
make:
- Disable ASAN/UBSAN builds configs as they require GCC/Clang, and on
Windows we're building with MSVC.
- An environment variable to `vcpkg` root is expected so that third
party packages (sqlite, postgres etc) can be installed and found via
vcpkg.
- Disable some warnings for testing code that are safe to ignore for
MSVC builds.
- Ensure the generated binaries have file level details (Details tab on
the file properties in Windows) for the version. This is required by
Windows MSIs that may be used to install the adbc DLLs in order to
detect if the DLL being installed is a newer or older version.
- Generate import LIB file for drivers built with go build, which
includes flight SQL and Snowflake drivers. This allows the testing
projects referencing those DLLs to built on Windows.
- The `GoUtils.cmake` is not automatically copying the driver DLLs to
the location of the test executables, causing the tests for those
drivers to fail. Added a post build command to ensure the DLLs are
copied.
- Fix some type casting mismatch (casting between size_t and int).
- Fix warnings where a variable is hiding a previous one with the same
name. Appended `2` to the second variable name.
What I haven't done is update the GitHub actions to verify a complete
build on a Windows machine as I'm not too familiar with the CI/CD
pipeline in this repo.
Hopefully this is a good start to get everything building successfully
and Windows.
Closes #2846
---------
Co-authored-by: Sutou Kouhei <[email protected]>
Co-authored-by: David Li <[email protected]>
Co-authored-by: Bryce Mecum <[email protected]>
---
.github/workflows/native-windows.yml | 99 ++++++++++++++++
c/CMakePresets.json | 53 +++++++++
c/cmake_modules/AdbcDefines.cmake | 20 ++++
c/cmake_modules/BuildUtils.cmake | 24 ++++
c/cmake_modules/DefineOptions.cmake | 4 +
c/cmake_modules/GoUtils.cmake | 131 ++++++++++++++++-----
c/driver/flightsql/CMakeLists.txt | 12 ++
.../postgresql/copy/postgres_copy_reader_test.cc | 4 +-
c/driver/snowflake/CMakeLists.txt | 12 ++
c/driver/sqlite/sqlite_test.cc | 7 +-
c/driver/sqlite/statement_reader.c | 9 ++
c/driver_manager/CMakeLists.txt | 2 +-
c/driver_manager/adbc_driver_manager.cc | 14 +--
c/driver_manager/adbc_driver_manager_test.cc | 17 ++-
c/validation/adbc_validation.cc | 11 +-
c/validation/adbc_validation_connection.cc | 2 +-
c/validation/adbc_validation_statement.cc | 28 ++---
c/validation/adbc_validation_util.h | 4 +-
c/version.rc.in | 49 ++++++++
ci/scripts/cpp_test.ps1 | 7 +-
go/adbc/drivermgr/adbc_driver_manager.cc | 14 +--
21 files changed, 442 insertions(+), 81 deletions(-)
diff --git a/.github/workflows/native-windows.yml
b/.github/workflows/native-windows.yml
index b72ace7e7..186b477af 100644
--- a/.github/workflows/native-windows.yml
+++ b/.github/workflows/native-windows.yml
@@ -260,6 +260,49 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
+ - name: Set Winlibs version
+ id: winlibs-version
+ shell: pwsh
+ run: |
+ $winlibs_asset_name =
"winlibs-x86_64-posix-seh-gcc-15.2.0-mingw-w64ucrt-13.0.0-r4.7z"
+ echo "winlibs_asset_name=$winlibs_asset_name" >> $env:GITHUB_OUTPUT
+
+ - name: Cache Winlibs
+ id: cache-winlibs
+ uses: actions/cache@v5
+ with:
+ path: ${{ runner.temp }}/winlibs
+ key: winlibs-${{ steps.winlibs-version.outputs.winlibs_asset_name }}
+
+ - name: Download and setup Winlibs
+ if: steps.cache-winlibs.outputs.cache-hit != 'true'
+ shell: pwsh
+ run: |
+ $base_url =
"https://github.com/brechtsanders/winlibs_mingw/releases/download/15.2.0posix-13.0.0-ucrt-r4/"
+ $asset_name = "${{ steps.winlibs-version.outputs.winlibs_asset_name
}}"
+ $hash_expected =
"148175f2ba3c4ab0bfd93116b75f7ff172e9e0d06ca8680c8a98c375ec45abb5"
+ $url = $base_url + $asset_name
+
+ Write-Host "Downloading $asset_name..."
+ Invoke-WebRequest -Uri $url -OutFile $asset_name -UseBasicParsing
+
+ Write-Host "Verifying hash..."
+ $hash_actual = (Get-FileHash -Path $asset_name -Algorithm
SHA256).Hash.ToLower()
+ if ($hash_actual -ne $hash_expected) {
+ throw "SHA256 mismatch! Expected: $hash_expected, Got:
$hash_actual"
+ }
+
+ Write-Host "Extracting..."
+ 7z x $asset_name -o"${{ runner.temp }}/winlibs" -y
+ Remove-Item $asset_name -Force
+
+ - name: Add Winlibs to PATH
+ shell: pwsh
+ run: |
+ $winlibs_bin = Join-Path "${{ runner.temp }}" "winlibs\mingw64\bin"
+ $env:PATH="$winlibs_bin;${env:PATH}"
+ echo "PATH=$env:PATH" >> $env:GITHUB_ENV
+
- name: Get Date
id: get-date
shell: bash
@@ -273,6 +316,7 @@ jobs:
with:
path: ~/conda_pkgs_dir
key: conda-${{ runner.os }}-${{ steps.get-date.outputs.today }}-${{
env.CACHE_NUMBER }}-${{ hashFiles('ci/**') }}
+
- uses:
conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f #
v3.2.0
with:
miniforge-version: latest
@@ -319,3 +363,58 @@ jobs:
BUILD_ALL: "0"
BUILD_DRIVER_SQLITE: "1"
run: .\ci\scripts\python_test.ps1 $pwd $pwd\build
+
+ # ------------------------------------------------------------
+ # MSVC/vcpkg build (no Conda)
+ # ------------------------------------------------------------
+ drivers-vcpkg:
+ name: "C/C++ (vcpkg/${{ matrix.os }}/${{ matrix.config }})"
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: ["windows-latest"]
+ arch: ["x64"]
+ config: ["debug", "release"]
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+ - name: Add msbuild to PATH
+ uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce
# v2
+ - name: Setup MSYS2 tools
+ run: |
+ # msys64 is pre-installed on windows but not added to path
+ $env:PATH =
"C:\msys64\mingw64\bin;C:\msys64\usr\bin\;C:\msys64\ucrt64\bin;$env:PATH"
+ echo "PATH=$env:PATH" >> $env:GITHUB_ENV
+
+ # Needed for gendef tool in GoUtils.cmake
+ pacman --noconfirm -S mingw-w64-x86_64-tools
+ # TODO(https://github.com/apache/arrow-adbc/issues/3825)
+ - name: Clone vcpkg
+ run: |
+ git clone https://github.com/microsoft/vcpkg.git
+ cd vcpkg
+ git checkout ef7dbf94b9198bc58f45951adcf1f041fcbc5ea0
+ .\bootstrap-vcpkg.bat
+ - name: Install vcpkg dependencies
+ working-directory: c
+ env:
+ VCPKG_ROOT: ${{ github.workspace }}/vcpkg
+ run: |
+ ${{ github.workspace }}/vcpkg/vcpkg.exe install libpq sqlite3
--triplet ${{ matrix.arch }}-windows
+ - name: Build and Install (No ASan)
+ env:
+ CMAKE_BUILD_TYPE: ${{ matrix.config }}
+ VCPKG_ROOT: ${{ github.workspace }}/vcpkg
+ run: |
+ cmake .\c\ --preset windows-${{ matrix.config }}
-DCMAKE_VERBOSE_MAKEFILE=ON
+
+ cmake --build .\build\${{ matrix.config }} --target install --config
${{ matrix.config }} --parallel
+ - name: Test
+ env:
+ BUILD_ALL: "0"
+ BUILD_DRIVER_MANAGER: "1"
+ BUILD_DRIVER_MANAGER_USER_CONFIG_TEST: "1"
+ BUILD_DRIVER_SQLITE: "1"
+ run: .\ci\scripts\cpp_test.ps1 $pwd\build\${{ matrix.config }}
$pwd\local\${{ matrix.config }}
diff --git a/c/CMakePresets.json b/c/CMakePresets.json
index fc4fdcb9a..b749532cc 100644
--- a/c/CMakePresets.json
+++ b/c/CMakePresets.json
@@ -23,6 +23,47 @@
"ADBC_USE_UBSAN": "ON"
}
},
+ {
+ "name": "multi-config-windows-base",
+ "displayName": "Base config for Windows without ASAN/UBSAN",
+ "hidden": true,
+ "toolchainFile":
"$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
+ "cacheVariables": {
+ "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
+ "ADBC_BUILD_TESTS": "ON",
+ "ADBC_DRIVER_FLIGHTSQL": "ON",
+ "ADBC_DRIVER_MANAGER": "ON",
+ "ADBC_DRIVER_POSTGRESQL": "ON",
+ "ADBC_DRIVER_SNOWFLAKE": "ON",
+ "ADBC_DRIVER_SQLITE": "ON",
+ "ADBC_BUILD_SHARED": "ON",
+ "ADBC_BUILD_STATIC": "OFF",
+ "ADBC_USE_ASAN": "OFF",
+ "ADBC_USE_UBSAN": "OFF",
+ "ADBC_BUILD_VCPKG": "ON",
+ "CMAKE_TOOLCHAIN_FILE":
"$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
+ "CMAKE_C_COMPILER": "cl.exe",
+ "CMAKE_CXX_COMPILER": "cl.exe"
+ }
+ },
+ {
+ "name": "windows-debug",
+ "displayName": "Windows Debug",
+ "inherits": "multi-config-windows-base",
+ "binaryDir": "${sourceDir}/../build/debug",
+ "cacheVariables": {
+ "CMAKE_INSTALL_PREFIX": "${sourceDir}/../local/debug"
+ }
+ },
+ {
+ "name": "windows-release",
+ "displayName": "Windows Release",
+ "inherits": "multi-config-windows-base",
+ "binaryDir": "${sourceDir}/../build/release",
+ "cacheVariables": {
+ "CMAKE_INSTALL_PREFIX": "${sourceDir}/../local/release"
+ }
+ },
{
"name": "debug-python",
"displayName": "debug, all drivers, with tests, without ASan/UBSan
(usable from Python)",
@@ -41,6 +82,18 @@
}
}
],
+ "buildPresets": [
+ {
+ "name": "debug-windows",
+ "configurePreset": "windows-debug",
+ "configuration": "Debug"
+ },
+ {
+ "name": "release-windows",
+ "configurePreset": "windows-release",
+ "configuration": "Release"
+ }
+ ],
"testPresets": [
{
"name": "debug",
diff --git a/c/cmake_modules/AdbcDefines.cmake
b/c/cmake_modules/AdbcDefines.cmake
index 11fe1a5d2..12b593759 100644
--- a/c/cmake_modules/AdbcDefines.cmake
+++ b/c/cmake_modules/AdbcDefines.cmake
@@ -148,6 +148,26 @@ endmacro()
# Common testing setup
add_custom_target(all-tests)
if(ADBC_BUILD_TESTS)
+ if(MSVC)
+ # MSVC emitted warnings for testing code
+ # Unary minus operator applied to unsigned type, result still unsigned
+ add_compile_options(/wd4146)
+ # An integer type is converted to a smaller integer type.
+ add_compile_options(/wd4244)
+ # Class has virtual functions, but its non-trivial destructor is not
virtual; instances of this class may not be destructed correctly
+ add_compile_options(/wd4265)
+ # No override available for virtual member function from base
+ add_compile_options(/wd4266)
+ # Signed integral constant overflow
+ add_compile_options(/wd4307)
+ # Move constructor was implicitly defined as deleted
+ add_compile_options(/wd5026)
+ # Class has virtual functions, but its trivial destructor is not virtual
+ add_compile_options(/wd5204)
+ # Implicit fall-through occurs here
+ add_compile_options(/wd5262)
+ endif()
+
find_package(GTest)
if(NOT GTest_FOUND)
message(STATUS "Building googletest from source")
diff --git a/c/cmake_modules/BuildUtils.cmake b/c/cmake_modules/BuildUtils.cmake
index 293b18d16..d7f4c2040 100644
--- a/c/cmake_modules/BuildUtils.cmake
+++ b/c/cmake_modules/BuildUtils.cmake
@@ -241,6 +241,17 @@ function(ADD_ARROW_LIB LIB_NAME)
VERSION "${ADBC_FULL_SO_VERSION}"
SOVERSION "${ADBC_SO_VERSION}")
+ if(WIN32)
+ # Binaries generated on Windows need file version information, otherwise
when the binary is part of a Windows installer
+ # the installer won't know to update a previously installed version.
+ set(VERSION_RC_TEMPLATE "${CMAKE_SOURCE_DIR}/version.rc.in")
+ configure_file("${VERSION_RC_TEMPLATE}"
+ "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}_version.rc"
@ONLY)
+
+ target_sources(${LIB_NAME}_shared
+ PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}_version.rc")
+ endif()
+
# https://github.com/apache/arrow-adbc/issues/81
target_compile_features(${LIB_NAME}_shared PRIVATE cxx_std_11)
@@ -289,6 +300,19 @@ function(ADD_ARROW_LIB LIB_NAME)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+ # If we're building on Windows using vcpkg, ensure the runtime
dependencies of binaries are copied to the install folder.
+ # TODO(https://github.com/apache/arrow-adbc/issues/3826): auto-detect this
+ if(ADBC_BUILD_VCPKG)
+ install(TARGETS ${LIB_NAME}_shared
+ RUNTIME_DEPENDENCIES
+ PRE_EXCLUDE_REGEXES
+ "api-ms-win-.*"
+ "ext-ms-.*"
+ POST_EXCLUDE_REGEXES
+ ".*system32.*"
+ RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR})
+ endif()
endif()
if(BUILD_STATIC)
diff --git a/c/cmake_modules/DefineOptions.cmake
b/c/cmake_modules/DefineOptions.cmake
index 759a8be40..37b0f62dc 100644
--- a/c/cmake_modules/DefineOptions.cmake
+++ b/c/cmake_modules/DefineOptions.cmake
@@ -232,6 +232,10 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL
"${CMAKE_CURRENT_SOURCE_DIR}")
define_option(ADBC_DRIVER_BIGQUERY "Build the BigQuery driver" OFF)
define_option(ADBC_INTEGRATION_DUCKDB "Build the test suite for DuckDB" OFF)
+
+ define_option(ADBC_BUILD_VCPKG
+ "Build on Windows using vcpkg for dependencies and Visual
Studio generator."
+ OFF)
endif()
macro(validate_config)
diff --git a/c/cmake_modules/GoUtils.cmake b/c/cmake_modules/GoUtils.cmake
index a0e2ccef7..3909efdcd 100644
--- a/c/cmake_modules/GoUtils.cmake
+++ b/c/cmake_modules/GoUtils.cmake
@@ -18,6 +18,13 @@
find_program(GO_BIN "go" REQUIRED)
message(STATUS "Detecting Go executable: Found ${GO_BIN}")
+# Find tools for generating import libraries on Windows when building with
vcpkg
+if(WIN32)
+ # msys64 is needed for dlltool and gendef
+ find_program(DLLTOOL_BIN "dlltool")
+ find_program(GENDEF_BIN "gendef")
+endif()
+
set(ADBC_GO_PACKAGE_INIT
[=[
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
@@ -65,6 +72,20 @@ function(adbc_add_static_library target_name base_name)
endfunction()
]=])
+# Function to generate import library from DLL on Windows
+function(generate_import_library DLL_PATH LIB_PATH DEF_PATH)
+ add_custom_command(OUTPUT "${DEF_PATH}"
+ COMMAND ${GENDEF_BIN} - "${DLL_PATH}" > "${DEF_PATH}"
+ DEPENDS "${DLL_PATH}"
+ COMMENT "Generating .def file from ${DLL_PATH}")
+
+ add_custom_command(OUTPUT "${LIB_PATH}"
+ COMMAND ${DLLTOOL_BIN} -d "${DEF_PATH}" -l "${LIB_PATH}"
-D
+ "${DLL_PATH}"
+ DEPENDS "${DEF_PATH}"
+ COMMENT "Generating import library ${LIB_PATH}")
+endfunction()
+
function(add_go_lib GO_MOD_DIR GO_LIBNAME)
set(options)
set(one_value_args
@@ -184,36 +205,79 @@ function(add_go_lib GO_MOD_DIR GO_LIBNAME)
list(APPEND GO_ENV_VARS "GOARCH=arm64")
endif()
- add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
- WORKING_DIRECTORY ${GO_MOD_DIR}
- DEPENDS ${ARG_SOURCES}
- COMMAND ${CMAKE_COMMAND} -E env ${GO_ENV_VARS}
${GO_BIN} build
- ${GO_BUILD_TAGS} "${GO_BUILD_FLAGS}" -o
- ${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}
- -buildmode=c-shared ${GO_LDFLAGS} .
- COMMAND ${CMAKE_COMMAND} -E remove -f
- "${LIBOUT_SHARED}.${ADBC_SO_VERSION}.0.h"
- COMMENT "Building Go Shared lib ${GO_LIBNAME}"
- COMMAND_EXPAND_LISTS)
+ if(WIN32)
+ # On Windows with MSVC, generate a lib from the DLL file created by Go.
Binaries generated on Windows have their version
+ # as part of the DLL/file details, therefore the generated DLL file name
does not need to have the version info.
+ set(LIBOUT_IMPORT_LIB
+
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_IMPORT_LIBRARY_PREFIX}${GO_LIBNAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+ )
+ set(LIBOUT_DEF_FILE "${CMAKE_CURRENT_BINARY_DIR}/${GO_LIBNAME}.def")
+
+ add_custom_command(OUTPUT "${LIBOUT_SHARED}"
+ WORKING_DIRECTORY ${GO_MOD_DIR}
+ DEPENDS ${ARG_SOURCES}
+ COMMAND ${CMAKE_COMMAND} -E env ${GO_ENV_VARS}
${GO_BIN} build
+ ${GO_BUILD_TAGS} "${GO_BUILD_FLAGS}" -o
${LIBOUT_SHARED}
+ -buildmode=c-shared ${GO_LDFLAGS} .
+ COMMAND ${CMAKE_COMMAND} -E remove -f
"${LIBOUT_SHARED}.h"
+ COMMENT "Building Go Shared lib ${GO_LIBNAME}"
+ COMMAND_EXPAND_LISTS)
+
+ # Generate import library if tools are available
+ if(GENDEF_BIN AND DLLTOOL_BIN)
+ generate_import_library("${LIBOUT_SHARED}" "${LIBOUT_IMPORT_LIB}"
+ "${LIBOUT_DEF_FILE}")
+ set(IMPORT_LIB_OUTPUTS "${LIBOUT_IMPORT_LIB}" "${LIBOUT_DEF_FILE}")
+ else()
+ set(IMPORT_LIB_OUTPUTS)
+ message(WARNING "Import library generation tools not found. You may
need to link directly to the DLL or use delay-loading."
+ )
+ endif()
+
+ add_custom_target(${GO_LIBNAME}_target ALL DEPENDS "${LIBOUT_SHARED}"
+ ${IMPORT_LIB_OUTPUTS})
+
+ add_library(${GO_LIBNAME}_shared SHARED IMPORTED GLOBAL)
+ set_target_properties(${GO_LIBNAME}_shared PROPERTIES IMPORTED_LOCATION
+ "${LIBOUT_SHARED}")
- add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_SO_VERSION}"
"${LIBOUT_SHARED}"
- DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${CMAKE_COMMAND} -E create_symlink
- "${LIB_NAME_SHARED}.${ADBC_FULL_SO_VERSION}"
- "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}"
- COMMAND ${CMAKE_COMMAND} -E create_symlink
- "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}"
- "${LIB_NAME_SHARED}")
-
- add_custom_target(${GO_LIBNAME}_target ALL
- DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
- "${LIBOUT_SHARED}.${ADBC_SO_VERSION}"
"${LIBOUT_SHARED}")
- add_library(${GO_LIBNAME}_shared SHARED IMPORTED GLOBAL)
- set_target_properties(${GO_LIBNAME}_shared
- PROPERTIES IMPORTED_LOCATION
- "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
- IMPORTED_SONAME "${LIB_NAME_SHARED}")
+ # Set import library if it was generated
+ if(IMPORT_LIB_OUTPUTS)
+ set_target_properties(${GO_LIBNAME}_shared PROPERTIES IMPORTED_IMPLIB
+
"${LIBOUT_IMPORT_LIB}")
+ endif()
+ else()
+ add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
+ WORKING_DIRECTORY ${GO_MOD_DIR}
+ DEPENDS ${ARG_SOURCES}
+ COMMAND ${CMAKE_COMMAND} -E env ${GO_ENV_VARS}
${GO_BIN} build
+ ${GO_BUILD_TAGS} "${GO_BUILD_FLAGS}" -o
+ ${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}
+ -buildmode=c-shared ${GO_LDFLAGS} .
+ COMMAND ${CMAKE_COMMAND} -E remove -f
+ "${LIBOUT_SHARED}.${ADBC_SO_VERSION}.0.h"
+ COMMENT "Building Go Shared lib ${GO_LIBNAME}"
+ COMMAND_EXPAND_LISTS)
+
+ add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_SO_VERSION}"
"${LIBOUT_SHARED}"
+ DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "${LIB_NAME_SHARED}.${ADBC_FULL_SO_VERSION}"
+ "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}"
+ "${LIB_NAME_SHARED}")
+
+ add_custom_target(${GO_LIBNAME}_target ALL
+ DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
+ "${LIBOUT_SHARED}.${ADBC_SO_VERSION}"
"${LIBOUT_SHARED}")
+ add_library(${GO_LIBNAME}_shared SHARED IMPORTED GLOBAL)
+ set_target_properties(${GO_LIBNAME}_shared
+ PROPERTIES IMPORTED_LOCATION
+
"${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}"
+ IMPORTED_SONAME "${LIB_NAME_SHARED}")
+ endif()
add_dependencies(${GO_LIBNAME}_shared ${GO_LIBNAME}_target)
if(ARG_OUTPUTS)
list(APPEND ${ARG_OUTPUTS} ${GO_LIBNAME}_shared)
@@ -243,6 +307,9 @@ function(add_go_lib GO_MOD_DIR GO_LIBNAME)
if(WIN32)
install(PROGRAMS $<TARGET_FILE:${GO_LIBNAME}_shared>
${INSTALL_IS_OPTIONAL}
DESTINATION ${RUNTIME_INSTALL_DIR})
+ if(IMPORT_LIB_OUTPUTS)
+ install(FILES "${LIBOUT_IMPORT_LIB}" TYPE LIB)
+ endif()
else()
install(PROGRAMS $<TARGET_FILE:${GO_LIBNAME}_shared>
${INSTALL_IS_OPTIONAL}
TYPE LIB)
@@ -259,8 +326,10 @@ function(add_go_lib GO_MOD_DIR GO_LIBNAME)
${CMAKE_INSTALL_LIBDIR})
endif()
if(WIN32)
- # This symlink doesn't get installed
- install(FILES "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" TYPE BIN)
+ install(FILES "${LIBOUT_SHARED}" TYPE BIN)
+ if(IMPORT_LIB_OUTPUTS)
+ install(FILES "${LIBOUT_IMPORT_LIB}" TYPE LIB)
+ endif()
else()
install(FILES "${LIBOUT_SHARED}" "${LIBOUT_SHARED}.${ADBC_SO_VERSION}"
TYPE LIB)
endif()
diff --git a/c/driver/flightsql/CMakeLists.txt
b/c/driver/flightsql/CMakeLists.txt
index 9f60cbf07..300833410 100644
--- a/c/driver/flightsql/CMakeLists.txt
+++ b/c/driver/flightsql/CMakeLists.txt
@@ -63,6 +63,18 @@ if(ADBC_BUILD_TESTS)
adbc_driver_common
adbc_validation
${TEST_LINK_LIBS})
+
+ if(ADBC_TEST_LINKAGE STREQUAL "shared")
+ # The Go build is not copying the DLL to the test location, causing the
test to fail on Windows when building with vcpkg.
+ if(WIN32)
+ add_custom_command(TARGET adbc-driver-flightsql-test
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "$<TARGET_FILE:adbc_driver_flightsql_shared>"
+
"$<TARGET_FILE_DIR:adbc-driver-flightsql-test>")
+ endif()
+ endif()
+
target_compile_features(adbc-driver-flightsql-test PRIVATE cxx_std_17)
target_include_directories(adbc-driver-flightsql-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/
${REPOSITORY_ROOT}/c/include/
diff --git a/c/driver/postgresql/copy/postgres_copy_reader_test.cc
b/c/driver/postgresql/copy/postgres_copy_reader_test.cc
index 18e487f9c..483c38ac9 100644
--- a/c/driver/postgresql/copy/postgres_copy_reader_test.cc
+++ b/c/driver/postgresql/copy/postgres_copy_reader_test.cc
@@ -238,10 +238,10 @@ TEST(PostgresCopyUtilsTest, PostgresCopyReadReal) {
ASSERT_TRUE(ArrowBitGet(validity, 3));
ASSERT_FALSE(ArrowBitGet(validity, 4));
- ASSERT_FLOAT_EQ(data_buffer[0], -123.456);
+ ASSERT_FLOAT_EQ(data_buffer[0], -123.456f);
ASSERT_EQ(data_buffer[1], -1);
ASSERT_EQ(data_buffer[2], 1);
- ASSERT_FLOAT_EQ(data_buffer[3], 123.456);
+ ASSERT_FLOAT_EQ(data_buffer[3], 123.456f);
ASSERT_EQ(data_buffer[4], 0);
}
diff --git a/c/driver/snowflake/CMakeLists.txt
b/c/driver/snowflake/CMakeLists.txt
index 2a81eb2c4..0560a3df5 100644
--- a/c/driver/snowflake/CMakeLists.txt
+++ b/c/driver/snowflake/CMakeLists.txt
@@ -63,6 +63,18 @@ if(ADBC_BUILD_TESTS)
adbc_validation
nanoarrow
${TEST_LINK_LIBS})
+
+ if(ADBC_TEST_LINKAGE STREQUAL "shared")
+ # The Go build is not copying the DLL to the test location, causing the
test to fail on Windows when building with vcpkg.
+ if(WIN32)
+ add_custom_command(TARGET adbc-driver-snowflake-test
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "$<TARGET_FILE:adbc_driver_snowflake_shared>"
+
"$<TARGET_FILE_DIR:adbc-driver-snowflake-test>")
+ endif()
+ endif()
+
target_compile_features(adbc-driver-snowflake-test PRIVATE cxx_std_17)
target_include_directories(adbc-driver-snowflake-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/
${REPOSITORY_ROOT}/c/include/
diff --git a/c/driver/sqlite/sqlite_test.cc b/c/driver/sqlite/sqlite_test.cc
index f270f5059..81817eb5d 100644
--- a/c/driver/sqlite/sqlite_test.cc
+++ b/c/driver/sqlite/sqlite_test.cc
@@ -446,7 +446,7 @@ class SqliteReaderTest : public ::testing::Test {
void Exec(const std::string& query) {
SCOPED_TRACE(query);
- int rc = sqlite3_prepare_v2(db, query.c_str(), query.size(), &stmt,
+ int rc = sqlite3_prepare_v2(db, query.c_str(),
static_cast<int>(query.size()), &stmt,
/*pzTail=*/nullptr);
ASSERT_EQ(SQLITE_OK, rc) << "Failed to prepare query: " <<
sqlite3_errmsg(db);
ASSERT_EQ(SQLITE_DONE, sqlite3_step(stmt));
@@ -480,8 +480,9 @@ class SqliteReaderTest : public ::testing::Test {
void Exec(const std::string& query, size_t infer_rows,
adbc_validation::StreamReader* reader) {
- ASSERT_EQ(SQLITE_OK, sqlite3_prepare_v2(db, query.c_str(), query.size(),
&stmt,
- /*pzTail=*/nullptr));
+ ASSERT_EQ(SQLITE_OK,
+ sqlite3_prepare_v2(db, query.c_str(),
static_cast<int>(query.size()), &stmt,
+ /*pzTail=*/nullptr));
struct AdbcSqliteBinder* binder =
this->binder.schema.release ? &this->binder : nullptr;
ASSERT_THAT(InternalAdbcSqliteExportReader(db, stmt, binder, infer_rows,
diff --git a/c/driver/sqlite/statement_reader.c
b/c/driver/sqlite/statement_reader.c
index 554bdaf20..7c2cae682 100644
--- a/c/driver/sqlite/statement_reader.c
+++ b/c/driver/sqlite/statement_reader.c
@@ -451,8 +451,17 @@ AdbcStatusCode InternalAdbcSqliteBinderBindNext(struct
AdbcSqliteBinder* binder,
}
case NANOARROW_TYPE_TIMESTAMP: {
struct ArrowSchemaView bind_schema_view;
+// TODO(https://github.com/apache/arrow-adbc/issues/1675)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4244) // RAISE_NA returns ArrowErrorCode, but this
function
+ // returns AdbcStatusCode
+#endif
RAISE_NA(ArrowSchemaViewInit(&bind_schema_view,
binder->schema.children[col],
&arrow_error));
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
enum ArrowTimeUnit unit = bind_schema_view.time_unit;
int64_t value =
ArrowArrayViewGetIntUnsafe(binder->batch.children[col],
binder->next_row);
diff --git a/c/driver_manager/CMakeLists.txt b/c/driver_manager/CMakeLists.txt
index 35f89ac84..ef488fb03 100644
--- a/c/driver_manager/CMakeLists.txt
+++ b/c/driver_manager/CMakeLists.txt
@@ -119,7 +119,7 @@ if(ADBC_BUILD_TESTS)
if(ADBC_DRIVER_SQLITE)
target_compile_definitions(adbc-driver-manager-test
- PRIVATE
ADBC_DRIVER_MANAGER_TEST_LIB="${CMAKE_BINARY_DIR}/driver/sqlite/${CMAKE_SHARED_LIBRARY_PREFIX}adbc_driver_sqlite${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ PRIVATE
ADBC_DRIVER_MANAGER_TEST_LIB="$<TARGET_FILE:adbc_driver_sqlite_shared>"
)
endif()
if(ADBC_DRIVER_MANAGER_TEST_MANIFEST_USER_LEVEL)
diff --git a/c/driver_manager/adbc_driver_manager.cc
b/c/driver_manager/adbc_driver_manager.cc
index c0e011098..93bc78791 100644
--- a/c/driver_manager/adbc_driver_manager.cc
+++ b/c/driver_manager/adbc_driver_manager.cc
@@ -462,18 +462,16 @@ AdbcStatusCode LoadDriverManifest(const
std::filesystem::path& driver_manifest,
SearchPaths GetEnvPaths(const char_type* env_var) {
#ifdef _WIN32
- size_t required_size;
-
- _wgetenv_s(&required_size, NULL, 0, env_var);
+ DWORD required_size = GetEnvironmentVariableW(env_var, NULL, 0);
if (required_size == 0) {
return {};
}
std::wstring path_var;
path_var.resize(required_size);
- _wgetenv_s(&required_size, path_var.data(), required_size, env_var);
+ DWORD actual_size = GetEnvironmentVariableW(env_var, path_var.data(),
required_size);
// Remove null terminator
- path_var.resize(required_size - 1);
+ path_var.resize(actual_size);
auto path = Utf8Encode(path_var);
#else
const char* path_var = std::getenv(env_var);
@@ -483,8 +481,8 @@ SearchPaths GetEnvPaths(const char_type* env_var) {
std::string path(path_var);
#endif // _WIN32
SearchPaths paths;
- for (auto path : InternalAdbcParsePath(path)) {
- paths.emplace_back(SearchPathSource::kEnv, path);
+ for (auto parsed_path : InternalAdbcParsePath(path)) {
+ paths.emplace_back(SearchPathSource::kEnv, parsed_path);
}
return paths;
}
@@ -1531,7 +1529,7 @@ std::string
InternalAdbcDriverManagerDefaultEntrypoint(const std::string& driver
// if pos == npos this is the entire filename
std::string token = filename.substr(prev, pos - prev);
// capitalize first letter
- token[0] = std::toupper(static_cast<unsigned char>(token[0]));
+ token[0] = static_cast<char>(std::toupper(static_cast<unsigned
char>(token[0])));
entrypoint += token;
diff --git a/c/driver_manager/adbc_driver_manager_test.cc
b/c/driver_manager/adbc_driver_manager_test.cc
index d67a1218c..80a2fe77f 100644
--- a/c/driver_manager/adbc_driver_manager_test.cc
+++ b/c/driver_manager/adbc_driver_manager_test.cc
@@ -569,7 +569,10 @@ class DriverManifest : public ::testing::Test {
protected:
void SetConfigPath(const char* path) {
#ifdef _WIN32
- ASSERT_TRUE(SetEnvironmentVariable("ADBC_DRIVER_PATH", path));
+ int size_needed = MultiByteToWideChar(CP_UTF8, 0, path, -1, nullptr, 0);
+ std::wstring wpath(size_needed, 0);
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, &wpath[0], size_needed);
+ ASSERT_TRUE(SetEnvironmentVariableW(L"ADBC_DRIVER_PATH", wpath.c_str()));
#else
setenv("ADBC_DRIVER_PATH", path, 1);
#endif
@@ -1138,12 +1141,20 @@ TEST_F(DriverManifest, AllDisabled) {
EXPECT_THAT(error.message,
::testing::HasSubstr("not enabled at run time: ADBC_DRIVER_PATH
(enable "
"ADBC_LOAD_FLAG_SEARCH_ENV)"));
+
+#ifdef _WIN32
EXPECT_THAT(error.message,
- ::testing::HasSubstr("not enabled at run time: user config dir
/"));
+ ::testing::HasSubstr("not enabled at run time:
HKEY_CURRENT_USER"));
EXPECT_THAT(error.message,
- ::testing::HasSubstr(" (enable ADBC_LOAD_FLAG_SEARCH_USER)"));
+ ::testing::HasSubstr("not enabled at run time:
HKEY_LOCAL_MACHINE"));
+#else
+ EXPECT_THAT(error.message,
+ ::testing::HasSubstr("not enabled at run time: user config dir
/"));
EXPECT_THAT(error.message,
::testing::HasSubstr("not enabled at run time: system config dir
/"));
+#endif // _WIN32
+ EXPECT_THAT(error.message,
+ ::testing::HasSubstr(" (enable ADBC_LOAD_FLAG_SEARCH_USER)"));
EXPECT_THAT(error.message,
::testing::HasSubstr(" (enable ADBC_LOAD_FLAG_SEARCH_SYSTEM)"));
}
diff --git a/c/validation/adbc_validation.cc b/c/validation/adbc_validation.cc
index 5cd592679..626b03f3d 100644
--- a/c/validation/adbc_validation.cc
+++ b/c/validation/adbc_validation.cc
@@ -51,11 +51,12 @@ AdbcStatusCode DoIngestSampleTable(struct AdbcConnection*
connection,
Handle<struct ArrowSchema> schema;
Handle<struct ArrowArray> array;
struct ArrowError na_error;
- CHECK_OK(MakeSchema(&schema.value, {{"int64s", NANOARROW_TYPE_INT64},
- {"strings", NANOARROW_TYPE_STRING}}));
- CHECK_OK((MakeBatch<int64_t, std::string>(&schema.value, &array.value,
&na_error,
- {42, -42, std::nullopt},
- {"foo", std::nullopt, ""})));
+ CHECK_OK(static_cast<AdbcStatusCode>(MakeSchema(
+ &schema.value,
+ {{"int64s", NANOARROW_TYPE_INT64}, {"strings",
NANOARROW_TYPE_STRING}})));
+ CHECK_OK((static_cast<AdbcStatusCode>(MakeBatch<int64_t, std::string>(
+ &schema.value, &array.value, &na_error, {42, -42, std::nullopt},
+ {"foo", std::nullopt, ""}))));
Handle<struct AdbcStatement> statement;
CHECK_OK(AdbcStatementNew(connection, &statement.value, error));
diff --git a/c/validation/adbc_validation_connection.cc
b/c/validation/adbc_validation_connection.cc
index 9c9bdeff2..d7e61b918 100644
--- a/c/validation/adbc_validation_connection.cc
+++ b/c/validation/adbc_validation_connection.cc
@@ -868,7 +868,7 @@ void ConstraintTest(const AdbcGetObjectsConstraint*
constraint,
const std::vector<std::string>& columns) {
std::string_view constraint_type(constraint->constraint_type.data,
constraint->constraint_type.size_bytes);
- int number_of_columns = columns.size();
+ int number_of_columns = static_cast<int>(columns.size());
ASSERT_EQ(constraint_type, key_type);
ASSERT_EQ(constraint->n_column_names, number_of_columns)
<< "expected constraint " << key_type
diff --git a/c/validation/adbc_validation_statement.cc
b/c/validation/adbc_validation_statement.cc
index ae5ef518a..131dbb2b6 100644
--- a/c/validation/adbc_validation_statement.cc
+++ b/c/validation/adbc_validation_statement.cc
@@ -1358,22 +1358,22 @@ void StatementTest::TestSqlIngestTemporaryAppend() {
ASSERT_THAT((MakeBatch<int64_t>(&schema.value, &array.value, &na_error,
{0, 1, 2})),
IsOkErrno());
- Handle<struct AdbcStatement> statement;
- ASSERT_THAT(AdbcStatementNew(&connection, &statement.value, &error),
+ Handle<struct AdbcStatement> statement2;
+ ASSERT_THAT(AdbcStatementNew(&connection, &statement2.value, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementSetOption(&statement.value,
ADBC_INGEST_OPTION_TEMPORARY,
+ ASSERT_THAT(AdbcStatementSetOption(&statement2.value,
ADBC_INGEST_OPTION_TEMPORARY,
ADBC_OPTION_VALUE_ENABLED, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementSetOption(&statement.value,
ADBC_INGEST_OPTION_MODE,
+ ASSERT_THAT(AdbcStatementSetOption(&statement2.value,
ADBC_INGEST_OPTION_MODE,
ADBC_INGEST_OPTION_MODE_APPEND, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementSetOption(&statement.value,
ADBC_INGEST_OPTION_TARGET_TABLE,
+ ASSERT_THAT(AdbcStatementSetOption(&statement2.value,
ADBC_INGEST_OPTION_TARGET_TABLE,
name.c_str(), &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementBind(&statement.value, &array.value,
&schema.value, &error),
+ ASSERT_THAT(AdbcStatementBind(&statement2.value, &array.value,
&schema.value, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementExecuteQuery(&statement.value, nullptr, nullptr,
&error),
+ ASSERT_THAT(AdbcStatementExecuteQuery(&statement2.value, nullptr, nullptr,
&error),
IsOkStatus(&error));
}
@@ -1533,22 +1533,22 @@ void StatementTest::TestSqlIngestTemporaryReplace() {
{"foo", "bar",
std::nullopt})),
IsOkErrno());
- Handle<struct AdbcStatement> statement;
- ASSERT_THAT(AdbcStatementNew(&connection, &statement.value, &error),
+ Handle<struct AdbcStatement> statement2;
+ ASSERT_THAT(AdbcStatementNew(&connection, &statement2.value, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementSetOption(&statement.value,
ADBC_INGEST_OPTION_TEMPORARY,
+ ASSERT_THAT(AdbcStatementSetOption(&statement2.value,
ADBC_INGEST_OPTION_TEMPORARY,
ADBC_OPTION_VALUE_ENABLED, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementSetOption(&statement.value,
ADBC_INGEST_OPTION_MODE,
+ ASSERT_THAT(AdbcStatementSetOption(&statement2.value,
ADBC_INGEST_OPTION_MODE,
ADBC_INGEST_OPTION_MODE_APPEND, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementSetOption(&statement.value,
ADBC_INGEST_OPTION_TARGET_TABLE,
+ ASSERT_THAT(AdbcStatementSetOption(&statement2.value,
ADBC_INGEST_OPTION_TARGET_TABLE,
name.c_str(), &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementBind(&statement.value, &array.value,
&schema.value, &error),
+ ASSERT_THAT(AdbcStatementBind(&statement2.value, &array.value,
&schema.value, &error),
IsOkStatus(&error));
- ASSERT_THAT(AdbcStatementExecuteQuery(&statement.value, nullptr, nullptr,
&error),
+ ASSERT_THAT(AdbcStatementExecuteQuery(&statement2.value, nullptr, nullptr,
&error),
IsOkStatus(&error));
}
diff --git a/c/validation/adbc_validation_util.h
b/c/validation/adbc_validation_util.h
index 57f3859f4..980912f71 100644
--- a/c/validation/adbc_validation_util.h
+++ b/c/validation/adbc_validation_util.h
@@ -445,8 +445,8 @@ void CompareArray(struct ArrowArrayView* array,
} else if constexpr (std::is_same<T, std::vector<std::byte>>::value) {
struct ArrowBufferView view = ArrowArrayViewGetBytesUnsafe(array, i);
ASSERT_EQ(v->size(), view.size_bytes);
- for (int64_t i = 0; i < view.size_bytes; i++) {
- ASSERT_EQ((*v)[i], std::byte{view.data.as_uint8[i]});
+ for (int64_t i2 = 0; i2 < view.size_bytes; i2++) {
+ ASSERT_EQ((*v)[i2], std::byte{view.data.as_uint8[i2]});
}
} else if constexpr (std::is_same<T, ArrowInterval*>::value) {
ASSERT_NE(array->buffer_views[1].data.data, nullptr);
diff --git a/c/version.rc.in b/c/version.rc.in
new file mode 100644
index 000000000..39938829b
--- /dev/null
+++ b/c/version.rc.in
@@ -0,0 +1,49 @@
+// 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.
+
+#include <windows.h>
+
+#define LANG_CODE_US_ENGLISH 0x0409
+#define CHARSET_UNICODE 0x04b0
+#define US_ENGLISH_UNICODE "040904b0"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION @ADBC_VERSION_MAJOR@,@ADBC_VERSION_MINOR@,@ADBC_VERSION_PATCH@,0
+PRODUCTVERSION @ADBC_VERSION_MAJOR@,@ADBC_VERSION_MINOR@,@ADBC_VERSION_PATCH@,0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEFLAGS 0x0L
+FILEOS VOS__WINDOWS32
+FILETYPE VFT_DLL
+FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK US_ENGLISH_UNICODE
+ BEGIN
+ VALUE "FileDescription", "ADBC: Arrow Database Connectivity"
+ VALUE "FileVersion", "@ADBC_VERSION@"
+ VALUE "ProductVersion", "@ADBC_VERSION@"
+ VALUE "CompanyName", "Apache Software Foundation"
+ VALUE "ProductName", "@LIB_NAME@"
+ VALUE "InternalName", "@LIB_NAME@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", LANG_CODE_US_ENGLISH, CHARSET_UNICODE
+ END
+END
diff --git a/ci/scripts/cpp_test.ps1 b/ci/scripts/cpp_test.ps1
index e25c2e026..9d92d50b1 100755
--- a/ci/scripts/cpp_test.ps1
+++ b/ci/scripts/cpp_test.ps1
@@ -32,9 +32,10 @@ $BuildDriverSqlite = ($BuildAll -and (-not
($env:BUILD_DRIVER_SQLITE -eq "0")))
$env:LD_LIBRARY_PATH += ":$($InstallDir)"
$env:LD_LIBRARY_PATH += ":$($InstallDir)/bin"
$env:LD_LIBRARY_PATH += ":$($InstallDir)/lib"
-$env:PATH += ";$($InstallDir)"
-$env:PATH += ";$($InstallDir)\bin"
-$env:PATH += ";$($InstallDir)\lib"
+# InstallDir must come first, else on CI we may pick up system sqlite and crash
+$env:PATH = "$($InstallDir);$env:PATH"
+$env:PATH = "$($InstallDir)\bin;$env:PATH"
+$env:PATH = "$($InstallDir)\lib;$env:PATH"
function Test-Project {
Push-Location $BuildDir
diff --git a/go/adbc/drivermgr/adbc_driver_manager.cc
b/go/adbc/drivermgr/adbc_driver_manager.cc
index c0e011098..93bc78791 100644
--- a/go/adbc/drivermgr/adbc_driver_manager.cc
+++ b/go/adbc/drivermgr/adbc_driver_manager.cc
@@ -462,18 +462,16 @@ AdbcStatusCode LoadDriverManifest(const
std::filesystem::path& driver_manifest,
SearchPaths GetEnvPaths(const char_type* env_var) {
#ifdef _WIN32
- size_t required_size;
-
- _wgetenv_s(&required_size, NULL, 0, env_var);
+ DWORD required_size = GetEnvironmentVariableW(env_var, NULL, 0);
if (required_size == 0) {
return {};
}
std::wstring path_var;
path_var.resize(required_size);
- _wgetenv_s(&required_size, path_var.data(), required_size, env_var);
+ DWORD actual_size = GetEnvironmentVariableW(env_var, path_var.data(),
required_size);
// Remove null terminator
- path_var.resize(required_size - 1);
+ path_var.resize(actual_size);
auto path = Utf8Encode(path_var);
#else
const char* path_var = std::getenv(env_var);
@@ -483,8 +481,8 @@ SearchPaths GetEnvPaths(const char_type* env_var) {
std::string path(path_var);
#endif // _WIN32
SearchPaths paths;
- for (auto path : InternalAdbcParsePath(path)) {
- paths.emplace_back(SearchPathSource::kEnv, path);
+ for (auto parsed_path : InternalAdbcParsePath(path)) {
+ paths.emplace_back(SearchPathSource::kEnv, parsed_path);
}
return paths;
}
@@ -1531,7 +1529,7 @@ std::string
InternalAdbcDriverManagerDefaultEntrypoint(const std::string& driver
// if pos == npos this is the entire filename
std::string token = filename.substr(prev, pos - prev);
// capitalize first letter
- token[0] = std::toupper(static_cast<unsigned char>(token[0]));
+ token[0] = static_cast<char>(std::toupper(static_cast<unsigned
char>(token[0])));
entrypoint += token;