msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.25k stars 1.21k forks source link

ld.lld: error: duplicate symbol: std::type_info::operator==(std::type_info const&) const #17730

Open maveric2 opened 1 year ago

maveric2 commented 1 year ago

Description / Steps to reproduce the issue

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

possible solution

Verification

Windows Version

MINGW64_NT-10.0-19042

MINGW environments affected

Are you willing to submit a PR?

No response

silverqx commented 3 months ago

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. 🙃

maveric2 commented 3 months ago

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++"

silverqx commented 3 months ago

Thx for the link, I currently fixed it by defining the __GXX_TYPEINFO_EQUALITY_INLINE macro manually and it works.

Peter0x44 commented 2 months ago

This is fixed on libstdc++ trunk and clang trunk.

silverqx commented 2 months ago

Already fixed, will be released in Clang 19.