Skip to content

CACHEDIR.TAG not created for some *-apple-darwin targets #165

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sandhose opened this issue Sep 8, 2023 · 5 comments
Closed

CACHEDIR.TAG not created for some *-apple-darwin targets #165

sandhose opened this issue Sep 8, 2023 · 5 comments

Comments

@sandhose
Copy link

sandhose commented Sep 8, 2023

Cargo creates CACHEDIR.TAG files in some directories of the target/ folder, so that they are marked as excluded for backups. This is also used by the Swatinem/rust-cache action to know if the directory should be kept for cache or not

Turns out, for some reason with *-apple-darwin targets (at least), cargo-zigbuild doesn't create such a file.

Repo:

Create an empty bin crate:

> cargo new cachedir-repro
     Created binary (application) `cachedir-repro` package
> cd cachedir-repo/

It works as expected with cargo build on the aarch64-apple-darwin target:

> rm -rf target/
> cargo build --target aarch64-apple-darwin
...
> cat target/aarch64-apple-darwin/CACHEDIR.TAG
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by cargo.
# For information about cache directory tags see https://bford.info/cachedir/

It doesn't with cargo zigbuild on the aarch64-apple-darwin target:

> rm -rf target/
> cargo zigbuild --target aarch64-apple-darwin
...
> cat target/aarch64-apple-darwin/CACHEDIR.TAG
cat: target/aarch64-apple-darwin/CACHEDIR.TAG: No such file or directory

But it works with some targets:

> rm -rf target/
> cargo zigbuild --target aarch64-unknown-linux-gnu
...
> cat target/aarch64-unknown-linux-gnu/CACHEDIR.TAG
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by cargo.
# For information about cache directory tags see https://bford.info/cachedir/

This is affecting me because it means macOS builds are not properly cached in my CI, with a combination of cargo-zigbuild and Swatinem/rust-cache.

Note that the host target seems irrelevant, I tried both from a Linux host and a macOS host, and it affects AFAIK the aarch64-apple-darwin and the x86_64-apple-darwin targets

@sandhose sandhose changed the title CACHEDIR.TAG not created for some cross-platform targets CACHEDIR.TAG not created for some *-apple-darwin targets Sep 8, 2023
@messense
Copy link
Member

messense commented Sep 9, 2023

I'm not sure why it's not created because eventually it's cargo driving the build, cargo-zigbuild only sets up some environment variables to use zig as c/c++ compiler and linker.

Nothing obvious I can do here.

@messense messense closed this as not planned Won't fix, can't repro, duplicate, stale Sep 9, 2023
@sandhose
Copy link
Author

sandhose commented Sep 9, 2023

But the issue exists, can be reliably reproduced, has real consequences (in my case, macOS CI builds not being cached), and looks somehow specific to cargo-zigbuild, since regular equivalent cargo calls work as expected. I can try investigating a bit more on my free time, but I really think the issue should stay open in the meantime

@messense
Copy link
Member

messense commented Sep 9, 2023

Sure, we can open it if you want to investigate.

Do note that I'll close it again if nothing comes up after a month or two.

@messense messense reopened this Sep 9, 2023
@sandhose
Copy link
Author

sandhose commented Sep 9, 2023

I found the culprit:

cargo-zigbuild/src/zig.rs

Lines 749 to 777 in 0c4827b

if target.contains("apple") {
let target_dir = if let Some(target_dir) = cargo.target_dir.clone() {
target_dir.join(target)
} else {
let manifest_path = manifest_path.unwrap_or_else(|| Path::new("Cargo.toml"));
if !manifest_path.exists() {
// cargo install doesn't pass a manifest path so `Cargo.toml` in cwd may not exist
continue;
}
let mut metadata_cmd = cargo_metadata::MetadataCommand::new();
metadata_cmd.manifest_path(manifest_path);
let metadata = metadata_cmd.exec()?;
metadata.target_directory.into_std_path_buf().join(target)
};
let profile = match cargo.profile.as_deref() {
Some("dev" | "test") => "debug",
Some("release" | "bench") => "release",
Some(profile) => profile,
None => {
if release {
"release"
} else {
"debug"
}
}
};
let deps_dir = target_dir.join(profile).join("deps");
fs::create_dir_all(&deps_dir)?;
fs::write(deps_dir.join("libiconv.tbd"), LIBICONV_TBD)?;

Before invoking cargo build, the target/[profile]/deps/ directory is being created, so when cargo is invoked, it skips the target directory creation (done here)

I don't exactly know how one would fix this, but I can confirm commenting the last two lines is enough to fix the issue

@messense
Copy link
Member

messense commented Sep 9, 2023

Thanks, see also rust-lang/cargo#12441.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants