nabijaczleweli / rust-embed-resource

A Cargo build script library to handle compilation and inclusion of Windows resources, in the most resilient fashion imaginable
MIT License
173 stars 29 forks source link

Support for .res and .rct files? #28

Closed rodrigocfd closed 3 years ago

rodrigocfd commented 3 years ago

Visual Studio Resource Editor is capable of exporting self-contained .rct and .res files, which do not depend on Windows headers.

It seems that, in its current version, embed-resource can load only .rc files. It would add extra flexibility if .rct and .res files could be loaded too, maybe with other methods besides compile.

nabijaczleweli commented 3 years ago

Cool, how are they different (from the canonically-.rc source and one another) and how do you make them linkable?

rodrigocfd commented 3 years ago

The .rct format is some sort of self-contained file created in Visual Studio, called Native Resource Template. I really don't know anything about the binary format, so we can let it aside for now.


The .res format is the binary result of the .rc compilation produced by the RC tool, which is then passed to the linker. I presume embed_resource::compile (which takes an .rc file) compiles it into a .res, and then this .res is passed to the linker in some way.

If so, adding .res support would be a matter of adding a mid-step to embed_resource::compile. We would have something like embed_resource::embed, which would be called by compile. In a bird's-eye view, these would be the external functions:

// Same pub function we have today.
pub fn compile(rc_file: &str) {
    let res_file = internal_compilation_stuff(rc_file);
    embed(res_file);
}

// New public function.
pub fn embed(res_file: &str) {
    // embed into exe..
}

I also see the possibility of leaving compile the way it is, and simply add embed as a function calling the linker with the .res file.

nabijaczleweli commented 3 years ago

I mean, in that case, just link it directly, there's no processing that needs to be done except to print cargo:rustc-link-lib=dylib=your_artifact.res (or summat along those lines), which should be emitted by whatever's building it, right?

rodrigocfd commented 3 years ago

I'm unaware of such option... where I can find documentation about it?

nabijaczleweli commented 3 years ago

(a) https://docs.microsoft.com/en-us/cpp/build/reference/dot-res-files-as-linker-input?view=msvc-160, (b) https://doc.rust-lang.org/cargo/reference/build-scripts.html

rodrigocfd commented 3 years ago

Thank you very much.

I made it work, but I'm having a problem. The tool is always appending a .lib extension to my .res file, so the build fails because the file is never found. I manually renamed my stuff.res to stuff.res.lib... and then it finally worked.

Do you know any way to make it accept the .res extension?

nabijaczleweli commented 3 years ago

No idea; if you had direct access to the linker cmdline you might be able to spec just suff.res instead of -lstuff.res (or which-ever format LINK.EXE supports), but I don't think that's possible with Cargo control lines.

rodrigocfd commented 3 years ago

Do you know where I can open an issue about this Cargo behavior?

nabijaczleweli commented 3 years ago

https://github.com/rust-lang/cargo probably

rodrigocfd commented 3 years ago

Thank you very much. I opened an issue here.