Skip to content

fix(c): Generate versioned DLLs and import LIBs when building with MSVC #2858

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

IIFE
Copy link

@IIFE IIFE commented May 25, 2025

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

@IIFE IIFE requested a review from lidavidm as a code owner May 25, 2025 21:36
@github-actions github-actions bot added this to the ADBC Libraries 19 milestone May 25, 2025
@IIFE IIFE changed the title Generate versioned DLLs and import LIBs when building with MSVC fix(c): Generate versioned DLLs and import LIBs when building with MSVC May 25, 2025
@lidavidm
Copy link
Member

Thanks for figuring this out. Overall this looks reasonable. If you don't mind I can attempt to push a Windows pipeline to this PR so we can test it.

FILEFLAGS 0x0L
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to specify this with VFT_DLL?

Copy link
Author

Choose a reason for hiding this comment

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

It's the main file type value that makes sense for the produced files (DLLs). The rest are unrelated to the DLL file type

@IIFE
Copy link
Author

IIFE commented May 26, 2025

Thanks for figuring this out. Overall this looks reasonable. If you don't mind I can attempt to push a Windows pipeline to this PR so we can test it.

Yes please @lidavidm that would be helpful.

@lidavidm
Copy link
Member

Got it - I'll try to get to it soon

@IIFE
Copy link
Author

IIFE commented May 27, 2025

pre-commit issues addressed

@Kakolukia91
Copy link

Hmm not sure why the pre-commit is still failing. Is it because I've run mine on a Windows machine so it's not capturing everything the CI does (which runs on Ubuntu from the looks of it)? 🤔

@lidavidm
Copy link
Member

How are you running it?

@IIFE
Copy link
Author

IIFE commented May 27, 2025

Using this command:
pre-commit run --show-diff-on-failure --color=always --all-files

@lidavidm
Copy link
Member

I don't see a problem. I guess it could be Windows.

@lidavidm lidavidm requested a review from zeroshade as a code owner May 30, 2025 05:16
@lidavidm
Copy link
Member

It looks like tests might not fully build:

C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: validation/Debug/libadbc_validation_util.a(adbc_validation_util.cc.obj): in function `adbc_validation::StatementGetOption[abi:cxx11](AdbcStatement*, std::basic_string_view<char, std::char_traits<char> >, AdbcError*)':
D:/a/arrow-adbc/arrow-adbc/c/validation/adbc_validation_util.cc:50: undefined reference to `__imp_AdbcStatementGetOption'

I'm OK disabling tests for time time being if we can just get DLLs to build properly (we could perhaps just verify that DLLs and implibs exist)

@lidavidm
Copy link
Member

Also I see gendef being invoked, but it's not installed by CMake - that probably also needs to be tweaked

@lidavidm
Copy link
Member

