Skip to content

GH-55279: [C++] Fix build errors with ARROW_BUILD_{SHARED,STATIC,TESTS}=ON on Windows - #55294

Open
kou wants to merge 7 commits into
apache:mainfrom
kou:ci-windows-build-static
Open

kou wants to merge 7 commits into
apache:mainfrom
kou:ci-windows-build-static

Conversation

@kou

@kou kou commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Rationale for this change

We can't build Arrow C++ with ARROW_BUILD_SHARED=ON, ARROW_BUILD_STATIC=ON and ARROW_BUILD_TESTS=ON on Windows. Tests are linked with shared libraries by default (ARROW_TEST_LINKAGE=shared) but some targets use ARROW_BUILD_STATIC to choose static libraries/definitions:

  • arrow_compute_testing is an object library and it sets ARROW_STATIC/ARROW_COMPUTE_STATIC as public compile definitions with ARROW_BUILD_STATIC. So tests that use arrow_compute_testing are compiled with ARROW_STATIC/ARROW_COMPUTE_STATIC even when they are linked with shared libraries.
  • arrow-compute-grouper-benchmark links arrow_compute_static with ARROW_BUILD_STATIC. So it's linked with both of arrow_static and arrow_shared.

parquet_static can't be built with Parquet encryption on Windows too. It doesn't link OpenSSL. We don't use a shared object library for shared and static libraries on Windows. So parquet_static can't find OpenSSL headers. parquet/arrow/reader.cc uses OpenTelemetry headers via arrow/util/tracing_internal.h but parquet_static doesn't link OpenTelemetry.

Our CI doesn't detect them because we don't have any Windows job that uses ARROW_BUILD_SHARED=ON and ARROW_BUILD_STATIC=ON.

There are similar problems that aren't detected by our CI:

  • Parquet benchmarks use parquet_shared with static test libraries when ARROW_BUILD_SHARED=ON, ARROW_BUILD_STATIC=ON and ARROW_TEST_LINKAGE=static. So they're linked with both of arrow_static and arrow_shared.
  • parquet_testing is an object library that doesn't have ARROW_STATIC/PARQUET_STATIC. So parquet/test_util.cc is compiled without them even when tests are linked with static libraries on Windows.

