GothicKit/ZenKit

Support `-flto`

lmichaelis opened this issue · 2 comments

As originally discussed in Try/OpenGothic#521, compilation seems to fail when enabling link-time-optimization in GCC. I am however not capable of reproducing the issue locally.

Generally, enabling additional optimization capabilities is a good idea I think.

Hi, I can reproduce this during LTO build of OPG on Fedora 38, GCC 13.2.1. Using Try/OpenGothic@fb11adaf.
When building from cmake -B build -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON:

...
[100%] Linking CXX executable opengothic/Gothic2Notr

/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/script.hh:408:15: error: type ‘struct symbol’ violates the C++ One Definition Rule [-Werror=odr]
  408 |         class symbol final {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/script.hh:408:15: note: a different type is defined in another translation unit
  408 |         class symbol final {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/script.hh:658:21: note: the first difference of corresponding definitions is field ‘_m_value’
  658 |                     _m_value;
      |                     ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/script.hh:658:21: note: a field of same name but different type is defined in another translation unit
  658 |                     _m_value;
      |                     ^
/usr/include/c++/13/variant:1337:11: note: type ‘struct variant’ itself violates the C++ One Definition Rule
 1337 |     class variant
      |           ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:45:15: error: type ‘struct VfsNode’ violates the C++ One Definition Rule [-Werror=odr]
   45 |         class VfsNode {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:45:15: note: a different type is defined in another translation unit
   45 |         class VfsNode {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:73:60: note: the first difference of corresponding definitions is field ‘_m_data’
   73 |                 std::variant<std::vector<VfsNode>, buffer> _m_data;
      |                                                            ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:73:60: note: a field of same name but different type is defined in another translation unit
   73 |                 std::variant<std::vector<VfsNode>, buffer> _m_data;
      |                                                            ^
/usr/include/c++/13/variant:1337:11: note: type ‘struct variant’ itself violates the C++ One Definition Rule
 1337 |     class variant
      |           ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:84:15: error: type ‘struct Vfs’ violates the C++ One Definition Rule [-Werror=odr]
   84 |         class Vfs {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:84:15: note: a different type is defined in another translation unit
   84 |         class Vfs {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:171:25: note: the first difference of corresponding definitions is field ‘_m_root’
  171 |                 VfsNode _m_root;
      |                         ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:171:25: note: a field of same name but different type is defined in another translation unit
  171 |                 VfsNode _m_root;
      |                         ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/Vfs.hh:45:15: note: type ‘struct VfsNode’ itself violates the C++ One Definition Rule
   45 |         class VfsNode {
      |               ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/vm.hh:74:16: error: type ‘struct daedalus_stack_frame’ violates the C++ One Definition Rule [-Werror=odr]
   74 |         struct daedalus_stack_frame {
      |                ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/vm.hh:74:16: note: a different type is defined in another translation unit
   74 |         struct daedalus_stack_frame {
      |                ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/vm.hh:77:82: note: the first difference of corresponding definitions is field ‘value’
   77 |                 std::variant<int32_t, float, symbol*, std::shared_ptr<instance>> value;
      |                                                                                  ^
/home/black_fox/src/OpenGothic/lib/phoenix/include/phoenix/vm.hh:77:82: note: a field of same name but different type is defined in another translation unit
   77 |                 std::variant<int32_t, float, symbol*, std::shared_ptr<instance>> value;
      |                                                                                  ^
/usr/include/c++/13/variant:1337:11: note: type ‘struct variant’ itself violates the C++ One Definition Rule
 1337 |     class variant
      |           ^
lto1: all warnings being treated as errors
lto-wrapper: fatal error: /usr/bin/c++ returned 1 exit status
compilation terminated.
mold: fatal: lto-wrapper failed
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Gothic2Notr.dir/build.make:2538: opengothic/Gothic2Notr] Error 1
make[1]: *** [CMakeFiles/Makefile2:567: CMakeFiles/Gothic2Notr.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
make: Leaving directory '/home/black_fox/src/OpenGothic/build'

Oh, thank you! I am now able to reproduce the errors! Looks like I just had to update my packages. I was about to say that this does not make any sense since I don't control std::variant but it looks like this has already been reported as a bug in GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111089. Looks like Clang does not have this issue but I can't confirm that it actually does LTO.

@CReimer looks like you should just disable LTO in the PKGBUILD then until this is fixed :)