Skip to content

--artifact-dir (nee --out-dir) Tracking Issue #6790

Open

Description

@ehuss

Note: this was renamed from --out-dir to --artifact-dir in #13809

Original issue: #4875
Implementation PR: #5203
Documentation: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dir
Issues: Z-out-dir Nightly: --out-dir

Summary
Adds --artifact-dir=PATH flag to cargo build to specify a directory to place final artifacts.

Tasks:

Unresolved questions

Future possibilities

  • Deprecate --target-dir, hiding it from the CLI help

Activity

  1. ultrasaurus commented on Jan 15, 2020

    @ultrasaurus

    I find this feature very helpful, since I get output in a directory named like this ./target/debug/build/mylib-79d5eadf36eadf53 and with a build.rs file there are two similarly named directories.

    However, it doesn't seem that OUT_DIR environment variable is set to the value of --out-dir when build.rs is executed. Is that intentional? is there some other way to discover the value of --out-dir?

  2. haze commented on Mar 22, 2020

    @haze

    +1 on this issue. I have a program that uses a template directory for rust compilation and would like to now have to recompile everything. Yes I could symlink all the folders within target, but it would be nicer to be able to specify the binary output path. I'm not sure why this is such an overlooked issue.

  3. robinbudd commented on Jul 8, 2020

    @robinbudd

    When will this feature be available in the stable release? It would greatly simplify my build/CI pipeline.

  4. Chris--B commented on Jul 16, 2020

    @Chris--B

    +1 on this. This greatly improves the workflow on our CI, and we'd like to avoid using a nightly compiler just for this.

    What needs to happen for this to move forward?

  5. lf- commented on Aug 9, 2020

    @lf-
    Contributor

    This issue makes nmattia/naersk unusable on stable rust. (another build system issue)

  6. golddranks commented on Oct 5, 2020

    @golddranks
    Contributor

    This would streamline some of my Dockerfiles and build scripts quite nicely.

  7. Diggsey commented on Nov 24, 2020

    @Diggsey
    Contributor

    Is there a reason this doesn't work with cargo rustc?

  8. benesch commented on Jan 26, 2021

    @benesch
    Contributor

    I just published a crate called cargo-out-dir to crates.io, which can ease some of the frustration while we wait for this to stabilize. All it does is print out the current' crate's out directory, as determined by running cargo check --metadata-format=json:

    $ cargo install cargo-out-dir
    $ cargo out-dir
    /home/benesch/path/to/crate/target/debug/build/foo-9d9f15d3d084bc3a/out
    
  9. simonbuchan commented on Apr 7, 2021

    @simonbuchan

    Another potential use case for out-dir is making cargo run work nicely with building MacOS apps, which expect a structure like:

    My App.app/Contents/
      Info.plist
      MacOS/actual-binary
      Resources/foo.png
    

    in order for native APIs like (the moral equivalent of) [NSImage imageNamed: @"foo"] to work.

    But in this case it would be more helpful to be able to put out-dir = "dist/My App.app/Contents/MacOS" in Cargo.toml somewhere, presumably in the [bin] section. Not sure if that makes anyone more or less happy?

  10. workingjubilee commented on Apr 15, 2021

    @workingjubilee
    Member

    --out-dir should not have this name because --out-dir on rustc performs almost the exact function of --target-dir, and to have this be a copy directory command on cargo instead would be confusing. A name like --copy-dir would suffice, however. I believe one of the proposed solutions for #6100, such as having the ability to independently specify "scratch" and "final" build artifact directories is worth investigating.

  11. piegamesde commented on Jun 3, 2022

    @piegamesde

    What exactly is the use case for this? In what scenario would it be used where you don't already have an outer build system or script that can copy the files into the correct location?

    I run into this regularly (multiple times a year), and I am not the only one. At the moment, people hard-code ./target/release/binary or some variant of it like $CARGO_TARGET_DIR/$TARGET/$APPNAME for copying their binaries in installation scripts. This quickly breaks apart in the following cases:

    • The cargo target dir has been moved to a custom value
    • Cross compilation.

    Cargo's current file handling is unfortunate, and stabilizing this value would help a lot. Specifically, all temporary build files should be freely movable to an external directory, while the build outputs (i.e. the binaries or shared objects) should land in a fixed path for easy packaging.

    (In an ideal world, ./target would only contain what --out-dir currently provides by default, and all other build artifacts would land somewhere user-configurable with a default to $XDG_CACHE_HOME/cargo-target/appname or something)

    Related: #6100 (comment)

  12. bugproof commented on Jun 23, 2022

    @bugproof

    @piegamesde exactly, I'm used to having bin and obj nice and clean. There should be an environment variable or make it configurable from file as well (--out-dir )

  13. vabka commented on Jul 13, 2022

    @vabka

    Why is it still unstable?
    I need to use some dark magic to build in debug/release profiles in one dockefile

    ...
    # If release is set to any value then PROFILE env var becomes 'release' and then left unchanged
    # Otherwise PROFILE env var becomes empy and then changes to debug 
    ARG release
    ENV PROFILE=${release:+release}
    ENV PROFILE=${PROFILE:-debug}
    
    RUN cargo build --frozen --offline --target x86_64-unknown-linux-gnu ${release:+--release}
    
    FROM docker.io/ubuntu:22.04 as prod
    COPY --from=build /target/${PROFILE}/executable /
    ...
    
  14. 54 remaining items

  15. stefnotch commented on Sep 15, 2025

    @stefnotch

    What exactly is the use case for this? In what scenario would it be used where you don't already have an outer build system or script that can copy the files into the correct location?

    I have such a case in vscode-lelwel for building a wasm binary. As it is a VSCode extension, the outer build system is "npm scripts".

    However, npm scripts are essentially platform specific shell scripts, which means that even the cp target/wasm32-wasip1-threads/release/lelwel-ls.wasm ../server/ is not a reliable option. It doesn't work on Windows. So it is currently a hassle to build the extension on Windows systems.

    So there is at least one common outer build system that would benefit from this feature.

  16. FredM67 commented on Oct 6, 2025

    @FredM67

    For what it's worth, I think it's very important to prioritize this issue.

    Because cargo's target directories are nested and are basically impossible to predict, it makes it hard to integrate crates into existing C or C++ projects.

    --artifact-dir solves my problem perfectly, I'm able to have Cargo spit out this .a that I need for testing in a place where the calling Makefile knows exactly where it is.

    I saw earlier in this thread that a design philosophy was "Cargo should work well with just Cargo" and I think that will ultimately harm Rust's adoption in industry. In the real world, we will need to do stuff like this and I don't think --artifact-dir is a bad solution at all. In fact, it's quite nice.

    100%...
    On entreprise build systems, we can most of the time if not all the time, specify where each type of artifacts is being placed/copied (binaries, static libs, ....).
    The solution with a script is ONLY a temporary solution...
    BTW, I don't understand why this simple feature is still not available after so many years !

  17. nine9ths commented on Nov 3, 2025

    @nine9ths

    Will this also set an env variable that is available to build.rs?

    My use case is that when I build I want to copy platform specific resources into my artifact directory based on which features I'm building with. I can achieve this with an env variable set when calling cargo build but it would be nice if it was set automatically.

    I've tried testing with the following and it fails:

    fn main() -> ExitCode {
        let Ok(artifact_dir) = env::var("CARGO_ARTIFACT_DIR") else {
            return ExitCode::from(1);
        };
        ExitCode::SUCCESS
    }
  18. epage commented on Nov 3, 2025

    @epage
    Contributor

    That request is a variant of #9661. Most likely how this will be handled is instead #13663.

  19. added
    S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
    and removed
    S-needs-team-inputStatus: Needs input from team on whether/how to proceed.
    S-waiting-on-feedbackStatus: An implemented feature is waiting on community feedback for bugs or design concerns.
    on Feb 9, 2026
  20. epage commented on Feb 9, 2026

    @epage
    Contributor

    Switched this from S-needs-team-input to S-needs-design as we previously had a high level discussion of what we want (#14125 (comment)), we just need to work out the details.

    At least build-dir is stabilized so we know what will live in each location.

  21. added
    S-acceptedStatus: Issue or feature is accepted, and has a team member available to help mentor or review
    and removed
    S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
    on Feb 9, 2026
  22. epage commented on Feb 9, 2026

    @epage
    Contributor

    I've enumerated some tasks that don't need major design work so I moved this to S-accepted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: A tracking issue for something unstable.S-acceptedStatus: Issue or feature is accepted, and has a team member available to help mentor or reviewZ-out-dirNightly: --out-dir

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions