slint icon indicating copy to clipboard operation
slint copied to clipboard

slint-macros fails to build on Windows under MINGW64 (x86_64-pc-windows-gnu): `export ordinal too large`

Open tay64 opened this issue 2 years ago • 7 comments

Linker error: export ordinal too large while building sixtyfps-macros.

See sixtyfps-macros-ld-error.txt for the full error message.

The ordinal value it complains about is ~82000 (differs depending on circumstances).

rustc --version: rustc 1.59.0-nightly (e100ec5bc 2021-12-21) gcc for linking: from the rust toolchain as set up by rustup: /home/user/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/bin/self-contained/x86_64-w64-mingw32-gcc --version: x86_64-w64-mingw32-gcc.exe (x86_64-posix-seh-rev2, Built by MinGW-W64 project) 6.3.0

Work-around:

Cross-compile in Linux.

How to reproduce:

  • follow the sixtyfps tutorial
  • be sure to specify the version sixtyfps = "0.1.5" when creating Cargo.toml
  • the build will fail right at the Getting Started step, no need to proceed further into the tutorial

Additional datapoints:

  • reproduced with x86_64-pc-windows-gnu toolchain versions 1.54, stable-1.57 and nightly-1.59
  • reproduced with system GCC as linker, as opposed to the toolchain's self-contained gcc (RUSTFLAGS="-C linker=gcc" cargo build); gcc version x86_64-w64-mingw32-gcc.exe (Rev2, Built by MSYS2 project) 11.2.0
  • reproduces both in debug and release builds
  • cross-compilation with cargo build --target x86_64-pc-windows-gnu under Ubuntu with mingw-w64 succeeds
  • sixtyfps-rs 0.1.4 builds successfully

(Speculation: could be related to rust #37530? That's solved for cdylibs but sixtyfps-macros is a dylib).

[Added] When cross-compiling under Linux, all the procedural macro libraries are built in the native ELF format (f.e. target/debug/deps/libsixtyfps_macros-6b856b93326235ff.so, even though the libsixtyfps library itself is at target/x86_64-pc-windows-gnu/debug/deps/libsixtyfps-95f79d3acfc3ff62.rlib), because they have to load into rustc. Whereas when compiling on Windows, rustc is a PE/COFF and the procedural macro libraries are by necessity compiled into PE/COFF DLLs. This brings into action the limit of 65535 export ordinals in PE/COFF, which is just not an issue when compiling under Linux.

Number of exports, Linux: 70056 (cargo sym -e target/debug/deps/libsixtyfps_macros-6b856b93326235ff.so | wc -l) Number of exports, Windows: 81654 (counting entries in the implib, D:\0\sixtyhello\target\debug\deps\libsixtyfps_macros-abae7269cd02c186.dll.a, which gets generated even though the linking fails)

So it looks to me like the excess of exported symbols is the problem, but I have no idea what to do about it.

tay64 avatar Dec 22 '21 17:12 tay64

i'm not quite sure how we can solve this problem. Would trying to reduce the amount of dependency helps?

ogoffart avatar Dec 23 '21 08:12 ogoffart

I'm not sure either -- I know too little about Rust and about SixtyFPS. My idea for my further research is to look into the content of sixtyfps_macros and attempt splitting it into separate crates, if it's possible.

This looks like a general problem, not specific to SixtyFPS, so I created an issue in rust-lang (#92212).

Fortunately cross-compiling in Linux seems to work as a work-around so it's not a critical problem with Windows desktop target support for SixtyFPS (I'll add a note about it to the issue).

tay64 avatar Dec 23 '21 09:12 tay64

Another workaround is to use the msvc toolchain.

thepperson avatar Feb 01 '22 13:02 thepperson

I met this problem too. I'm using msys2+ming64, GNU toolchain on windows 10. Waiting for solution...

lotusstudio avatar Feb 04 '22 03:02 lotusstudio

I reinstalled Rust with MSVC toolchain. Another error occurs: PS D:\coding\Rust\sixtyfps-test1> cargo build Compiling sixtyfps-test1 v0.1.0 (D:\coding\Rust\sixtyfps-test1) error: proc macro panicked --> src\main.rs:5:1 | 5 | / sixtyfps::sixtyfps! { 6 | | MemoryTile := Rectangle { 7 | | width: 64px; 8 | | height: 64px; ... | 20 | | } 21 | | } | |_^ | = help: message: called Option::unwrap() on a None value

error[E0433]: failed to resolve: use of undeclared type MainWindow --> src\main.rs:2:5 | 2 | MainWindow::new().run(); | ^^^^^^^^^^ use of undeclared type MainWindow

For more information about this error, try rustc --explain E0433. error: could not compile sixtyfps-test1 due to 2 previous errors

lotusstudio avatar Feb 04 '22 08:02 lotusstudio

@lotusstudio That problem seem unrelated. Can you open a new issue for that. The issue should contain the code sample to reproduce this problem, and, if possible, the backtrace of the panic. (using -Z proc-macro-backtrace)

ogoffart avatar Feb 04 '22 09:02 ogoffart

A new workaround has surfaced: Add this to your Cargo.toml to compile the macro crate in release and thus reduce the amount of symbols that require an ordinal each:

[profile.dev.build-override]
opt-level = 2

tronical avatar Apr 10 '22 08:04 tronical

This is a problem in rust: https://github.com/rust-lang/rust/issues/92212

ogoffart avatar Jan 19 '24 11:01 ogoffart