rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.78k stars 2.42k forks source link

Add support for resource files #5305

Open Pzixel opened 6 years ago

Pzixel commented 6 years ago

This is similar to #2729, however, it's a bit different.

The main problem I currently have is that I cannot place configs near my executable. It's common practice in many languages and IDE's that you have some file that gets copied to output directory. For example, let's look at csproj configuration for C# project:

  <ItemGroup>
    <None Update="appsettings.json">
      <Generator>SettingsSingleFileGenerator</Generator>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="appsettings.Production.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

It literaly says "copy this file to output directory (wherever it is) if file in project is newer". It's common, it's convinient.

Currently in Rust i have following build.rs script:

use std::path::Path;
use std::{env, fs};

const SETTINGS_FILE: &str = "Settings.toml";
const LOG4RS_FILE: &str = "log4rs.toml";
fn main() {
    let target_dir_path = env::var("OUT_DIR").unwrap();
    copy(&target_dir_path, LOG4RS_FILE);
    copy(&target_dir_path, SETTINGS_FILE);
}

fn copy<S: AsRef<std::ffi::OsStr> + ?Sized, P: Copy + AsRef<Path>>(target_dir_path: &S, file_name: P) {
    fs::copy(file_name, Path::new(&target_dir_path).join("../../..").join(file_name)).unwrap();
}

It actually does work, but it's not really convinient and we'd like ot have more declarative description.

We'd probably like to specify in cargo.toml as:

[resources]
preserve_newest = ["log4rs.toml", "Settings.toml"]

or even

[resources]
preserve_newest = {file = "log4rs.toml", target_path = "configs/log4rs/log4rs.toml"}

And be sure that when cargo build an application, resource files gets its place near executable (or at some relative path).

This feature should be limited to executables, so it doesn't work for libraries so we don't care about requiring copying these files transitively.

seik0ixtem commented 6 years ago

Finally I'm not the only one on the whole rusternet with the Problem of copying associated files to binary output dir.

p.s. sorry for off-topic, but I lost whole day in hope that this problems must already been solved.

cschlesselmann commented 5 years ago

I would really like this as well

joshhansen commented 5 years ago

Upvote. I need to include image files, data files, etc. with my application and would like to do so in a clean and standard way.

proninyaroslav commented 4 years ago

This would allow us to take a step forward for the development of GUI apps in which resources are used most often.

adamrybak commented 4 years ago

I nice clean solution to add an icon/resource to our binaries would be great!

ta32 commented 2 years ago

for wasm projects people use trunk to pack and run their app https://trunkrs.dev/ but yea for small projects with resources would be nice to have some standard way of doing it.

I guess everyone implements in a build.rs file

epage commented 1 year ago

A more general solution is #545.

Pzixel commented 1 year ago

My original thought was about more declarative approach. OTOH maybe crates.io can fill this by providing libraries with required DSL to make it more convenient to use than managing everything by hand.