Skip to content

Commit

Permalink
Added build.build_dir configuration option
Browse files Browse the repository at this point in the history
This commit adds a `build_dir` option to the `build` table in
`config.toml` and adds the equivalent field to `Workspace` and `GlobalContext`.
  • Loading branch information
ranger-ross committed Feb 24, 2025
1 parent f6f2622 commit aab7b90
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
16 changes: 16 additions & 0 deletions src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ pub struct Workspace<'gctx> {
/// `None` if the default path of `root/target` should be used.
target_dir: Option<Filesystem>,

/// Shared build directory for intermediate build artifacts.
/// This directory may be shared between multiple workspaces.
build_dir: Option<Filesystem>,

/// List of members in this workspace with a listing of all their manifest
/// paths. The packages themselves can be looked up through the `packages`
/// set above.
Expand Down Expand Up @@ -209,6 +213,7 @@ impl<'gctx> Workspace<'gctx> {
pub fn new(manifest_path: &Path, gctx: &'gctx GlobalContext) -> CargoResult<Workspace<'gctx>> {
let mut ws = Workspace::new_default(manifest_path.to_path_buf(), gctx);
ws.target_dir = gctx.target_dir()?;
ws.build_dir = gctx.build_dir()?;

if manifest_path.is_relative() {
bail!(
Expand Down Expand Up @@ -238,6 +243,7 @@ impl<'gctx> Workspace<'gctx> {
},
root_manifest: None,
target_dir: None,
build_dir: None,
members: Vec::new(),
member_ids: HashSet::new(),
default_members: Vec::new(),
Expand Down Expand Up @@ -282,6 +288,7 @@ impl<'gctx> Workspace<'gctx> {
} else {
ws.gctx.target_dir()?
};
ws.build_dir = ws.target_dir.clone();
ws.members.push(ws.current_manifest.clone());
ws.member_ids.insert(id);
ws.default_members.push(ws.current_manifest.clone());
Expand Down Expand Up @@ -418,6 +425,15 @@ impl<'gctx> Workspace<'gctx> {
.unwrap_or_else(|| self.default_target_dir())
}

pub fn build_dir(&self) -> Filesystem {
if !self.gctx().cli_unstable().build_dir {
return self.target_dir();
}
self.build_dir
.clone()
.unwrap_or_else(|| self.default_target_dir())
}

fn default_target_dir(&self) -> Filesystem {
if self.root_maybe().is_embedded() {
let hash = crate::util::hex::short_hash(&self.root_manifest().to_string_lossy());
Expand Down
31 changes: 30 additions & 1 deletion src/cargo/util/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ impl GlobalContext {
///
/// Returns `None` if the user has not chosen an explicit directory.
///
/// Callers should prefer `Workspace::target_dir` instead.
/// Callers should prefer [`Workspace::target_dir`] instead.
pub fn target_dir(&self) -> CargoResult<Option<Filesystem>> {
if let Some(dir) = &self.target_dir {
Ok(Some(dir.clone()))
Expand Down Expand Up @@ -634,6 +634,34 @@ impl GlobalContext {
}
}

/// The directory to use for intermediate build artifacts.
///
/// Falls back to the target directory if not specified.
///
/// Callers should prefer [`Workspace::build_dir`] instead.
pub fn build_dir(&self) -> CargoResult<Option<Filesystem>> {
if !self.cli_unstable().build_dir {
return self.target_dir();
}
if let Some(val) = &self.build_config()?.build_dir {
let path = val.resolve_path(self);

// Check if the target directory is set to an empty string in the config.toml file.
if val.raw_value().is_empty() {
bail!(
"the build directory is set to an empty string in {}",
val.value().definition
)
}

Ok(Some(Filesystem::new(path)))
} else {
// For now, fallback to the previous implementation.
// This will change in the future.
return self.target_dir();
}
}

/// Get a configuration value by key.
///
/// This does NOT look at environment variables. See `get_cv_with_env` for
Expand Down Expand Up @@ -2653,6 +2681,7 @@ pub struct CargoBuildConfig {
pub pipelining: Option<bool>,
pub dep_info_basedir: Option<ConfigRelativePath>,
pub target_dir: Option<ConfigRelativePath>,
pub build_dir: Option<ConfigRelativePath>,
pub incremental: Option<bool>,
pub target: Option<BuildTargetConfig>,
pub jobs: Option<JobsConfig>,
Expand Down
22 changes: 22 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Each new feature described below should explain how to use it.
* [feature-unification](#feature-unification) --- Enable new feature unification modes in workspaces
* Output behavior
* [artifact-dir](#artifact-dir) --- Adds a directory where artifacts are copied to.
* [build-dir](#build-dir) --- Adds a directory where intermediate build artifacts are stored.
* [Different binary name](#different-binary-name) --- Assign a name to the built binary that is separate from the crate name.
* [root-dir](#root-dir) --- Controls the root directory relative to which paths are printed
* Compile behavior
Expand Down Expand Up @@ -238,6 +239,27 @@ This can also be specified in `.cargo/config.toml` files.
artifact-dir = "out"
```

## build-dir
* Original Issue: [#14125](https://github.com/rust-lang/cargo/issues/14125)
* Tracking Issue: [#14125](https://github.com/rust-lang/cargo/issues/14125)

The directory where intermediate build artifacts will be stored.
Intermediate artifacts are produced by Rustc/Cargo during the build process.

```toml
[build]
build-dir = "out"
```

### `build.build-dir`

* Type: string (path)
* Default: Defaults to the value of `build.target-dir`
* Environment: `CARGO_BUILD_BUILD_DIR`

The path to where internal files used as part of the build are placed.


## root-dir
* Original Issue: [#9887](https://github.com/rust-lang/cargo/issues/9887)
* Tracking Issue: None (not currently slated for stabilization)
Expand Down

0 comments on commit aab7b90

Please sign in to comment.