Changing the icon of an .exe file in Rust - rust

So I did some research and found out about rs.exe in Windows to convert my resources.rs file containing a name to_do and PATH to ico to res. The only problem is after navigating to its directory and running the command rs resource.exe. I get the error RC1109 which im told is that the rc.exe can not find the path.
What am I doing wrong? should I keep my resources.rs file in the same folder as the rc.exe?
do I have to format the text included in the file in some sort of way?
As always thanks for your help!

You can use the winres crate to set an icon for the .exe when you run cargo build or cargo run.
Add this to your Cargo.toml:
[package]
...
build = "build.rs"
[build-dependencies]
winres = "0.1"
Then create a build.rs file in the same directory where the Cargo.toml is located, with the following content:
extern crate winres;
fn main() {
if cfg!(target_os = "windows") {
let mut res = winres::WindowsResource::new();
res.set_icon("my_icon.ico"); // Replace this with the filename of your .ico file.
res.compile().unwrap();
}
}
Then you have to copy your .ico file in that same directory, too. Don't forget to change the filename in build.rs.

Related

Rust - Call functions from a c lib under windows with .dll file

I'm working on a project that need to call a C project shared lib in Windows.
Suppose I have the my-math.dll file under rust src folder. I already add libc crate in Cargo.toml and following is my main.rs code:
extern crate libc;
#[link(name = "my-math")]
extern {
}
fn main() {
}
When I tried to build the project, it came with the error note: LINK : fatal error LNK1181: cannot open input file 'my-math.lib'
Seems the #[link(name="my-math")] converted to my-math.lib automatically. But I only have the .dll file. Is there anyway to switch to dll file instead of lib file.
I don't want to use the header file with bindgen crate for some special reasons.

How to list a project's source files using the cargo crate?

I'm trying to list the source files of a Rust project using the cargo crate. I can not just simply list all the .rs files present in a directory as I want to retrieve exactly the files that the compiler sees during the compilation, which may not be all the .rs files.
I'm conducting my experiments on the the Alacritty repository, which has a cargo workspace of 3 projects. Here is my code so far:
extern crate cargo;
use std::path::Path;
use cargo::core::Source;
fn main() {
let path = Path::new("/tmp/alacritty/Cargo.toml");
let config = cargo::util::config::Config::default().unwrap();
let ws = cargo::core::Workspace::new(&path, &config).unwrap();
for pkg in ws.members() {
println!("found package {}", pkg);
let config = ws.config();
let mut src = cargo::sources::PathSource::new(pkg.root(), pkg.package_id().source_id(), config);
src.update().unwrap();
let src_files = src.list_files(pkg).unwrap();
println!("found {} source files", src_files.len());
}
}
Here is the output:
found package alacritty v0.5.0-dev (/tmp/alacritty/alacritty)
found 0 source files
found package alacritty_terminal v0.5.0-dev (/tmp/alacritty/alacritty_terminal)
found 0 source files
found package font v0.1.0 (/tmp/alacritty/font)
found 0 source files
The members of the workspace are correctly found but I fail to retrieve the source files for each of these members. What am I missing?
Your code works!
If you run 'cargo vendor' in the alacritty tree, this should solve your issue. Study the 'cargo vendor' command Also, study the --offline switch for the cargo build command. I did not need to use this, but it is very helpful reading.
Basically, cargo vendor pulls in all the source.
I am not sure exactly why your code is not working. I had difficulty recreating this using the /tmp directory. I then used a normal directory combined with a call to 'cargo vendor', and it worked. Before cutting and pasting my code below, be sure to change '/Users/[username]' with your own path to your home directory.
Here is my procedure:
cd ~
git clone https://github.com/jwilm/alacritty
cargo vendor
This next part is probably not necessary:
mkdir /Users/[username]/alacritty/.cargo
Create a file at /Users/[username]/alacritty/.cargo/config
and, insert the following:
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"
Continuation of necessary part:
Modify the path statement to point to the newly created alacritty path:
let path = Path::new("/Users/[username]/alacritty/Cargo.toml");
Now, run your code
cargo run
Here is my output:
cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.27s
Running `target/debug/test3`
found package alacritty v0.5.0-dev (/Users/jmurray/alacritty/alacritty)
found 18 source files
found package alacritty_terminal v0.5.0-dev
(/Users/[username]/alacritty/alacritty_terminal)
found 172 source files
found package font v0.1.0 (/Users/jmurray/alacritty/font)
found 12 source files
Search for each element of the needle in the haystack in order. Each time you find a matching element, only continue the search in the remaining portion of the haystack. You can express this nicely by taking a new subslice of of the haystack each time you match an element.

