On Wed, 29 Dec 2021 at 17:01, Jonathan Wakely wrote: > > On Wed, 29 Dec 2021 at 16:16, Tom Kacvinsky <tkacvins@xxxxxxxxx> wrote: > > > > On Wed, Dec 29, 2021 at 10:39 AM Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > > > > > > > > > > > > On Wed, 29 Dec 2021, 11:45 Tom Kacvinsky via Gcc-help, <gcc-help@xxxxxxxxxxx> wrote: > > >> > > >> Hi, > > >> > > >> First, using GCC 8.3.0 and binutils 2.37.I am trying to increase > > >> performance of linking our product, so I thought I'd give LTO a try. So > > >> I am compiling all object files with -flto, and passing -flto to g++ > > >> (which we use as our link driver). However, what I have found is that > > >> some of our code violates the C++ One Definition Rule (-Werror=odr). This > > >> only happens when building with LTO - without LTO, the C++ rule is > > >> not violated. > > > > > > > > > As already explained, this is almost certainly wrong. It is more likely that the LTO violation is always present, but only detected when using LTO. > > > > > > > > >> The problem exists with LTO using both the BFD and gold > > >> linkers. > > >> > > >> So, my question is, since the LTO object files are now such that one > > >> needs to use gcc-nm to examine them (which I know is a wrapper around nm, > > >> and passes an option to load the LTO plugin). how can I leverage that to > > >> see if there are other translation units that define the class that ODR > > >> violation is complaining about? I did do a fairly thorough analysis of > > >> the object files and did not see there the particular class and methods > > >> would be multiply defined, > > > > > > > > > It would help if you tell us the actual error/warning you get. -Wodr can warn about various different things. It does not warn about multiple definitions, it warns about *inconsistent* definitions. > > > > > > > This is long. Not sure of the attachment fule for this, so I am > > pasting it in email. Ib obfuscated the actual source file > > names, but this is the general gist of the link error. I wonder if > > the error is coming from boost::python::api::object. > > > > /home/home/tkacvins/project/libbar/include/Bar.h:38:7: error: type > > ‘struct Bar’ violates the C++ One Definition Rule [-Werror=odr] > > You said it was defined in one C++ file, but it's clearly defined in a > header. So the problem is that the definition is different in > different translation units. > > > > > class Bar { > > ^ > > /home/home/tkacvins/project/libbar/include/Bar.h:38:7: note: a > > different type is defined in another translation unit > > class Bar { > > ^ > > /home/home/tkacvins/project/libbar/include/Bar.h:40:32: note: the > > first difference of corresponding definitions is field ‘api’ > > boost::python::object* api; > > ^ > > /home/home/tkacvins/project/libbar/include/Bar.h:40:32: note: a field > > of same name but different type is defined in another translation unit > > boost::python::object* api; > > ^ > > /home/home/tkacvins/project/libbar/include/Bar.h:15:11: note: type > > name ‘boost::python::object’ should match type name > > ‘boost::python::api::object’ > > class object; > > ^ > > /home/BUILD64/lib/boost-1.69.0-py39-1/include/boost/python/object_core.hpp:238:9: > > note: the incompatible type is defined here > > class object : public object_base > > ^ > > As it says, one definition has a member of type > ‘boost::python::object’ and another has a member of type > ‘boost::python::api::object’. I have two guesses how that could > happen: either you're compiling with two different versions of boost > (which seems unlikely because I think boost::python::api::object has > been in that namespace for 20 years), or you are using a forward > declaration of boost::python::object in your own files, instead of > including the correct boost header to define it properly. > > The most likely explanation is that somebody tried to "optimize" the > build by cheating, and not including the right boost header for the > type. Including <boost/python/object_fwd.hpp> would be the correct way to do that.