Cross-compile works in debug mode, fails in release mode

Here, I'm trying to cross-compile the "rend3" crate's examples to Windows from Linux. Debug compiles. Release fails with a giant linker error.

> git clone https://github.com/BVE-Reborn/rend3.git
> cd rend3
> cargo build --target x86_64_pc-windows-gnu --release

Giant linker error follows. This is so huge I had to put it into an upload.

The error message starts:

   Compiling rend3-imgui-example v0.3.0 (/home/john/projects/rend3/examples/imgui)
   Compiling rend3-egui-example v0.3.0 (/home/john/projects/rend3/examples/egui)
error: linking with `x86_64-w64-mingw32-gcc` failed: exit status: 1
  |
  = note: "x86_64-w64-mingw32-gcc" "-fno-use-linker-plugin" "-Wl,--dynamicbase" "-Wl,--disable-auto-image-base" "-m64" "-Wl,--high-entropy-va" "/home/john/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/rsbegin.o" "/tmp/rustctfBOHd/symbols.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.1cfg6db1xs636qm4.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.0.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.1.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.2.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.3.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.4.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.5.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.6.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.7.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.8.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6400f0093d5a791e.addr2line.eed8dd10-cgu.9.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.addr2line-6d52d94befc8840f.addr2line.7ffcc1e1-cgu.0.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.adler-55ef25959858fd57.adler.e8851cc1-cgu.0.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.ahash-7e0490fb5baa39bf.ahash.d92843b3-cgu.0.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.ahash-7e0490fb5baa39bf.ahash.d92843b3-cgu.1.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.ahash-7e0490fb5baa39bf.ahash.d92843b3-cgu.2.rcgu.o.rcgu.o" "/home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/

and a few thousand lines later, we get to

  = note: /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.rend3-453033c5e7b550be.rend3.e9d9b511-cgu.15.rcgu.o.rcgu.o: in function `core::sync::atomic::atomic_load':
          /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483\library\core\src\sync\atomic.rs:2988: undefined reference to `__imp__ZN11rend3_types9attribute30VERTEX_ATTRIBUTE_JOINT_WEIGHTS17h05d76e67463d83e8E'
          /usr/bin/x86_64-w64-mingw32-ld: /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483\library\core\src\sync\atomic.rs:2988: undefined reference to `__imp__ZN11rend3_types9attribute30VERTEX_ATTRIBUTE_JOINT_INDICES17hfdcc5160c0b7af3aE'
          /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.rend3-453033c5e7b550be.rend3.e9d9b511-cgu.15.rcgu.o.rcgu.o: in function `rend3::managers::skeleton::SkeletonManager::add':
          /home/john/projects/rend3/rend3/src/managers/skeleton.rs:94: undefined reference to `__imp__ZN11rend3_types9attribute25VERTEX_ATTRIBUTE_POSITION17h5da116102e5decbcE'
          /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/rend3/src/managers/skeleton.rs:94: undefined reference to `__imp__ZN11rend3_types9attribute23VERTEX_ATTRIBUTE_NORMAL17h63229ce637477ce0E'
          /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/rend3/src/managers/skeleton.rs:94: undefined reference to `__imp__ZN11rend3_types9attribute24VERTEX_ATTRIBUTE_TANGENT17h2f5406bee084f752E'
          /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.rend3-453033c5e7b550be.rend3.e9d9b511-cgu.4.rcgu.o.rcgu.o: in function `once_cell::sync::OnceCell<T>::get':
          /home/john/.cargo/registry/src/github.com-1ecc6299db9ec823/once_cell-1.17.1/src/lib.rs:932: undefined reference to `__imp__ZN11rend3_types9attribute30VERTEX_ATTRIBUTE_JOINT_INDICES17hfdcc5160c0b7af3aE'
          /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/cube-8dc5475b2d78886d.rend3-453033c5e7b550be.rend3.e9d9b511-cgu.4.rcgu.o.rcgu.o: in function `core::sync::atomic::atomic_load':

where the symbols mentioned were found OK in a debug compile. At the end, we get

VERTEX_ATTRIBUTE_TEXTURE_COORDINATES_117h59a79f42f6985c39E'
          /usr/bin/x86_64-w64-mingw32-ld: /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483\library\core\src\sync\atomic.rs:2988: undefined reference to `__imp__ZN11rend3_types9attribute24VERTEX_ATTRIBUTE_COLOR_017h34b28a0425e36fbdE'
          /usr/bin/x86_64-w64-mingw32-ld: /home/john/projects/rend3/target/x86_64-pc-windows-gnu/release/deps/imgui-c8185a310b11f66b.rend3_routine-04e83d9954e6715a.rend3_routine.12c8a977-cgu.9.rcgu.o.rcgu.o: in function `core::sync::atomic::atomic_load':
          /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483\library\core\src\sync\atomic.rs:2988: undefined reference to `__imp__ZN11rend3_types9attribute25VERTEX_ATTRIBUTE_POSITION17h5da116102e5decbcE'
          /usr/bin/x86_64-w64-mingw32-ld: /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483\library\core\src\sync\atomic.rs:2988: undefined reference to `__imp__ZN11rend3_types9attribute25VERTEX_ATTRIBUTE_POSITION17h5da116102e5decbcE'
          collect2: error: ld returned 1 exit status

  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `rend3-imgui-example` due to previous error

Almost everything seems to involve core::sync::atomic_load. Which, on x86, is trivial, because x86 machines don't need a fence for that.

Possibly related: two bugs from last year involving atomic_load causing similar linker errors.

Close, but that wasn't it. It's Bug# 98302.

There's a workaround. In Cargo.toml, change, for cross-compiles,

lto = "thin"

to

lto = "fat"

"Fat" is right. I can't even compile on the 8GB machine any more. The linking step runs out of memory and aborts. I have to use the 32 GB machine. Link times are in the 1-2 minute range.

Yeah, full lto link times can be spectacularly unfunny. When I build python on an embedded system the lto takes more than 30 minutes.

I always disable lto entirely until I'm doing a release (candidate) build, and then I use full lto.

Thanks. OK, bug workaround time.

How do I express this in Cargo.toml language?

if profile = "release" {
    if target == "x86_64-pc-windows-gnu" { lto = "fat" } else { lto = "thin" }
    } else { lto = false }
}

I don't think you can (#4897), though @Yandros posted this workaround a while back.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.