Hey guys I was wondering when you produce your executable, is there a way to put like an image or something on your executable file? Is there some cargo package or something?
You can include_bytes!()
files to embed them as a byte array in the same way how string literals are stored.
I have used it to copy files over but I am not too sure how do I like get it to embed an image on my executable rather than coming up as blank?
Are you talking about the file icon in Windows explorer? In that case, maybe winapi and this can help.
yeah so you know how if I type cargo build
and it generates an executable? So if you happen to know how I can change the icon of the executable that will be great. I will check out your links, thanks
Rust does not support this out of the box therefore you have to do it manually.
So create a folder in your project called "resources". In it, put the .ico
file that will be your application's icon. In the following steps I'm assuming you're using the MSVC toolchain.
Create a .rc files
So the easiest way to use this icon is to compile it in a way the msvc linker understands. To do this you'll need to create a resources.rc
file in the same folder as your icon. The resource.rc
file should contain this line:
APPICON ICON icon.ico
Change icon.ico
to the name of your .ico
file.
Compile the resource
The next step is to compile the .rc
file, which requires MSVC tools (you may need to open a "native tools command line" to find them).
Enter this command while in your project's directory:
rc /nologo /fo resources\res.lib resources\resources.rc
This will create a res.lib
file that can be passed to the linker.
build.rs
The final step is to tell Rust to link the icon. For this you will need a build script. Create a build.rs
in the root of your project and add this to it:
fn main() {
println!("cargo:rustc-link-lib=./resources/res");
}
Note that this is a bit of a hack. The compiled resource isn't really a lib
file but we pretend it is so we can persuade Rust to pass it to the linker.
Hey mate sorry but I keep getting this error:
fatal error RC1109: error creating resources\res.lib
I am probably just using cmd
that is why.
Where can I find this mate?
Where can I find this mate?
Search the start menu, it should be there. Although if the rc
command is found then you probably don't need to.
fatal error RC1109: error creating resources\res.lib
Hm, that likely means it couldn't write the file. In case it helps, here's a log of my cmd line sessions of a hello
project I used to test this.
Z:\test\hello>dir
Volume in drive Z is RAMDisk
Volume Serial Number is F8C4-CDD2
Directory of Z:\test\hello
31/07/2021 13:49 <DIR> .
31/07/2021 13:49 <DIR> ..
31/07/2021 13:23 8 .gitignore
31/07/2021 13:49 67 build.rs
31/07/2021 13:49 149 Cargo.lock
31/07/2021 13:23 174 Cargo.toml
01/08/2021 12:59 <DIR> resources
31/07/2021 13:23 <DIR> src
4 File(s) 398 bytes
4 Dir(s) 4,102,807,552 bytes free
Z:\test\hello>dir resources
Volume in drive Z is RAMDisk
Volume Serial Number is F8C4-CDD2
Directory of Z:\test\hello\resources
01/08/2021 12:59 <DIR> .
01/08/2021 12:59 <DIR> ..
19/05/2019 13:15 23,229 icon.ico
31/07/2021 13:25 70 resources.rc
2 File(s) 23,299 bytes
2 Dir(s) 4,102,807,552 bytes free
Z:\test\hello>rc /nologo /fo resources\res.lib resources\resources.rc
Z:\test\hello>dir resources
Volume in drive Z is RAMDisk
Volume Serial Number is F8C4-CDD2
Directory of Z:\test\hello\resources
01/08/2021 13:00 <DIR> .
01/08/2021 13:00 <DIR> ..
19/05/2019 13:15 23,229 icon.ico
01/08/2021 13:00 23,428 res.lib
31/07/2021 13:25 70 resources.rc
3 File(s) 46,727 bytes
2 Dir(s) 4,102,782,976 bytes free
Z:\test\hello>
Yeah I find where rc.exe
is located.
Interesting it works when I created a "resources" folder, before I didn't do this and I ran this in the root of my project. I am not too sure why I have to create a "resources" folder? (I obviously removed "resources" from the argument i.e. rc /nologo /fo resources\res.lib resources.rc
In the root of my project directory, should i just run cargo run
after creating that file?
Edit, that works actually, thanks =D
Oh yeah, if you don't use the "resources" folder then the command is just:
rc /nologo /fo res.lib resources.rc
You would also need to update build.rs
with the location of res
which would be:
println!("cargo:rustc-link-lib=./res");
oh right lol
yeah true mate, anyways thanks mate
There's also a crate to do this: https://crates.io/crates/embed_resource
Would it work on Linux as well
There's a few questions here, not sure which you mean:
- Does embed-resource work on linux cross-compiling to windows... I don't think so. You need the rc tool, I don't think you can get that separately in something that runs on linux.
- Can you embed icons in linux executables? ...possibly, but that's done in a completely different way than for windows. Generally on Linux you'd have a separate icon file and use a .desktop file to provide application launcher support. And embed-resource won't do that.
- If you integrate embed-resource, will it fail on Linux? No. Internally embed-resource just doesn't do anything on Linux.
Google finds a lot of language agnostic solutions hinting to a freeware tool named Ressource Hacker at Resource Hacker
Apparantly it has a GUI for that job as well as a CLI syntax.
I have not used it myself and so can't really judge.
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.