What changes are included in this PR?

  • Use ARROW_BUILD_STATIC=ON in the Windows CI job to detect this case.
  • Link OpenSSL to parquet_static when Parquet encryption is enabled.
  • Link OpenTelemetry to parquet_static when OpenTelemetry is enabled.
  • Use interface libraries instead of object libraries for arrow_compute_core_testing, arrow_compute_testing, arrow_compute_kernels_testing, arrow_acero_testing and arrow_dataset_testing. Sources of interface libraries are compiled as sources of each test executable. So they use the same compile definitions as the test. We don't need to set ARROW_STATIC/ARROW_COMPUTE_STATIC manually.
    • Testing interface libraries must be linked only by test/benchmark executables. If they are linked by other targets such as object libraries, their sources are also compiled into these targets. (This is why arrow_dataset_testing doesn't link ${ARROW_DATASET_TEST_LINK_LIBS} now.)
    • arrow_compute_kernels_testing and arrow_acero_testing link arrow_compute_core_testing because they use it.
    • Use a fully qualified name for MapVector in arrow/compute/test_util_internal.cc because internal:: refers to arrow::compute::internal:: in unity build files.
  • Use ARROW_TEST_LINKAGE instead of ARROW_BUILD_STATIC to choose a compute library for arrow-compute-grouper-benchmark.
  • Use ARROW_TEST_LINKAGE instead of ARROW_BUILD_SHARED to choose a Parquet library for Parquet benchmarks.

Note that the ORC adapter test still uses ARROW_BUILD_STATIC to choose libraries. It uses liborc directly and links orc::orc. If it's linked with arrow_shared, ORC's protobuf messages are registered twice (by libarrow and the test). We'll work on it separately if we need it.

Are these changes tested?

Yes.

Are there any user-facing changes?

No.

Was AI used for this PR?

In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.

PR code and description written by:

  • Human
  • AI

Reviewed before submission by:

  • Human
  • AI
  • Not reviewed

Copilot AI balanced review requested due to automatic review settings October 28, 2026 00:07
@kou
kou marked this pull request as draft October 28, 2026 00:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@github-actions github-actions Bot added the awaiting committer review Awaiting committer review label Oct 28, 2026
parquet_static isn't compiled from the shared object library on
Windows. So it needs OpenSSL in its own link libraries to find OpenSSL
headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kou

kou commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

Confirmed: https://github.com/apache/arrow/actions/runs/40611094510/job/122562525836?pr=55294#step:11:6776

FAILED: [code=2] src/arrow/c/CMakeFiles/arrow-c-bridge-test.dir/Unity/unity_0_cxx.cxx.obj 
"C:\Program Files\Git\usr\bin\ccache.exe" C:\PROGRA~1\MICROS~2\2022\ENTERP~1\VC\Tools\MSVC\1444~1.352\bin\Hostx64\x64\cl.exe  /nologo /TP -DARROW_COMPUTE_STATIC -DARROW_HAVE_AVX2 -DARROW_HAVE_BMI2 -DARROW_HAVE_RUNTIME_AVX2 -DARROW_HAVE_RUNTIME_AVX512 -DARROW_HAVE_RUNTIME_BMI2 -DARROW_HAVE_RUNTIME_SSE4_2 -DARROW_HAVE_SSE4_2 -DARROW_STATIC -DARROW_WITH_BENCHMARKS_REFERENCE -DARROW_WITH_TIMING_TESTS -DGTEST_LINKED_AS_SHARED_LIBRARY=1 -D_CRT_SECURE_NO_WARNINGS -ID:\a\arrow\arrow\build\cpp\src -ID:\a\arrow\arrow\cpp\src -external:ID:\a\arrow\arrow\build\cpp\_deps\googletest-src\googlemock\include -external:ID:\a\arrow\arrow\build\cpp\_deps\googletest-src\googletest\include -external:ID:\a\arrow\arrow\cpp\thirdparty\flatbuffers\include -external:ID:\a\arrow\arrow\build\cpp\_deps\googletest-src\googletest -external:ID:\a\arrow\arrow\build\cpp\_deps\googletest-src\googlemock -external:W0 /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING /W3 /EHsc /Zc:preprocessor /bigobj /utf-8 /W3 /wd4365 /wd4267 /wd4838 /wd4800 /wd4996 /wd4065 /arch:AVX2  /Ob0 /Od /RTC1 /WX -std:c++20 -MDd -Z7 /showIncludes /Fosrc\arrow\c\CMakeFiles\arrow-c-bridge-test.dir\Unity\unity_0_cxx.cxx.obj /Fdsrc\arrow\c\CMakeFiles\arrow-c-bridge-test.dir\ /FS -c D:\a\arrow\arrow\build\cpp\src\arrow\c\CMakeFiles\arrow-c-bridge-test.dir\Unity\unity_0_cxx.cxx
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(30): error C2220: the following warning is treated as an error
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(30): warning C4275: non dll-interface class 'arrow::ExtensionArray' used as base for dll-interface class 'arrow::ExampleUuidArray'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(107): note: see declaration of 'arrow::ExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(30): note: see declaration of 'arrow::ExampleUuidArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(35): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::ExampleUuidType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(35): note: see declaration of 'arrow::ExampleUuidType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(52): warning C4275: non dll-interface class 'arrow::ExtensionArray' used as base for dll-interface class 'arrow::SmallintArray'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(107): note: see declaration of 'arrow::ExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(52): note: see declaration of 'arrow::SmallintArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(57): warning C4275: non dll-interface class 'arrow::ExtensionArray' used as base for dll-interface class 'arrow::TinyintArray'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(107): note: see declaration of 'arrow::ExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(57): note: see declaration of 'arrow::TinyintArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(62): warning C4275: non dll-interface class 'arrow::ExtensionArray' used as base for dll-interface class 'arrow::ListExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(107): note: see declaration of 'arrow::ExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(62): note: see declaration of 'arrow::ListExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(67): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::SmallintType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(67): note: see declaration of 'arrow::SmallintType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(84): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::TinyintType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(84): note: see declaration of 'arrow::TinyintType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(101): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::ListExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(101): note: see declaration of 'arrow::ListExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(118): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::DictExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(118): note: see declaration of 'arrow::DictExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(135): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::BinaryViewExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(135): note: see declaration of 'arrow::BinaryViewExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(153): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::MetadataOptionalExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(153): note: see declaration of 'arrow::MetadataOptionalExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(171): warning C4275: non dll-interface class 'arrow::ExtensionArray' used as base for dll-interface class 'arrow::UnionExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(107): note: see declaration of 'arrow::ExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(171): note: see declaration of 'arrow::UnionExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(181): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::UnionExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(181): note: see declaration of 'arrow::UnionExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(203): warning C4275: non dll-interface class 'arrow::ExtensionArray' used as base for dll-interface class 'arrow::Complex128Array'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(107): note: see declaration of 'arrow::ExtensionArray'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(203): note: see declaration of 'arrow::Complex128Array'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(208): warning C4275: non dll-interface class 'arrow::ExtensionType' used as base for dll-interface class 'arrow::Complex128Type'
D:\a\arrow\arrow\cpp\src\arrow/extension_type.h(39): note: see declaration of 'arrow::ExtensionType'
D:\a\arrow\arrow\cpp\src\arrow/testing/extension_type.h(208): note: see declaration of 'arrow::Complex128Type'

@kou
kou force-pushed the ci-windows-build-static branch 2 times, most recently from 15d8bbc to 24e1a08 Compare October 28, 2026 02:22
kou and others added 2 commits October 28, 2026 11:46
arrow_compute_core_testing, arrow_compute_testing,
arrow_compute_kernels_testing, arrow_acero_testing and
arrow_dataset_testing were object libraries. Object libraries are
compiled with their own compile definitions, not with test's compile
definitions. So we needed to set ARROW_STATIC and ARROW_COMPUTE_STATIC
manually for arrow_compute_testing on Windows. But it was wrong with
ARROW_BUILD_SHARED=ON, ARROW_BUILD_STATIC=ON and
ARROW_TEST_LINKAGE=shared.

Interface libraries with interface sources are compiled as sources of
each test executable. So they use the same compile definitions as the
test automatically.

Testing interface libraries must be linked only by test and benchmark
executables. If they are linked by other targets such as object
libraries, their sources are also compiled into the targets.

arrow_compute_kernels_testing and arrow_acero_testing now link
arrow_compute_core_testing because they use arrow_compute_core_testing.

Sources of testing interface libraries are compiled in unity build
files with test sources. So we need to use a fully qualified name for
MapVector in arrow/compute/test_util_internal.cc. internal:: refers
to arrow::compute::internal:: in unity build files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ARROW_BUILD_STATIC=ON doesn't mean that benchmarks are linked
statically. Benchmarks use ARROW_TEST_LINK_LIBS that depends on
ARROW_TEST_LINKAGE. If we use arrow_compute_static with
ARROW_TEST_LINKAGE=shared, both arrow_static and arrow_shared are
linked. It causes duplicated symbol errors on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kou
kou force-pushed the ci-windows-build-static branch from 24e1a08 to ee78b4d Compare October 28, 2026 02:46
@kou

kou commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

@github-actions crossbow submit -g cpp

@github-actions

Copy link
Copy Markdown

Revision: ee78b4d

Submitted crossbow builds: ursacomputing/crossbow @ actions-9252eadce2

Task Status
example-cpp-minimal-build-static GitHub Actions
example-cpp-minimal-build-static-system-dependency GitHub Actions
example-cpp-tutorial GitHub Actions
test-build-cpp-fuzz GitHub Actions
test-conda-cpp GitHub Actions
test-conda-cpp-valgrind GitHub Actions
test-debian-13-cpp-amd64 GitHub Actions
test-debian-13-cpp-i386 GitHub Actions
test-debian-experimental-cpp-gcc-15 GitHub Actions
test-fedora-42-cpp GitHub Actions
test-ubuntu-22.04-cpp GitHub Actions
test-ubuntu-22.04-cpp-bundled GitHub Actions
test-ubuntu-22.04-cpp-emscripten GitHub Actions
test-ubuntu-22.04-cpp-no-threading GitHub Actions
test-ubuntu-24.04-cpp GitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundled GitHub Actions
test-ubuntu-24.04-cpp-gcc-14 GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formats GitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizer GitHub Actions

@kou kou added the CI: Extra: C++ Run extra C++ CI label Oct 28, 2026
@kou
kou marked this pull request as ready for review October 28, 2026 05:23
Copilot AI balanced review requested due to automatic review settings October 28, 2026 05:24
@kou kou changed the title GH-55279: [C++] Fix a build error with ARROW_BUILD_{SHARED,STATIC,TESTS}=ON on Windows GH-55279: [C++] Fix build errors with ARROW_BUILD_{SHARED,STATIC,TESTS}=ON on Windows Oct 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@kou

kou commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

This is ready.

I think that we should use INTERFACE instead of OBJECT + manual configurations for *_testing CMake targets. If we use INTERFACE, we don't need to set manual configurations because INTERFACE CMake targets use configurations of dependencies automatically.

We need to build the same source files multiple times with INTERFACE but it's not a problem with ccache. We can reuse build results by ccache.

@zanmato1984 zanmato1984 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1

Thanks for working on this.

@raulcd raulcd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, just a couple of minor things I have found trying to find other patterns that might not be covered by this specific build.

Comment thread cpp/src/arrow/compute/row/CMakeLists.txt
Comment thread cpp/src/parquet/CMakeLists.txt
@github-actions github-actions Bot added awaiting merge Awaiting merge and removed awaiting committer review Awaiting committer review labels Oct 28, 2026
Copilot AI balanced review requested due to automatic review settings October 29, 2026 02:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

parquet/arrow/reader.cc uses OpenTelemetry headers via
arrow/util/tracing_internal.h. parquet_static can't find them on
Windows because we don't use a shared object library for shared and
static libraries on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kou
kou force-pushed the ci-windows-build-static branch from 1c48296 to a958284 Compare October 29, 2026 03:12
Copilot AI balanced review requested due to automatic review settings October 29, 2026 03:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@github-actions github-actions Bot added awaiting changes Awaiting changes and removed awaiting merge Awaiting merge labels Oct 29, 2026
kou and others added 2 commits October 29, 2026 17:01
Parquet benchmarks used parquet_shared with static test libraries when
ARROW_BUILD_SHARED=ON and ARROW_TEST_LINKAGE=static.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_util.cc is compiled as a source of each test executable so that
it uses the same compile definitions as the test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kou
kou force-pushed the ci-windows-build-static branch from a958284 to 5756a51 Compare October 29, 2026 08:02
Copilot AI balanced review requested due to automatic review settings October 29, 2026 08:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@github-actions github-actions Bot added awaiting change review Awaiting change review awaiting changes Awaiting changes and removed awaiting changes Awaiting changes awaiting change review Awaiting change review labels Oct 29, 2026
@pitrou

pitrou commented Oct 29, 2026

Copy link
Copy Markdown
Member

We need to build the same source files multiple times with INTERFACE but it's not a problem with ccache. We can reuse build results by ccache.

That doesn't sound great. Not everyone uses ccache I suppose, and it can have limitations too (such as unsupported compile options).

For example, "AMD64 Conda C++ AVX2" used to have 1312 build steps, now it has 1522 build steps...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants