Skip to content

Conversation

@HaochengLIU
Copy link
Contributor

@HaochengLIU HaochengLIU commented Mar 29, 2023

Rationale for this change

On MacOS, the system GTest from brew uses C++14 while arrow is default to C++17.
The build will fail at the linking stage unless users explicity uses bundled GTest.

Users are often confused by unclear linking errors.

What changes are included in this PR?

At CMake configuration time, the CMake code will automatically detect and
compare the C++ standard used by GTest and arrow. If a mismatch is detected,
CMake will error out and privide meaningful guidance. It will apply both to
linux and MacOS.

Are these changes tested?

Covered by Arrow github test worker and tested on local host.

Are there any user-facing changes?

Yes, now users are given better guidance when building Arrow against the system
GTest.

@github-actions
Copy link

@github-actions
Copy link

⚠️ GitHub issue #14917 has been automatically assigned in GitHub to PR creator.

@HaochengLIU
Copy link
Contributor Author

Hi @AlenkaF , after some thoughts, IMO the correct thing here is to fix things at the building level rather than asking every Arrow user to add an extra flag manually in the doc. I have richful experience with CMake thus I go ahead and touch the toolchain file.

I've tested the build settings from #14779 as well as few build configurations with test enabled and they all build smoothly. Looking forward to your thoughts.

Thanks.

@HaochengLIU HaochengLIU force-pushed the fix-arrow-build-on-macos-arm64 branch from 79ca552 to e2d2c8f Compare March 29, 2023 03:43
@AlenkaF
Copy link
Member

AlenkaF commented Mar 29, 2023

Thank you for the thoughtful contribution @HaochengLIU !

Hi @AlenkaF , after some thoughts, IMO the correct thing here is to fix things at the building level rather than asking every Arrow user to add an extra flag manually in the doc. I have richful experience with CMake thus I go ahead and touch the toolchain file.

That would for sure be useful for all that have this issue. My only thought here is that this doesn't seem to be an issue for every MacOS user. For this reason I suggested to first add this to the docs.

The change in the PR looks good to me though (will still wait for the CI and local test to approve it).

@kou what do you think about this change?

Copy link
Member

Choose a reason for hiding this comment

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

We should not change *_SOURCE in SetupCxxFlags.cmake.
We should process *_SOURCE in ThirdpartyToolchain.cmake.

This problem is caused by C++ standard difference, right?
For example, this problem is caused when Apache Arrow C++ uses C++17 and system GoogleTest uses C++14.

Can we detect whether system GoogleTest uses different C++ standard than Apache Arrow C++? If we can detect it, we can fallback to bundled GoogleTest automatically when system GoogleTest uses different C++ standard.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi Sutou, Good point. I will check CMake and get back to you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After checking the upstream FindGTest.cmake as well as the pkgconfig from GoogleTest on my host, here is my finding:

In order to detect what C++ standard is used by GoogleTest, there is no simple way to do so except by importing it first to my best knowledge. Moreover, once a target is imported, you can not rename or delete it(See Ben's - one of the main CMake developers - comment here). Thus there is no way to fall back to bundled mode.

My new proposed fix is at CMake configuration time, the CMake code will automatically detect and
compare the C++ standard used by GTest and arrow. If a mismatch is detected,
CMake will error out and provide meaningful guidance. With respect to The principle of least astonishment, I prefer to let the users add these flags by themselves.

// sample output from my host
CMake Error at cmake_modules/ThirdpartyToolchain.cmake:2238 (message):
  SYSTEM GTest is built with c++14 but project is built

  with a different standard(17).  Use bundled GTest via passing in CMake flag

  -DGTest_SOURCE="BUNDLED"
Call Stack (most recent call first):
  CMakeLists.txt:505 (include)


-- Configuring incomplete, errors occurred!

Looking forward to your thoughts. @kou .

Copy link
Member

Choose a reason for hiding this comment

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

Can we use try_compile() https://cmake.org/cmake/help/latest/command/try_compile.html for this like we did for gRPC

try_compile(HAS_GRPC_VERSION ${CMAKE_CURRENT_BINARY_DIR}/try_compile
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/try_compile/${TEST_FILE}"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CURRENT_INCLUDE_DIRECTORIES}"
LINK_LIBRARIES gRPC::grpc++ Threads::Threads
OUTPUT_VARIABLE TLS_CREDENTIALS_OPTIONS_CHECK_OUTPUT CXX_STANDARD 11)
?

I think that checking INTERFACE_COMPILE_FEATURES isn't so portable.
For example, libgtest-dev on Debian/Ubuntu still uses cxx_std_11 not cxx_std_14.

For CMake target conflict, we can use different CMake target names (such as arrow::GTest::gtest) and CMake variables to refer suitable CMake targets (such as set(ARROW_GTEST_GTEST arrow::GTest::gtest)) like we did for Zstandard:

if(ZSTD_VENDORED)
set(ARROW_ZSTD_LIBZSTD zstd::libzstd_static)
else()
if(ARROW_ZSTD_USE_SHARED)
set(ARROW_ZSTD_LIBZSTD zstd::libzstd_shared)
else()
set(ARROW_ZSTD_LIBZSTD zstd::libzstd_static)
endif()
if(NOT TARGET ${ARROW_ZSTD_LIBZSTD})
message(FATAL_ERROR "Zstandard target doesn't exist: ${ARROW_ZSTD_LIBZSTD}")
endif()
message(STATUS "Found Zstandard: ${ARROW_ZSTD_LIBZSTD}")
endif()

Copy link
Member

Choose a reason for hiding this comment

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

We can use FindXXXAlt.cmake such as FindGTestAlt.cmake to check such additional check.
We can use FindXXXAlt.cmake by resolve_dependency(... HAVE_ALT TRUE).

Copy link
Member

Choose a reason for hiding this comment

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

The latter.
We can just wrap existing GTestConfig.cmake like we did in FindOpenSSLAlt.cmake: https://github.com/apache/arrow/blob/main/cpp/cmake_modules/FindOpenSSLAlt.cmake

In this PR, We limit the scope to error out whenever INTERFACE_COMPILE_FEATURES from GTest is lower than that? It will be universal to all platforms and truly detect the issue at CMake configure time.

Then in another PR/issue, we can discuss how to implement try_compile and FindXXXAlt.cmake as it will need non trivial work.

It makes sense. Could you update the title of this pull request and open a new issue for the follow-up action?

Copy link
Member

Choose a reason for hiding this comment

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

FYI: If we use the latter approach, we can implement an automatically fallback solution instead of raising an error for C++ standard miss match. (If system GoogleTest isn't suitable, we can use our bundled GoogleTest instead of stopping cmake.)

Copy link
Contributor Author

@HaochengLIU HaochengLIU Mar 31, 2023

Choose a reason for hiding this comment

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

Thanks for the suggestion @kou , I've updated the title of the PR and opened a new follow up issue. Please take a look when you have time

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The failing test - test_generic_options - looks like a flaky one

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting review Awaiting review labels Mar 29, 2023
@HaochengLIU HaochengLIU force-pushed the fix-arrow-build-on-macos-arm64 branch from e2d2c8f to f86840c Compare March 30, 2023 03:00
@github-actions github-actions bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Mar 30, 2023
@HaochengLIU
Copy link
Contributor Author

My only thought here is that this doesn't seem to be an issue for every MacOS user

@AlenkaF I totally agree. With the new change, I believe the doc update is no longer needed since users will do it by themselves with a meaningful error message now?

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting change review Awaiting change review labels Mar 30, 2023
@HaochengLIU HaochengLIU force-pushed the fix-arrow-build-on-macos-arm64 branch from f86840c to 6c540a6 Compare March 30, 2023 22:55
@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 Mar 30, 2023
…d lower than 17

### Rationale for this change
On MacOS, the system GTest from brew uses C++14 while arrow is default to C++17.
The build will fail at the linking stage unless users explicity uses bundled GTest.

Users are often confused by unclear linking errors.

### What changes are included in this PR?
At CMake configuration time, the CMake code will automatically detect and
compare the C++ standard used by GTest and arrow. If a mismatch is detected,
CMake will error out and privide meaningful guidance. It will apply both to
Linux and MacOS.

### Are these changes tested?
Covered by Arrow github test worker and tested on local host.

### Are there any user-facing changes?
Yes, now users are given better guidance when building Arrow against the system
GTest.

* Closes: apache#14917
@HaochengLIU HaochengLIU force-pushed the fix-arrow-build-on-macos-arm64 branch from 6c540a6 to 60b4567 Compare March 31, 2023 00:58
@HaochengLIU HaochengLIU changed the title GH-14917: [C++] Issues with GTest when building Arrow C++ on MacOS GH-14917: [C++] Error out when GTest is compiled with a C++ standard lower than 17 Mar 31, 2023
@github-actions github-actions bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Mar 31, 2023
@github-actions github-actions bot removed the awaiting change review Awaiting change review label Mar 31, 2023
@github-actions github-actions bot added the awaiting changes Awaiting changes label Mar 31, 2023
Copy link
Member

@kou kou left a comment

Choose a reason for hiding this comment

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

+1

@kou kou merged commit 68dc40a into apache:main Mar 31, 2023
@github-actions github-actions bot added awaiting merge Awaiting merge and removed awaiting changes Awaiting changes labels Mar 31, 2023
@ursabot
Copy link

ursabot commented Mar 31, 2023

Benchmark runs are scheduled for baseline = 5dde5d4 and contender = 68dc40a. 68dc40a is a master commit associated with this PR. Results will be available as each benchmark for each run completes.
Conbench compare runs links:
[Finished ⬇️0.0% ⬆️0.0%] ec2-t3-xlarge-us-east-2
[Failed ⬇️0.18% ⬆️0.0%] test-mac-arm
[Finished ⬇️0.26% ⬆️0.0%] ursa-i9-9960x
[Failed ⬇️0.0% ⬆️0.0%] ursa-thinkcentre-m75q
Buildkite builds:
[Finished] 68dc40a1 ec2-t3-xlarge-us-east-2
[Failed] 68dc40a1 test-mac-arm
[Finished] 68dc40a1 ursa-i9-9960x
[Failed] 68dc40a1 ursa-thinkcentre-m75q
[Finished] 5dde5d4e ec2-t3-xlarge-us-east-2
[Failed] 5dde5d4e test-mac-arm
[Finished] 5dde5d4e ursa-i9-9960x
[Finished] 5dde5d4e ursa-thinkcentre-m75q
Supported benchmarks:
ec2-t3-xlarge-us-east-2: Supported benchmark langs: Python, R. Runs only benchmarks with cloud = True
test-mac-arm: Supported benchmark langs: C++, Python, R
ursa-i9-9960x: Supported benchmark langs: Python, R, JavaScript
ursa-thinkcentre-m75q: Supported benchmark langs: C++, Java

@austin3dickey
Copy link
Contributor

FYI, this PR caused the cpp-micro benchmarks to start failing. See linked issue ^

@jorisvandenbossche
Copy link
Member

Is this limitation necessary on non-MacOS systems? I have been using the conda installed gtest on linux, and don't remember to have run into problems with this

@HaochengLIU
Copy link
Contributor Author

Yes. It's platform agnostic, only depending on which C++ standard gtest is compiled with.

@jorisvandenbossche
Copy link
Member

But the reported issues all seem to involve people using Mac? As mentioned, I have always been using gtest from conda on linux, and never ran into any issues with it (while now this check avoids a successful compilation)

@HaochengLIU
Copy link
Contributor Author

It depends on how conda builds/ships gtest on linux which I'm not familiar with. When you say "while now this check avoids a successful compilation", does it happen after this #34874?

@kou
Copy link
Member

kou commented Apr 5, 2023

We use INTERFACE_COMPILE_FEATURES for this approach but it's not perfect because GoogleTest always sets cxx_std_14 (or cxx_std_11 in older Google Test): https://github.com/google/googletest/blob/7ee260c54921571b18b15049304426fe151c1265/googletest/cmake/internal_utils.cmake#L204

But GoogleTest may be built with C++17 even when INTERFACE_COMPILE_FEATURES is cxx_std_14 or cxx_std_11.
It's occurred when C++ compiler uses C++17 by default. (Recent Linux distributions will use g++ that uses C++17 by default.)

I'll implement #34813. Please wait for a few days.

FYI: We need a GoogleTest that uses https://github.com/google/googletest/blob/7ee260c54921571b18b15049304426fe151c1265/googletest/include/gtest/internal/gtest-port.h#L2470-L2482

@jorisvandenbossche
Copy link
Member

When you say "while now this check avoids a successful compilation", does it happen after this #34874?

No, because when you use ARROW_DEPENDENCY_SOURCE=CONDA, it get actually set to SYSTEM for each of the dependencies (but with the path (ARROW_PACKAGE_PREFIX) pointing to the conda prefix)

@kou thanks for taking a look!

kou added a commit that referenced this pull request Apr 6, 2023
### Rationale for this change

#34765 approach has some corner cases. They causes CI failures.

### What changes are included in this PR?

If incompatible GoogleTest is detected, we can fallback to bundled GoogleTest automatically.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

Yes.
* Closes: #34813

Authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
liujiacheng777 pushed a commit to LoongArch-Python/arrow that referenced this pull request May 11, 2023
### Rationale for this change

apache#34765 approach has some corner cases. They causes CI failures.

### What changes are included in this PR?

If incompatible GoogleTest is detected, we can fallback to bundled GoogleTest automatically.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

Yes.
* Closes: apache#34813

Authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
ArgusLi pushed a commit to Bit-Quill/arrow that referenced this pull request May 15, 2023
…ndard lower than 17 (apache#34765)

### Rationale for this change
On MacOS, the system GTest from brew uses C++14 while arrow is default to C++17.
The build will fail at the linking stage unless users explicity uses bundled GTest.

Users are often confused by unclear linking errors.

### What changes are included in this PR? 
At CMake configuration time, the CMake code will automatically detect and 
compare the C++ standard used by GTest and arrow. If a mismatch is detected,
CMake will error out and privide meaningful guidance. It will apply both to
linux and MacOS.

### Are these changes tested?
Covered by Arrow github test worker and tested on local host.

### Are there any user-facing changes?
Yes, now users are given better guidance when building Arrow against the system
GTest.

* Closes: apache#14917
* Closes: apache#14779

Authored-by: Haocheng Liu <lbtinglb@gmail.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
ArgusLi pushed a commit to Bit-Quill/arrow that referenced this pull request May 15, 2023
### Rationale for this change

apache#34765 approach has some corner cases. They causes CI failures.

### What changes are included in this PR?

If incompatible GoogleTest is detected, we can fallback to bundled GoogleTest automatically.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

Yes.
* Closes: apache#34813

Authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
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.

[C++] Issues with GTest when building Arrow C++ on MacOS [C++] Compiling failed on Mac M1

6 participants