Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust 1.61 in Linux does no add resources to the EXE #40

Open
rodrigorc opened this issue May 18, 2022 · 8 comments
Open

Rust 1.61 in Linux does no add resources to the EXE #40

rodrigorc opened this issue May 18, 2022 · 8 comments

Comments

@rodrigorc
Copy link

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.

@petrochenkov
Copy link

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.

@koriwi
Copy link

koriwi commented Jun 4, 2022

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

@getreu
Copy link

getreu commented Jul 22, 2022

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

@tay64
Copy link

tay64 commented Oct 12, 2022

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");

@BenjaminRi
Copy link

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.

@ghost
Copy link

ghost commented Oct 15, 2022

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" }

@BenjaminRi
Copy link

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
Copy link

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 pushed a commit to BenjaminRi/Sherlog that referenced this issue Nov 20, 2022
getreu pushed a commit to getreu/tp-note that referenced this issue Nov 20, 2022
See

* [Rust 1.61 in Linux does no add resources to the EXE · Issue #40 ·
  mxre/winres ·
  GitHub](mxre/winres#40 (comment))
* [winresource - crates.io: Rust Package Registry](https://crates.io/crates/winresource)
FabianLars added a commit to tauri-apps/winres that referenced this issue Jan 5, 2023
Fix mxre#40 by using different linking flags depending on rustc version
fenhl added a commit to midoshouse/ootr-multiworld that referenced this issue Oct 8, 2024
* winres is unmaintained, switch to winresource mxre/winres#40 (comment)
* Double colon syntax for build script outputs is preferred https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants