【问题标题】:Copy files to the target directory after build构建后将文件复制到目标目录
【发布时间】:2021-05-13 16:55:37
【问题描述】:

假设我有一个具有以下目录结构的游戏:

/src
/resources
Cargo.toml

我希望cargo build复制resources目录下的文件,并将它们粘贴到可执行文件所在的同一目录中。

我知道可以使用自定义构建脚本来执行此操作,但这似乎是一个常见的情况,需要特殊处理。所以问题是:cargo 是否提供了将文件复制到目标目录的标准方法(仅使用Cargo.toml)?

【问题讨论】:

    标签: rust rust-cargo


    【解决方案1】:

    不,它没有。

    您可以使用 build scripts 移动文件,但这些文件在您的 crate 构建之前运行,因为它们的唯一目的是准备环境(例如编译 C 库和垫片)。

    如果您认为这是一个重要功能,您可以在 Cargo issue tracker 中打开功能请求。

    或者,您可以编写一个makefile或一个shell脚本,将所有参数转发给cargo,然后手动复制目录:

    #!/bin/bash
    
    DIR="$(dirname "$0")"
    
    if cargo "$@"; then
        [ -d "$DIR/target/debug" ] && cp -r "$DIR/resources" "$DIR/target/debug/resources"
        [ -d "$DIR/target/release" ] && cp -r "$DIR/resources" "$DIR/target/release/resources"
    fi
    

    现在你可以像这样运行货物了

    % ./make.sh build
    

    【讨论】:

    【解决方案2】:

    我无法为 crates 解决这个问题(正如公认的答案所说),但对于需要文件才能正确运行的“单一”二进制文件,这对我有用。

    use std::env;
    use std::path::Path;
    use std::path::PathBuf;
    
    fn main() {
        println!("cargo:rerun-if-changed=config.json");
        println!("cargo:warning=Hello from build.rs");
        println!("cargo:warning=CWD is {:?}", env::current_dir().unwrap());
        println!("cargo:warning=OUT_DIR is {:?}", env::var("OUT_DIR").unwrap());
        println!("cargo:warning=CARGO_MANIFEST_DIR is {:?}", env::var("CARGO_MANIFEST_DIR").unwrap());
        println!("cargo:warning=PROFILE is {:?}", env::var("PROFILE").unwrap());
    
        let output_path = get_output_path();
        println!("cargo:warning=Calculated build path: {}", output_path.to_str().unwrap());
    
        let input_path = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join("config.json");
        let output_path = Path::new(&output_path).join("config.json");
        let res = std::fs::copy(input_path, output_path);
        println!("cargo:warning={:#?}",res)
    }
    
    fn get_output_path() -> PathBuf {
        //<root or manifest path>/target/<profile>/
        let manifest_dir_string = env::var("CARGO_MANIFEST_DIR").unwrap();
        let build_type = env::var("PROFILE").unwrap();
        let path = Path::new(&manifest_dir_string).join("target").join(build_type);
        return PathBuf::from(path);
    }
    

    这是一团糟,我对 Rust 很陌生。欢迎改进。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    相关资源
    最近更新 更多