This is just to summarize my experience while trying to compile Octave for mingw32 with LTO (link time optimization) using MXE Octave.
To state the most important at the beginning: I wasn’t successful.
But still this might help someone else that tries to do something similar. (Maybe at least, it’ll save them some time.)
If I understand GCC’s documentation correctly, using LTO should be possible in principle for a mingw target:
LTO Overview (GNU Compiler Collection (GCC) Internals)
Currently, LTO support is enabled in most ELF-based systems, as well as darwin, cygwin and mingw systems.
I wanted to see if there is any measurable performance difference when using LTO compared to a “regular” build.
I used this patch for the build rule of default Octave: mxe-octave-lto.patch (1.6 KB)
Compilation went smoothly. But I got the following errors when linking liboctinterp:
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-pager.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD1Ev[_ZThn8_N11oprocstreamD1Ev]+0x0): multiple definition of `oprocstream::~oprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD1Ev[_ZTv0_n24_N11oprocstreamD1Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-pager.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD1Ev[_ZThn8_N11oprocstreamD1Ev]+0x0): multiple definition of `non-virtual thunk to oprocstream::~oprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD1Ev[_ZTv0_n24_N11oprocstreamD1Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-pager.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD1Ev[_ZThn8_N11oprocstreamD1Ev]+0x0): multiple definition of `virtual thunk to oprocstream::~oprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD1Ev[_ZTv0_n24_N11oprocstreamD1Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-pager.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD0Ev[_ZThn8_N11oprocstreamD0Ev]+0x0): multiple definition of `oprocstream::~oprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD0Ev[_ZTv0_n24_N11oprocstreamD0Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-pager.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD0Ev[_ZThn8_N11oprocstreamD0Ev]+0x0): multiple definition of `non-virtual thunk to oprocstream::~oprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD0Ev[_ZTv0_n24_N11oprocstreamD0Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-pager.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD0Ev[_ZThn8_N11oprocstreamD0Ev]+0x0): multiple definition of `virtual thunk to oprocstream::~oprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11oprocstreamD0Ev[_ZTv0_n24_N11oprocstreamD0Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-toplev.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD1Ev[_ZThn16_N11iprocstreamD1Ev]+0x0): multiple definition of `iprocstream::~iprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD1Ev[_ZTv0_n24_N11iprocstreamD1Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-toplev.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD1Ev[_ZThn16_N11iprocstreamD1Ev]+0x0): multiple definition of `non-virtual thunk to iprocstream::~iprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD1Ev[_ZTv0_n24_N11iprocstreamD1Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-toplev.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD1Ev[_ZThn16_N11iprocstreamD1Ev]+0x0): multiple definition of `virtual thunk to iprocstream::~iprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD1Ev[_ZTv0_n24_N11iprocstreamD1Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-toplev.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD0Ev[_ZThn16_N11iprocstreamD0Ev]+0x0): multiple definition of `iprocstream::~iprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD0Ev[_ZTv0_n24_N11iprocstreamD0Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-toplev.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD0Ev[_ZThn16_N11iprocstreamD0Ev]+0x0): multiple definition of `non-virtual thunk to iprocstream::~iprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD0Ev[_ZTv0_n24_N11iprocstreamD0Ev]+0x0): first defined here
/home/osboxes/Documents/Repositories/Octave/mxe-octave/usr/bin/x86_64-w64-mingw32-ld: libcorefcn_la-toplev.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD0Ev[_ZThn16_N11iprocstreamD0Ev]+0x0): multiple definition of `virtual thunk to iprocstream::~iprocstream()'; libcorefcn_la-dirfns.o (symbol from plugin):(.gnu.linkonce.t._ZN11iprocstreamD0Ev[_ZTv0_n24_N11iprocstreamD0Ev]+0x0): first defined here
collect2: error: ld returned 1 exit status
It is “only” complaining about two classes: iprocstream
and oprocstream
.
This might be caused by the issue described in this bug report against gcc:
94156 – Multiple definition of destructor and non-virtual thunk for classes that use multiple inheritance when building static library (gnu.org)
The inheritance of those two classes is
class
OCTINTERP_API
iprocstream : public std::istream, public procstreambase
and
class
OCTINTERP_API
oprocstream : public std::ostream, public procstreambase
They also inherit from multiple classes like in the linked bug report.
It is interesting that it doesn’t complain about procstream
which has very similar inheritance:
class
OCTINTERP_API
procstream : public std::iostream, public procstreambase
AFAICT, this is not a bug in Octave. But more likely a compiler/linker issue.
That’s all I got.