Once you have a project that voluntarily uses –allow-multiple-definition with GCC/ld.bfd and cannot be built without it, we can add it to lld. But until then, we should find out what makes the actual error appear if it is not present when building with GCC/ld.bfd. Normally we use with clang ++ –allow-multiple-definition, but it is not supported clang ++ t.cpp -fuse-ld = lld –static -Wl,–allow-multiple-definition lld: error: unknown argument: –allow-multiple-definition The next problem with binding to lld is that binutils seem to increase its section size to multiples of 4, whereas llvm does not. For the clang built object file, the comdat section containing _ZTSSt9exception is 13 bytes, while the one created by gcc is 16 bytes. In general, it should be easy to add the –allow-multiple-definition option in the lld mingw frontend. But in most cases, I would advise against using it, as it usually really needs to solve these problems. Well, the fact is that the object files provided by binutils contain the actual size not filled in the SectionDefinition (coff_aux_section_definition in lld), but we do not always have this structure available when we look for comdat collisions in lld. Specifically, when we parse a new object file, we have the coff_aux_section_definition for that object file, but we don`t just have the coff_aux_section_definition of the previously scanned object file. The latter was actually not too difficult to implement, so with martin.st/temp/0001-LLD-COFF-Check-the-aux-section-definition-size-for-I.patch the link seems to be successful for me.
(The patch lacks a test case before it can be sent upstream.) [EDIT: Update patch later with test case.] So, I took a closer look, and here`s a braindump of the problem – I don`t have a ready-made solution yet (but forcing it with this flag, –allow-multiple-definition in the current git or -Xlink = -force: multiple in existing versions, coupled with the usual -Wl, should work for this problem, but it also masks many other problems). [When I`m done typing, at least I have a patch.] The very first question is – why doesn`t this happen when building with GCC/ld.bfd? ld.bfd is also wrong on several definitions, so this is not a case where we should let LLD tolerate something that ld.bfd tolerates. A multiple definition of “X” is caused when the linker encounters multiple definitions of the same function (Member). See for example the following code: –allow-multiple-definition is something I`ve recently wanted to use myself, but I don`t have time to study yet. Public function declarations go in header files, yes, but definitions are also absolutely valid in headers! You can declare the definition static (only 1 copy allowed for the entire program) if you define elements in a header for utility functions that you do not want to redefine in each c file. That is, the definition of an enumeration and a static function to translate the enumeration into a string. You do not need to rewrite the string enumeration translator for each .c file that contains the header. 🙂 It also doesn`t work if you`re using Clang+ld.bfd (without –allow-multiple-definition), you should probably report it upstream. No, going back to –allow-multiple-definition is wrong at first. This should be the very last step once the full problem is fully understood and it is clear that there are no other solutions. This header file contains both a declaration and a definition of the Class A constructor. The duplicate symbol itself seems to be a problem with clang++, assuming the wrong library is being used, but I don`t know if it`s something in the msys64 port.
I don`t know who is responsible for the fact that ld-link does not support –allow-multiple-definition (lld itself is documented as support). “Huh, but there`s a #include guard!” you might think. Admittedly, this prevents the `Redefinition of` compilation error. However, the (non-inline) definition of the Class A constructor is present in all translation units that this header file #include. > I`m trying to see if the multiple definition of gcc could be ignored. I > tried to do “-z muldefs” with ld but I still encountered the same error. To solve this problem, we can easily switch github.com/llvm/llvm-project/blob/e524daa7e8719f4b43e6ebcf25fd4e7d74c5d1c4/lld/COFF/InputFiles.cpp#L660 def to handleComdatSelection, but github.com/llvm/llvm-project/blob/e524daa7e8719f4b43e6ebcf25fd4e7d74c5d1c4/lld/COFF/InputFiles.cpp#L543 we also need the coff_aux_section_definition associated with leaderChunk and compare sizes with each other instead of comparing sizes of SectionChunks. To check. You can also save the size of the original definition in a new SectionChunk field by github.com/llvm/llvm-project/blob/e524daa7e8719f4b43e6ebcf25fd4e7d74c5d1c4/lld/COFF/InputFiles.cpp#L273-L275. This increases the size of SectionChunk (and a non-trivial effort has been made to keep these objects as small as possible, so new fields should not be added to them lightly). I`ll see if I can reproduce the problems myself somewhere, but in the meantime, a general guess: so it`s by linking a static libstdc++ built by gcc to object files built by clang, either lld or ld.bfd? That`s strange.
This looks like a case where clang and gcc make things vaguely different, and it explodes when statically joined, as there may be functions/sections of data contained in multiple object files (e.g., like inline functions), but they are supposed to be identical in all object files. It`s a bit tricky. This is an example of data (in this case, a member function) with outer join. Avoid file-level external link data . Avoid function definitions that are not inserted into header files. I am trying to see if the multiple definition of gcc could be ignored. I tried to do “-z muldefs” with ld but I still encountered the same error. I read in the gcc manuals about the linker option “-Xlinker” so I used -Xlinker -z -Xlinker muldefs with gcc/g++, but this info *********** gcc:-z: linker input file unused since the link was not madegcc: muldefs: linker input file unused since the link did not do ************Can you suggest to the experts an option I could use to ignore the multiple definitions? I`m trying the -Wl, (-Wl,-zmuldefs) option with gcc. Will it help!! For each comdat, there is a selection box that indicates how conflicts should be resolved, IMAGE_COMDAT_SELECT_ANY that says that all definitions except one are simply discarded, does not matter much if they differ, IMAGE_COMDAT_SELECT_EXACT_MATCH that allows several definitions, provided they correspond exactly, and IMAGE_COMDAT_SELECT_SAME_SIZE, which allows multiple definitions, Do not look at the content, but require it to be the same size.