Is using main.rs as lib entry point unidiomatic?

I'm currently experimenting with wasm, which has to be compiled as cdylib. I don't want to maintain two entry files for the bin target and for the lib target, so I added these lines to my Cargo.toml:
[lib]
name = "sandbox"
path = "src/main.rs"
crate-type = ["cdylib"]
My fn main() has now this attribute:
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
Everything works as expected, but cargo warns me about this:
warning: file found to be present in multiple build targets
Can this warning safely be ignored? Why?
If yes, is it possible to suppress it?

failed to parse manifest - no targets specified

I am new to Rust and attempting to build a test project with Cargo. My Cargo.toml looks like:
[package]
name = "rust-play"
version = "0.0.1"
authors = [ "Bradley Wogsland <omitted>" ]
(but the actual TOML file doesn't omit my email). When I cargo build I am getting the following error:
error: failed to parse manifest at /Users/wogsland/Projects/rust-play/Cargo.toml
Caused by:
no targets specified in the manifest
either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present
My main function is in a src/test.rs file. Do I need to specify that in the TOML file? If so, how? I tried adding
target = "src/test.rs"
to no avail.
As the error says:
either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present
So the direct answer is to add a [[bin]] section:
[[bin]]
name = "test"
path = "src/test.rs"
However, it's far more usual to just place the file in the expected location: src/main.rs. You could also place it in src/bin/test.rs if you plan on having multiple binaries.
If it's actually for testing your code, then unit tests go in the same file as the code they are testing and integration tests go in tests/foo.rs.
Alternative issue and solution: You can also be faced with this error if you have copied Cargo.toml file to a parent folder of the crate.
I ran into this issue on Ubuntu 20.04 after having inadvertently copied Cargo.toml to my home folder. Even though my working directory had a properly defined Cargo.toml, the copy in $HOME was taking precedence and causing builds to fail.
In my case and probably in your case as well, the rs file was not named main.rs while Cargo assumes that src/main.rs is the crate root of a binary crate. So, the rule is that If project is an executable, name the main source file src/main.rs. If it is a library, name the main source file src/lib.rs.
Additionally, Cargo will also treat any files located in src/bin/*.rs as executables like mentioned in the previous answer.
As a summary:
If you use cargo new xxx --bin, you will find the file in the src directory is named main.rs. And when you check the file Cargo.toml. It is the same as you written. So the first way is to change the file in src to main.rs
As the cargo report, we can use the [[bin]] to set the file. #Shepmaster has solved it.
Both two ways can work.
I also had this issue and it was because the parent directory also contained a Cargo.toml file and it was prioritising that over the one in the current directory

capnpc::compile not writing files

I'm having difficulty working with the capnpc crate. I'm running Arch Linux and have installed capnp from the AUR and compiled capnpc-rust from the github project and put it in /usr/local/bin. I can manually compile the .capnp file easily with the command
capnp compile -orust --src-prefix=capnp capnp/message.capnp
I tried cloning the capnpc project and compiling the .capnp test file in the test directory and that didn't work either. I'm not getting any errors (whereas earlier I was getting "File not found") so it seems like capnpc is working, but I can't find files anywhere.
build.rs
extern crate capnpc;
fn main() {
::capnpc::compile("capnp", &["capnp/message.capnp"]).unwrap();
}
Cargo.toml
...
build = "build.rs"
[lib]
name = "rustp2p"
path = "src/lib.rs"
[build-dependencies]
capnpc = "*"
[dependencies]
capnp = "0.5.0"
Edit: .rs file builds out into /target/debug/build/.../out.
When you invoke capnpc::compile from a Cargo build script, the generated code goes in a subdirectory of target/ that can be found at main compile time through the OUT_DIR environment variable. This strategy is described in the Cargo documentation.
You shouldn't need to install the capnpc-rust binary in /usr/local/bin or anywhere else for this to work.
Your build.rs and Cargo.toml files look fine to me.
You might find it helpful to consult the addressbook example.

Resources