Is there a way to put an image on your executable?

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.

4 Likes

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.

17 Likes

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>
1 Like

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

1 Like

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

2 Likes

oh right lol

yeah true mate, anyways thanks mate

1 Like

There's also a crate to do this: https://crates.io/crates/embed_resource

2 Likes

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.
1 Like

https://stackoverflow.com/a/65393488


Found a much easier solution.

1 Like

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.