ld.lld: error: duplicate symbol: std::type_info::operator==(std::type_info const&) const
Description / Steps to reproduce the issue
- install msys2 bundle
- install mingw-w64-clang:
-
- pacman -S mingw-w64-x86_64-clang
-
- pacman -S mingw-w64-x86_64-lld
- create files to reproduce the linker error (comp_unit.cpp, comp_unit.h, main.cpp)
comp_unit.h
#pragma once
#include <condition_variable>
class comp_unit {
std::condition_variable_any m_cv; // root cause, if line is removed -> works
public:
comp_unit();
};
There may be a better vehicle to reproduce, but we reduced a real world example to this minimum.
comp_unit.cpp
#include "comp_unit.h"
comp_unit::comp_unit() {
}
main.cpp
#include <iostream>
int main() {
std::cout << "__GXX_TYPEINFO_EQUALITY_INLINE " << __GXX_TYPEINFO_EQUALITY_INLINE << std::endl;
std::cout << "__GXX_MERGED_TYPEINFO_NAMES " << __GXX_MERGED_TYPEINFO_NAMES << std::endl;
std::cout << "__GXX_WEAK__ " << __GXX_WEAK__ << std::endl;
std::cout << "Hallo from main!!!!!!!" << std::endl;
return 0;
}
Now compile and link
export CLANG_HOME=/mingw64
export CXX=${CLANG_HOME}/bin/clang++
${CXX} -c comp_unit.cpp -o comp_unit.o
${CXX} -c main.cpp -o main.o
${CLANG_HOME}/bin/llvm-ar cr libclang_lld_error.a comp_unit.o
// ERROR
${CXX} -static main.o -pthread -fuse-ld=lld -L. -lclang_lld_error -o main.exe
Expected behavior
compile and link successfully ;-)
Actual behavior
ld.lld: error: duplicate symbol: std::type_info::operator==(std::type_info const&) const
>>> defined at ../../../../libstdc++-v3/libsupc++/tinfo.cc:38
>>> libstdc++.a(tinfo.o)
>>> defined at libclang_lld_error.a(comp_unit.o)
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
Issue Clang doesn't define the macro __GXX_TYPEINFO_EQUALITY_INLINE which is evaluated within typeinfo AND set it if not set before to __GXX_TYPEINFO_EQUALITY_INLINE=1:
#ifndef __GXX_TYPEINFO_EQUALITY_INLINE
#if !__GXX_WEAK__
#define __GXX_TYPEINFO_EQUALITY_INLINE 0
#else
#define __GXX_TYPEINFO_EQUALITY_INLINE 1
#endif
#endif
GCC defines the macro (built-in) __GXX_TYPEINFO_EQUALITY_INLINE=0 (for mingw only - see gcc/config/i386/cygming.h). Thus the tinfo.o already contains the operator. Now compiling and link the user code the same operator in invoked again, since the __GXX_TYPEINFO_EQUALITY_INLINE switch picks it again from the typeinfo header.
hackaround
- run clang++ with -D__GXX_TYPEINFO_EQUALITY_INLINE=0 to define this macro -> linking went well
- use -fuse-ld=ld to link, it does not recognize this issue -> linking went well
possible solution
- add __GXX_TYPEINFO_EQUALITY_INLINE=0 to clang built-in
- fix the issue within libstdc++/typeinfo (inline the operator==) - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110572
Verification
- [X] I have verified that my MSYS2 is up-to-date before submitting the report (see https://www.msys2.org/docs/updating/)
Windows Version
MINGW64_NT-10.0-19042
MINGW environments affected
- [X] MINGW64
- [ ] MINGW32
- [ ] UCRT64
- [ ] CLANG64
- [ ] CLANG32
- [ ] CLANGARM64
Are you willing to submit a PR?
No response
I'm dealing with this problem for years, the fix was planned for 12.4 but is still unfixed, could somebody ping that issue at GCC bugzilla. I can't as registrations are closed and I don't have an account there.
Is weird that there is one definition that prevents strict -static linking and is unfixed still. 🙃
There is already discussion going on here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110572 see: "N.B. this can be reproduced without clang, just by using -std=c++20 -static-libstdc++"
Thx for the link, I currently fixed it by defining the __GXX_TYPEINFO_EQUALITY_INLINE macro manually and it works.
This is fixed on libstdc++ trunk and clang trunk.
Already fixed, will be released in Clang 19.