mxre / winres Goto Github PK
View Code? Open in Web Editor NEWCreate and set windows icons and metadata for executables with a rust build script
License: MIT License
Create and set windows icons and metadata for executables with a rust build script
License: MIT License
With a standard manifest entry such as the Common Controls dependency, I spread it over many lines as it is easier to read:
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
However, due to the handling of the XML manifest:
for line in manf.lines() {
writeln!(f, "\"{}\"", escape_string(line.trim()))?;
}
The whitespace is trimmed and the resulting XML snippet has no whitespace:
<assemblyIdentitytype="win32"name="Microsoft.Windows.Common-Controls"version="6.0.0.0"processorArchitecture="*"publicKeyToken="6595b64144ccf1df"language="*"/>
Understandably, this breaks the build with the error: The application has failed to start because its side-by-side configuration is incorrect.
Ideally, whitespace should be preserved, though I'm not sure if this will break something else which is why this is a bug instead of a PR.
I just tried to run the tests and they don't work on my machine. Do they work on yours?
I have a hypothesis of why they don't work. I ran into this issue here: tauri-apps/tauri#2871 (comment) TLDR; registry access to blocked on my machine, winres cannot find my win sdk so defaults to an incorrect one.
I recognize that this is probably a one off error due to my computers strange configuration. However, I think we can make the issue more clear for new users by making the error message for these failing tests better. Here is what the tests look like on my machine:
> cargo test
Finished test [unoptimized + debuginfo] target(s) in 0.23s
Running unittests (target\debug\deps\winres-d3c7430050472df1.exe)
running 3 tests
test tests::toolkit_include_win10 ... ok
test tests::toolkit_include_win8 ... ok
test tests::string_escaping ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests winres
running 6 tests
test lib.rs - WindowsResource::set_icon_with_id (line 357) ... ignored
test lib.rs - WindowsResource::set_icon_with_id (line 363) ... ignored
test lib.rs - WindowsResource::append_rc_content (line 540) ... FAILED
test lib.rs - WindowsResource::set_manifest (line 411) ... ok
test lib.rs - (line 12) ... ok
test lib.rs - WindowsResource::set_language (line 284) ... FAILED
failures:
---- lib.rs - WindowsResource::append_rc_content (line 540) stdout ----
Test executable failed (exit code 101).
stdout:
package.metadata does not exist
stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: NotPresent', lib.rs:638:64
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- lib.rs - WindowsResource::set_language (line 284) stdout ----
Test executable failed (exit code 101).
stdout:
package.metadata does not exist
stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: NotPresent', lib.rs:638:64
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
lib.rs - WindowsResource::append_rc_content (line 540)
lib.rs - WindowsResource::set_language (line 284)
test result: FAILED. 2 passed; 2 failed; 2 ignored; 0 measured; 0 filtered out; finished in 12.50s
error: test failed, to rerun pass '--doc'
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots]
"KitsRoot10"="C:\\Program Files\\Windows Kits\\10\\"
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots]
"KitsRoot10"="C:\\Program Files (x86)\\Windows Kits\\10\\"
When building for 64-bit, winres
ends up looking at the regular registry node instead of the WOW6432Node
version and so ends up getting the Program Files
version instead of the Program Files (x86)
version, and therefore fails to locate rc.exe
. It might be a good idea to pass /reg:32
when calling reg
.
The new
method on WindowsResource
sets the FileDescription
field to package.description
Cargo field by default. While this would be true to the name of that field itself, it's not what actual Windows programs do. That field is typically the same as ProductName
for the main executable of the product, or something similar to it which includes ProductName
. The package.description
manifest field, on the other hand, describes the package without including its name, because it's displayed by Crates.io right below that name.
During actual usage of the program, with the current defaults for this crate (unless they are specifically overridden using package.metadata.winres
by the downstream crate), the Crates.io description will display in Task Manager where most other programs have the name of the executable (as in "Steam Client WebHelper" or "Radeon Settings: Host Service", or "COM Surrogate"). This can be extremely confusing for users who wish to forcibly close the program or modify its priority.
My preferred solution would be to use package.name
, i.e. the same value as ProductName
, by default, unless overridden using package.metadata.winres
to a more specific description for the file, such as "MyAwesomeProgram Update Helper", by the downstream crate.
When I put
[package.metadata.winres]
FileDescription = "A simple \"Hello, World!\" program."
in the Cargo.toml, it gave this error:
D:\projects\icon-test\target\release\build\icon-test-7fe8c39ee383430f\out\resource.rc(16) : error RC2104 : undefined keyword or key name: Hello
------
RC Error:
------
--- stderr
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: StringError("Could not compile resource file") }', libcore\result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Double quotes shouldn't break anything.
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.
As stated in the title of this issue, winres
fails to change the resource data of executables generated by Cargo when compiling a package that has both a library and binary crate (i.e. both a src/main.rs
and src/lib.rs
). No error happens whatsoever, and both the resource file and Cargo instructions output in the build script are correct, which makes this a pretty sneaky issue.
I've managed to trace the cause down to how Cargo works. Citing the documentation (emphasis mine):
The -l flag is only passed to the library target of the package, unless there is no library target, in which case it is passed to all targets. This is done because all other targets have an implicit dependency on the library target, and the given library to link should only be included once. This means that if a package has both a library and a binary target, the library has access to the symbols from the given lib, and the binary should access them through the library target's public API.
Because winres
instructs the linker to link to the resource file via cargo:rustc-link-lib
, the binary crate that generates the actual program is not linked against the resource file, and that essentially means that winres
ends up doing nothing visible. I've confirmed that this happens when using the GNU toolchain, although for MSVC this is also done as well, so I'd expect MSVC builds to be affected too.
One obvious workaround would be getting rid of the library crate, but this is not necessarily a good practice (separating the application code from the API it uses is usually nice). Another workaround is to set up a workspace and separate the library and binary crates into different packages, but this seems like overkill to just get some metadata linked to a binary crate.
Can winres
reliably link the resource file with the binary somehow, even if it shares package with a library crate? If not, can I workaround it in a better way than using workspaces? Thanks!
I honestly wouldn't be surprised if windows explorer was caching the icon. Even a cargo clean
before rebuilding gives me the old icon. Anything funky with GUIDs that could cause it? I don't know anything about resources.
FileVersion is not listed in the supported variables of this crate, but my exe still has a FileVersion (0.1.0.0). Is it set by cargo based on the version set it Cargo.toml? Or also set by this crate?
Shouldn't the ProductVersion always be the same as FileVersion when publishing the exe?
How can I keep the ProductVersion (and FileVersion) automatically the same as the version set in Cargo.toml? :)
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadicona
When using the LoadIcon API, IDI_APPLICATION looks for id 32512: MAKEINTRESOURCE(32512)
Hi, I am trying to use GNU compiler on windows and utilities from Msys.
But I'm having this error when I'm trying to build:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', C:\bot\slave\stable-dist-rustc-win-gnu-64\build\src\libcore\option.rs:323
Why is it printing the path I haven't in the first place? I don't have C:\bot\slave\...
:(
Is there a way to put resources into other binaries except main.rs?
stuff in src/bin, [[bin]] on Cargo.toml ...
It would be desirable to be able to handle these separately..
On my win11 system, running cargo install juliaup --verbose
for stable-x86_64-pc-windows-gnu (default) fails with the following:
Running 'rustc --crate-name human_panic --edition=2021 C:\Users\Rob\.cargo\registry\src\index.crates.io-6f17d22bba15001f\human-panic-1.2.3\src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=172 --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C linker-plugin-lto -C codegen-units=1 --cfg "feature=\"color\"" --cfg "feature=\"default\"" -C metadata=8a1a8d70e1b56d2e -C extra-filename=-8a1a8d70e1b56d2e --out-dir C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps -C strip=debuginfo -L dependency=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps --extern anstream=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libanstream-66b7a2fe48a1d3b6.rmeta --extern anstyle=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libanstyle-4e7fc4a51adeb06d.rmeta --extern backtrace=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libbacktrace-164cb7e122807f72.rmeta --extern os_info=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libos_info-49329536c48b8a08.rmeta --extern serde=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libserde-64f01729d1e13c0d.rmeta --extern serde_derive=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\serde_derive-2c8f67e335b69f1a.dll --extern toml=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libtoml-8f1f71222cc8eb46.rmeta --extern uuid=C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\deps\libuuid-6625922bf2bae00c.rmeta --cap-lints allow -L native=C:\Users\Rob\.cargo\registry\src\index.crates.io-6f17d22bba15001f\windows_x86_64_gnu-0.52.5\lib'
error: failed to run custom build command for 'juliaup v1.14.7'
Caused by:
process didn't exit successfully: 'C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV\release\build\juliaup-a849c2712ac6e5d7\build-script-build' (exit code: 101)
--- stderr
cc1: fatal error: C:UsersRobAppDataLocalTempcargo-installHfI1HVreleasebuildjuliaup-b64f51bcb697a75boutresource.rc: No such file or directory
compilation terminated.
windres: preprocessing failed.
thread 'main' panicked at C:\Users\Rob\.cargo\registry\src\index.crates.io-6f17d22bba15001f\juliaup-1.14.7\build.rs:48:23:
called 'Result::unwrap()' on an 'Err' value: Custom { kind: Other, error: "Could not compile resource file" }
note: run with 'RUST_BACKTRACE=1' environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: failed to compile 'juliaup v1.14.7', intermediate artifacts can be found at 'C:\Users\Rob\AppData\Local\Temp\cargo-installHfI1HV'.
To reuse those artifacts with a future compilation, set the environment variable 'CARGO_TARGET_DIR' to that path.
Notice the cc1
fatal error calls out an invalid path with backslashes removed.
I realize this probably is not appropriate for all systems, but I sidestepped this by adding the following to lib.rs:
fn fix_path_for_msys(&self, input_path: PathBuf) -> String {
let path_argument = format!("{0}", input_path.display());
let cygpath_result = process::Command::new("cygpath").arg(path_argument).output();
let cygpath_checked_result = match cygpath_result {
Ok(result) => result,
Err(error) => panic!("Problem calling cygpath: {:?}", error),
};
let result_str = String::from_utf8_lossy(&cygpath_checked_result.stdout);
return format!("{}", result_str);
}
Then I updated the paths in compile_with_toolkit_gnu
:
let input_path = &self.fix_path_for_msys(input);
let output_path = &self.fix_path_for_msys(output).clone(); // Needed for both windres and ar, avoid borrow errors
let status = process::Command::new(&self.windres_path)
// ... set current_dir, pass args, call status, check status
let libname_path = &self.fix_path_for_msys(libname);
let status = process::Command::new(&self.ar_path)
// ... set current_dir, pass args, call status, check status
Replacing the use of input.display()
, output.display()
, and libname.display()
with these paths for the process args — on what is currently at line(s) 587, 588, 601, and 602 — fixes the issue for me.
Initially I suspected Git-bash for Windows, but found it still occurs when running cargo install from cmd
.
Any thoughts on why this is happening?
Can compile_with_toolkit_gnu
conditionally handle this scenario and fix the paths as needed?
Scenario: under linux ubuntu,
rustup target add x86_64-pc-windows-gnu
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
cargo build --target=x86_64-pc-windows-gnu
the build fail with the error--- stderr
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
This non versatile error mean you tried to invoke windres.exe but under linux this executable is named x86_64-w64-mingw32-windres
you should add an option to specify the executable name
Instead of having to hand code a Windows application manifest and embed it into the build.rs
script as a string or as a file, it would be nice to have a utility to generate such a manifest by code. e.g.
shadow.set_manifest(WindowsManifest::new()
.set_...()
.set_...()
.build())
See https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
Hi!
I added this crate as dependency to add an icon to my project and expected this to have zero effect on the final binary size. To my surprise was the binary size increased. Is this expected or not?
This is how my toml looks like...
[package]
#...
build = "build.rs"
#...
[target.'cfg(windows)'.build-dependencies]
winres = "0.1.11"
Hi, what's the current state of cross compilation from Windows? The README says:
Note that using this crate on non windows platform is undefined behavior. It does not contain safeguards against doing so.
What actions would be necessary to get this to work on Linux? If this is not easily possible, can at least some safeguards please be added?
TL;DR: Might be worth inserting \0
after the escaped v
on line 400 here:
Lines 396 to 404 in 82f55f8
MSDN Examples for VERSIONINFO resources appear to explicitly null terminate file/product version strings (VER_FILEVERSION_STR
/ VER_PRODUCTVERSION_STR
). The docs aren't super clear on if this is actually necessary though. Other documentation is muddled: STRINGTABLE resources appear to be implicitly null terminated... but User-Defined Resources explicitly aren't: "RC does not automatically append a terminating null character to a string." I'd mostly worry about mixed Rust/C(++) codebases possibly reading back the version strings. E.g. LoadStringA(hinstance, id, &ptr, 0) will give you C-string pointer - not sure if you can get C-string pointers directly from Win32 for the version strings?
The path of SDK has changed in VS2017, rc.exe
is no longer in C:\Program Files (x86)\Windows Kits\10\bin\x86
. It's in C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x86
now.(depends on the SDK version).
I did a monkey patch to solve this issue, (see master...bennyyip:master), but the way how SDK is detected should be updated.
Why no \
--- stderr
gcc: error:C:ProjGameProjHeatEndtargetdebugbuildheatend-10131cee3e57bea3outresource.rc:No such file or directory
I check the file actually it exists
I'm cross compiling from linux to windows, but I found it not work.
I checked the history issue and found that the problem is still unresolved.
However, in the course of my continuous testing, I found that the cfg
conditional judgment in the build script does not work.
// build.rs
#[cfg(target_os="windows")]
fn main() {
panic!("target_os = windows")
}
#[cfg(windows)]
fn main() {
panic!("windows")
}
#[cfg(unix)]
fn main() {
panic!("unix")
}
$ uname -a
Linux alex 5.13.19-2-MANJARO #1 SMP PREEMPT Sun Sep 19 21:31:53 UTC 2021 x86_64 GNU/Linux
$ cargo build
Compiling target v0.1.0 (/data/projects/target)
error: failed to run custom build command for `target v0.1.0 (/data/projects/target)`
Caused by:
process didn't exit successfully: `/data/projects/target/target/debug/build/target-fff5ba352ad7afdb/build-script-build` (exit status: 101)
--- stderr
thread 'main' panicked at 'unix', build.rs:13:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
That's fine, however when cross compile...
$ cargo build --target x86_64-pc-windows-gnu
Compiling target v0.1.0 (/data/projects/target)
error: failed to run custom build command for `target v0.1.0 (/data/projects/target)`
Caused by:
process didn't exit successfully: `/data/projects/target/target/debug/build/target-fff5ba352ad7afdb/build-script-build` (exit status: 101)
--- stderr
thread 'main' panicked at 'unix', build.rs:13:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I expect it to output window
or target_os = windows
, but it panic at unix
I think it may be because some features were not determined when build.rs
was compiled and the features not been passed to rustc.
I have found some environment variables from the documentation and they can be used to determine target and host.
use std::env;
fn main() {
if env::var("PROFILE").unwrap() == "release" {
if let Ok(_) = env::var("CARGO_CFG_WINDOWS") {
let mut res = winres::WindowsResource::new();
if let Ok(host) = env::var("HOST") {
if host.contains("linux") {
res.set_toolkit_path("/usr/bin")
.set_windres_path("x86_64-w64-mingw32-windres");
}
}
res.set_icon("res/copy-translator.ico").set_language(0x04);
res.compile().unwrap();
}
}
}
Icons are still not set successfully when cross compile fron linux to windows
@mxre I am having trouble implementing this for use with Servo's Windows version. Could you provide a demo version of your code in action?
Hi,, I am trying to build an application from (Arch) Linux to Windows.
I use this command cargo build --release --target x86_64-pc-windows-gnu
and it works just fine. I can execute my program just fine.
Now I want to include an icon to my executable.
I followed this post (as shown in the screenshot)
https://stackoverflow.com/questions/30291757/attaching-an-icon-resource-to-a-rust-application
And this works fine if I am compiling on Windows. However on Linux when building for Windows, it fails to add an icon. I have made the following modification:
build.rs
use std::io;
use winres::WindowsResource;
fn main() -> io::Result<()> {
WindowsResource::new()
// This path can be absolute, or relative to your crate root.
.set_toolkit_path("/usr/bin")
.set_windres_path("x86_64-w64-mingw32-windres")
.set_icon("./assets/icon.ico")
.compile()?;
Ok(())
}
Cargo.toml
[package]
name = "testing"
version = "0.1.0"
edition = "2018"
[build-dependencies]
winres = "0.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
However, with the following modification I get this error message:
Compiling testing v0.1.0 (/home/test/Desktop/programming/testing)
error: failed to run custom build command for `testing v0.1.0 (/home/test/Desktop/programming/testing)`
Caused by:
process didn't exit successfully: `/home/test/Desktop/programming/testing/target/release/build/testing-eda5b7592106f7de/build-script-build` (exit status: 1)
--- stdout
package.metadata does not exist
--- stderr
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
Does anyone know why this is happening?
I am building a single bin Rust application with a single ico file used as its icon. I am using the MingW toolchain from Msys2. I used the following build.rs
script to compile.
#[cfg(windows)]
extern crate winres;
#[cfg(windows)]
fn main() {
use std::process::exit;
let mut resource: winres::WindowsResource = winres::WindowsResource::new();
resource.set_icon("./assets/icon.ico");
resource.set_manifest_file("./manifest.xml");
if let Err(e) = resource.compile() {
eprintln!("{}", e);
exit(1);
}
println!("cargo:rustc-link-search=./");
println!("cargo:rustc-link-arg=./resource.rc");
}
#[cfg(unix)]
fn main() {
}
Here is my manifest.xml
file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<windowsSettings>
<startMenu>
<shortcut>
<iconResource path="./icon.ico" index="0" />
</shortcut>
</startMenu>
</windowsSettings>
</application>
</compatibility>
</assembly>
When I compile with the verbose flag, I get the following error:
error: linking with `x86_64-w64-mingw32-gcc` failed: exit code: 1
|
= note: "x86_64-w64-mingw32-gcc" "-fno-use-linker-plugin" "-Wl,--dynamicbase" "-Wl,--disable-auto-image-base" "-m64" "-Wl,--high-entropy-va" "C:\\Users\\samj\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\rsbegin.o" "C:\\Users\\samj\\AppData\\Local\\Temp\\rustcRrQ3C6\\symbols.o" "E:\\GitHub\\reapmo\\target\\release\\deps\\reapmo-4df19b3370c7f44b.reapmo.350bddc7-cgu.0.rcgu.o" "-L" "E:\\GitHub\\reapmo\\target\\release\\deps" "-L" "E:\\GitHub\\reapmo\\target\\release\\build\\reapmo-ed22b6e6b438d4f4\\out" "-L" "./" "-L" "E:\\GitHub\\reapmo\\target\\release\\build\\libgit2-sys-b41b64cbcd060796\\out\\build" "-L" "E:\\GitHub\\reapmo\\target\\release\\build\\libssh2-sys-908da47e12aac88e\\out\\build" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:\\Users\\samj\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\winapi-x86_64-pc-windows-gnu-0.4.0\\lib" "-L" "C:\\Users\\samj\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\windows_x86_64_gnu-0.42.2\\lib" "-L" "E:\\GitHub\\reapmo\\target\\release\\build\\ring-ab0d9158d6d12028\\out" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:/msys64/mingw64/bin/../lib" "-L" "C:\\Users\\samj\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib" "-Wl,-Bstatic" "-lresource" "C:\\Users\\samj\\AppData\\Local\\Temp\\rustcRrQ3C6\\liblibgit2_sys-ecb01175c63a069e.rlib" "C:\\Users\\samj\\AppData\\Local\\Temp\\rustcRrQ3C6\\liblibssh2_sys-867ba9c714c8239b.rlib" "C:\\Users\\samj\\AppData\\Local\\Temp\\rustcRrQ3C6\\libring-12aa43ceea9e8d77.rlib" "C:\\Users\\samj\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libcompiler_builtins-d765c9bc514400ee.rlib" "-Wl,-Bdynamic" "-lwinhttp" "-lrpcrt4" "-lole32" "-lcrypt32" "-lbcrypt" "-lcrypt32" "-luser32" "-lntdll" "-lz" "-lntdll" "-lwindows" "-lgobject-2.0" "-lgtk-3" "-lgdk-3" "-lz" "-lgdi32" "-limm32" "-lshell32" "-lole32" "-lwinmm" "-ldwmapi" "-lsetupapi" "-lcfgmgr32" "-lhid" "-lwinspool" "-lcomctl32" "-lcomdlg32" "-lpangowin32-1.0" "-lpangocairo-1.0" "-lpango-1.0" "-lharfbuzz" "-latk-1.0" "-lcairo-gobject" "-lcairo" "-lgdk_pixbuf-2.0" "-lgio-2.0" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-latk-1.0" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lgdk-3" "-lz" "-lgdi32" "-limm32" "-lshell32" "-lole32" "-lwinmm" "-ldwmapi" "-lsetupapi" "-lcfgmgr32" "-lhid" "-lwinspool" "-lcomctl32" "-lcomdlg32" "-lpangowin32-1.0" "-lpangocairo-1.0" "-lpango-1.0" "-lharfbuzz" "-lgdk_pixbuf-2.0" "-lcairo-gobject" "-lcairo"
"-lgobject-2.0" "-lglib-2.0" "-lintl" "-lpango-1.0" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lharfbuzz" "-lgdk_pixbuf-2.0" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lgio-2.0" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lwinapi_advapi32" "-lwinapi_cfgmgr32" "-lwinapi_credui" "-lwinapi_fwpuclnt" "-lwinapi_gdi32" "-lwinapi_kernel32" "-lwinapi_msimg32" "-lwinapi_ntdll" "-lwinapi_opengl32" "-lwinapi_secur32" "-lwinapi_user32" "-lwinapi_winspool"
"-lwinapi_ws2_32" "-lcairo-gobject" "-lcairo" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lgobject-2.0" "-lglib-2.0" "-lintl" "-lkernel32" "-ladvapi32" "-luserenv" "-lkernel32" "-lws2_32" "-lbcrypt" "-lgcc_eh" "-l:libpthread.a" "-lmsvcrt" "-lmingwex" "-lmingw32" "-lgcc" "-lmsvcrt" "-luser32" "-lkernel32" "-Wl,--nxcompat" "-L" "C:\\Users\\samj\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib" "-o" "E:\\GitHub\\reapmo\\target\\release\\deps\\reapmo-4df19b3370c7f44b.exe" "-Wl,--gc-sections" "-no-pie" "-Wl,--strip-all" "-nodefaultlibs" "./resource.rc" "C:\\Users\\samj\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\rsend.o"
= note: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe:./resource.rc: file format not recognized; treating as linker script
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe:./resource.rc:2: syntax error
collect2.exe: error: ld returned 1 exit status
./resource.rc: file format not recognized; treating as linker script
./resource.rc:2: syntax error
If I omit line 15 (println statement), Rust compilation will complete but without the icon file attached to the binary.
How can I fix this problem?
This came up in the context of Servo:
servo/servo#11969 (comment)
Basically, the issue is that the MSVC codepath uses res
to create a .res file, but just renames it to .lib:
https://github.com/mxre/winres/blob/master/lib.rs#L466
Instead, it could either:
Do you have a preference, @mxre?
CC @Coder206
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.