-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[fix](build) fix duplicate symbol errors when compiling BE UT with Clang #60504
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
base: master
Are you sure you want to change the base?
Conversation
Problem: When running `./run-be-ut.sh` without the `--coverage` flag using Clang compiler, the build fails with duplicate symbol errors: ld.lld: error: duplicate symbol: __gcov_fork >>> defined in libgcov.a(libgcov-interface.o) >>> defined in libclang_rt.profile-x86_64.a(GCDAProfiling.o) Root cause analysis: PR apache#59543 introduced a condition in be/CMakeLists.txt to guard GCC-style coverage flags (`-fprofile-arcs -ftest-coverage -lgcov`): if (NOT (ENABLE_CLANG_COVERAGE STREQUAL "ON" AND COMPILER_CLANG)) The intent was to skip GCC coverage when Clang coverage is active. However, this condition has a logic flaw. When using Clang without `--coverage`: - ENABLE_CLANG_COVERAGE = OFF (default, set in run-be-ut.sh line 88) - COMPILER_CLANG = true The condition evaluates as: NOT (OFF AND true) = NOT (false) = true So GCC coverage flags are still added even when using Clang. Clang then implicitly links libclang_rt.profile (which provides its own implementation of __gcov_fork, __gcov_reset, etc.), causing duplicate symbol conflicts with the explicitly linked libgcov.a. Before PR apache#59543, coverage flags were unconditionally added for all compilers in MAKE_TEST mode — which also had the same issue with Clang. Fix: Replace the condition with `if (COMPILER_GCC)` so that GCC-style coverage flags are only added when actually using GCC compiler. This cleanly separates the two coverage mechanisms: - GCC compiler → automatic GCC coverage via -fprofile-arcs + libgcov - Clang compiler → no coverage by default; use --coverage flag to enable Clang coverage via -fprofile-instr-generate | Scenario | Before apache#59543 | After apache#59543 (bug) | This fix | |----------------------|---------------|--------------------|-------------| | GCC, no --coverage | GCC coverage | GCC coverage | GCC coverage| | GCC, --coverage | GCC coverage | GCC coverage | GCC coverage| | Clang, no --coverage | GCC cov (bad) | GCC cov (bad) | No coverage | | Clang, --coverage | GCC+Clang(bad)| Clang coverage | Clang cov |
|
run buildall |
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
TPC-H: Total hot run time: 31568 ms |
ClickBench: Total hot run time: 28.69 s |
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
Problem:
When running
./run-be-ut.shwithout the--coverageflag using Clang compiler, the build fails with duplicate symbol errors:ld.lld: error: duplicate symbol: __gcov_fork
Root cause analysis:
PR #59543 introduced a condition in be/CMakeLists.txt to guard GCC-style coverage flags (
-fprofile-arcs -ftest-coverage -lgcov):if (NOT (ENABLE_CLANG_COVERAGE STREQUAL "ON" AND COMPILER_CLANG))
The intent was to skip GCC coverage when Clang coverage is active. However, this condition has a logic flaw. When using Clang without
--coverage:The condition evaluates as:
NOT (OFF AND true) = NOT (false) = true
So GCC coverage flags are still added even when using Clang. Clang then implicitly links libclang_rt.profile (which provides its own implementation of __gcov_fork, __gcov_reset, etc.), causing duplicate symbol conflicts with the explicitly linked libgcov.a.
Before PR #59543, coverage flags were unconditionally added for all compilers in MAKE_TEST mode — which also had the same issue with Clang.
Fix:
Replace the condition with
if (COMPILER_GCC)so that GCC-style coverage flags are only added when actually using GCC compiler. This cleanly separates the two coverage mechanisms:What problem does this PR solve?
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
Release note
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)