Oh wait - is the dll.a sufficient? (That's being installed.) Does the .def file need to be installed?

@IIFE
Copy link
Author

IIFE commented May 30, 2025

Also I see gendef being invoked, but it's not installed by CMake - that probably also needs to be tweaked

Yeah that's needed to generate the DEF file, which is then used to create the lib import

It looks like tests might not fully build:

C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: validation/Debug/libadbc_validation_util.a(adbc_validation_util.cc.obj): in function `adbc_validation::StatementGetOption[abi:cxx11](AdbcStatement*, std::basic_string_view<char, std::char_traits<char> >, AdbcError*)':
D:/a/arrow-adbc/arrow-adbc/c/validation/adbc_validation_util.cc:50: undefined reference to `__imp_AdbcStatementGetOption'

I'm OK disabling tests for time time being if we can just get DLLs to build properly (we could perhaps just verify that DLLs and implibs exist)

Hmm interesting, I didn't encounter this. Suggests the DEF/Lib is not getting generated?

Oh wait - is the dll.a sufficient? (That's being installed.) Does the .def file need to be installed?

Unfortunately the DLL by itself is not sufficient, as on Windows the LIB import file is needed in order to link at build time. So without the LIB file the test projects don't build.

@lidavidm
Copy link
Member

Yeah, I ask because it seems the .lib isn't there

- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/pkgconfig/adbc-driver-sqlite.pc
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/include/arrow-adbc/driver/snowflake.h
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/bin/libadbc_driver_snowflake.dll
-- Up-to-date: D:/a/arrow-adbc/arrow-adbc/local/bin/libadbc_driver_snowflake.dll
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/libadbc_driver_snowflake.dll.a
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/cmake/AdbcDriverSnowflake/AdbcDriverSnowflakeConfig.cmake
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/cmake/AdbcDriverSnowflake/AdbcDriverSnowflakeConfigVersion.cmake
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/pkgconfig/adbc-driver-snowflake.pc

@lidavidm
Copy link
Member

Hmm interesting, I didn't encounter this. Suggests the DEF/Lib is not getting generated?

I'm guessing it just doesn't know where to look; either that or the steps aren't getting sequenced right

@IIFE
Copy link
Author

IIFE commented May 30, 2025

Yeah, I ask because it seems the .lib isn't there

- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/pkgconfig/adbc-driver-sqlite.pc
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/include/arrow-adbc/driver/snowflake.h
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/bin/libadbc_driver_snowflake.dll
-- Up-to-date: D:/a/arrow-adbc/arrow-adbc/local/bin/libadbc_driver_snowflake.dll
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/libadbc_driver_snowflake.dll.a
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/cmake/AdbcDriverSnowflake/AdbcDriverSnowflakeConfig.cmake
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/cmake/AdbcDriverSnowflake/AdbcDriverSnowflakeConfigVersion.cmake
-- Installing: D:/a/arrow-adbc/arrow-adbc/local/lib/pkgconfig/adbc-driver-snowflake.pc

Are the 2 required msys64 tools (gendef and dlltool) installed? Is this warning getting generated?

Import library generation tools not found. You may need to link directly to the DLL or use delay-loading.

@lidavidm
Copy link
Member

@IIFE
Copy link
Author

IIFE commented May 30, 2025

I don't see that in the log: https://github.com/apache/arrow-adbc/actions/runs/15340229681/job/43164905567?pr=2858

The issue is down to the commands in GitHub action not simulating Visual Studio. Pushed these changes to the GitHub flow:

  • Use Visual Studio generator so that the required vcxproj files are created
  • Build using msbuild against ALL_BUILD.vcxproj
  • Install using msbuild against INSTALL.vcxproj

Tested the above from PowerShell locally and works as expected. Let's see if the GitHub action passes now. This is also with tests enabled.

@@ -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.
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, how is this handled for the C/C++ builds? I wouldn't think CMake copies the DLL over...

Copy link
Author

Choose a reason for hiding this comment

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

It seems by default cmake copies the dll when it is referenced as a library by another cmake project (the test one in this case). However, because the flightsql and snowflake ones are generated manually via GoUtils, they are not getting copied to the test bin folder.

"${LIBOUT_SHARED}.${ADBC_SO_VERSION}.0.h"
COMMENT "Building Go Shared lib ${GO_LIBNAME}"
COMMAND_EXPAND_LISTS)
if(WIN32)
Copy link
Member

Choose a reason for hiding this comment

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

We're now fully duplicating the build paths...if Windows doesn't want the version suffix, can it just rename the file afterwards instead?

Copy link
Author

Choose a reason for hiding this comment

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

Yes ideally the Windows files don't need the version in the file name, as that makes copying them during build events in Visual Studio difficult. Where is the duplication happening? The main change was to remove ${ADBC_FULL_SO_VERSION} and ${ADBC_SO_VERSION} suffixes.

Copy link
Member

Choose a reason for hiding this comment

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

The build commands are effectively the same, though. If it's just a matter of filename, can we either (1) introduce a variable to hold the filename, or (2) just rename it after build?

@lidavidm
Copy link
Member

lidavidm commented Jun 2, 2025

Also ping @zeroshade

@lidavidm
Copy link
Member

lidavidm commented Jun 4, 2025

I have another concern in that we seem to be installing gmock/gtest, but that should be unrelated to this PR

         -- Install configuration: "Release"
         -- Installing: D:/a/arrow-adbc/arrow-adbc/local/include
         -- Installing: D:/a/arrow-adbc/arrow-adbc/local/include/gmock
         -- Installing: D:/a/arrow-adbc/arrow-adbc/local/include/gmock/gmock-actions.h
         -- Installing: D:/a/arrow-adbc/arrow-adbc/local/include/gmock/gmock-cardinalities.h

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Building ADBC and flightsql driver on Windows
4 participants