winres icon indicating copy to clipboard operation
winres copied to clipboard

Rust 1.61 in Linux does no add resources to the EXE

Open rodrigorc opened this issue 2 years ago • 8 comments

Since Rust 1.61 1, the linker no longer includes the static libraries with the --whole-archive flag. This means that the resource.o file is only added to the final EXE if it defines any symbol undefined elsewhere. But resource objects do not define any symbol at all!

There are several solutions for this that I can think of:

Solution n.1: The fancy one.

-        println!("cargo:rustc-link-lib=static=resource");
+        println!("cargo:rustc-link-lib=static:+whole-archive=resource");

This forces the --whole-archive flag for this particular library, restoring the old behavior. The drawback is that I think it will not be backwards compatible, it will require Rust 1.61.

Solution n.2: The classic.

-        println!("cargo:rustc-link-lib=static=resource");
+        println!("cargo:rustc-link-args={}", output.display()); // .../resource.o

By passing the name of the object file instead of the library it will link the given object into the EXE, unconditionally. The nice thing is that it is backwards compatible. And the call to AR is not longer needed.

Solution #3: The hack.

-        let output = PathBuf::from(output_dir).join("resource.o");
+        let output = PathBuf::from(output_dir).join("libresource.a");

And then removing the call to AR. Then when linking the static library resource the linker will find the libresource.a, that is not an archive but an object, thus it is included unconditionally. It is similar to n.2 but it still uses the static flag.

rodrigorc avatar May 18 '22 18:05 rodrigorc

The drawback is that I think it will not be backwards compatible, it will require Rust 1.61.

You can use https://crates.io/crates/version_check to do it conditionally. That's better than hacks, at least.

petrochenkov avatar May 20 '22 09:05 petrochenkov

i just downgraded to 1.60 because i wasted 2.5 days with this cross compilation problem

koriwi avatar Jun 04 '22 20:06 koriwi

I probably run into the same problem with my tp-note/build.rs. Could you please publish a (minor) version upgrade?

getreu avatar Jul 22 '22 01:07 getreu

This also affects Windows/MINGW. (This issue's title happens to be too narrow, I almost not looked here before submitting a duplicate :) )

[EDIT: deleted some premature conclusions. My attempts to use @rodrigorc's solution 1 as a user-side workaround failed because they conflicted with cargo directives emitted by the unmodified winres.]

Can confirm that PR #41 (which implements solution 1 on my rust version) fixes the issue for me.

Leaving my ugly user-side workaround here just in case it might work as a stop-gap for someone who cannot use the PR branch:

	println!("cargo:rustc-link-arg=-Wl,--whole-archive");
	println!("cargo:rustc-link-arg=-Wl,-Bstatic");
	println!("cargo:rustc-link-arg=-lresource");
	println!("cargo:rustc-link-arg=-Wl,--no-whole-archive");

tay64 avatar Oct 12 '22 22:10 tay64

This bug breaks this crate completely for up to date Rust toolchains.

@mxre would it be possible to accept PR #41 and publish the fix on crates.io? The crate silently stops working whenever someone updates their toolchain to Rust 1.61 or higher, leading to unexpected outcomes and troubleshooting for every person who uses it.

BenjaminRi avatar Oct 13 '22 15:10 BenjaminRi

A temporary solution until the crate gets fixed would be to add @Nilstrieb's repo to Cargo.toml instead:

winres = { git = "https://github.com/Nilstrieb/winres", branch = "linking-flags" }

yakovlevegor avatar Oct 15 '22 23:10 yakovlevegor

A temporary solution until the crate gets fixed would be to add @Nilstrieb's repo to Cargo.toml instead:

winres = { git = "https://github.com/Nilstrieb/winres", branch = "linking-flags" }

I know. But then you cannot publish it on crates.io. Ultimately, if this bug is not fixed, a fork is required.

BenjaminRi avatar Oct 16 '22 12:10 BenjaminRi

In early November 2022, I wrote an email to @mxre with the question whether he could accept PR #41 or give a short feedback on how to proceed. I did not receive an answer.

Hence, with utmost respect for the original work, I forked the repository and created a new crate that is maintained again.

https://github.com/BenjaminRi/winresource https://crates.io/crates/winresource

Everything is identical, except that this bug is fixed and the name is winresource. I will also continue to maintain the crate to the best of my ability and available time. Whether you switch to the new crate or use a workaround for the time being is up to you, of course.

BenjaminRi avatar Nov 20 '22 14:11 BenjaminRi