Skip to content
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

A relative CARGO_TARGET_DIR is no longer relative to the users current working directory but instead is always relative to the target crate's root directory #138

Closed
masonhieb opened this issue Aug 22, 2024 · 10 comments

Comments

@masonhieb
Copy link

I am using cargo deb from the root directory of a workspace. I use a relative path in CARGO_TARGET_DIR to send all output to one directory, and I provide a --manifest-path to the Cargo.toml of the crate I wish to build. I believe as a result of this commit, this no longer works. Now the CARGO_TARGET_DIR path is always presumed to be relative to the root directory of the crate because cargo deb changes the working directory to the root directory of the crate. Now a new output subdirectory is created for each crate in my workspace.

The Rust docs define CARGO_TARGET_DIR as:

Location of where to place all generated artifacts, relative to the current working directory

My assumption as a user is that the current working directory is wherever I am currently running my cargo command from, but with this new change that assumption no longer holds. Is this the desired behavior? Am I just using cargo deb improperly?

@masonhieb masonhieb changed the title A relative CARGO_TARGET_DIR is no longer relative to the *users* current working directory but instead is always relative to the *target crate*'s root directory A relative CARGO_TARGET_DIR is no longer relative to the users current working directory but instead is always relative to the target crate's root directory Aug 22, 2024
@kornelski
Copy link
Owner

Ugh, it looks like an impossible scenario.

That commit fixed problems caused by .cargo/config changing the meaning of target-dir.

I think the current state is the better one, because the current directory is the same for the call to cargo metadata and call to cargo build. Previously they were mismatched, so I'm surprised that relative CARGO_TARGET_DIR worked at all.

@kornelski
Copy link
Owner

kornelski commented Aug 28, 2024

Cargo is surprisingly sensitive to the current directory, and not just env vars, but also config.toml is dependent on the current dir rather than the workspace location: rust-lang/cargo#2930

This is really weird and unexpected to me.

Cargo-deb needs to have cargo metadata, cargo build, and its own file access agree where the target directory is. Additionally it needs to be able to build multiple binaries from the same workspace, or select individual crates with -p or --manifest-path, or by running bare cargo deb in crate's manifest dir. All of this is already a delicate puzzle, and allowing it to further vary where current dir != manifest dir, creates too many possible configurations for me to test and support.

So I'm going to deviate from cargo's quirk here, and force current dir to be the same as manifest dir.

@kornelski kornelski closed this as not planned Won't fix, can't repro, duplicate, stale Aug 28, 2024
@WhiteBlackGoose
Copy link

WhiteBlackGoose commented Nov 30, 2024

Sad that cargo-deb doesn't support workspaces (correct me if I'm wrong)

The hack I decided to go with is creating a symlink in YOURCRATE/target/ pointing to workspace's target/release:

export CRATE=my_crate
mkdir -p target/release 2> /dev/null
mkdir $CRATE/target/
ln -s $(pwd)/target/release $(pwd)/$CRATE/target/
cd $CRATE
cargo-deb

That way you get the .deb package in the target/debian of the workspace (where it needs to be anyway), so the only part we're tricking here is so cargo-deb can look into the crate's relative target

@ximon18
Copy link
Contributor

ximon18 commented Nov 30, 2024

From the README:

Workspaces

Cargo-deb understands workspaces and can build all crates in the workspace if necessary. However, you must choose one crate to be the source of the package metadata. You can select which crate to build with -p crate_name or --manifest-path=<path/to/Cargo.toml>.

@WhiteBlackGoose
Copy link

Thanks for a quick response. I tried that before actually, and I'm hitting the problem from this issue (I believe):

cargo-deb: Asset file path does not match any files: /home/azureuser/MYWORKSPACE/MYCRATE/./target/release/MYCRATE

cargo-deb is looking for the wrong folder (I'm calling it from the workspace's root:

$ cd /home/azureuser/MYWORKSPACE
$ cargo deb -p MYCRATE
cargo-deb: Asset file path does not match any files: /home/azureuser/MYWORKSPACE/MYCRATE/./target/release/MYCRATE

(same result with --manifest-path)

@kornelski
Copy link
Owner

kornelski commented Nov 30, 2024

Don't hack it with symlinks!

cargo deb has the -o option to specify exactly where to put the .deb files, regardless of where Cargo keeps its build temp files. If you need the deb in a specific place, use -o. It can be a dir or a file path.

If you want Cargo's target dir elsewhere, just configure Cargo properly! cargo deb uses the official cargo metadata tool to find where the target dir is, so it uses what Cargo tells it to use. Set CARGO_TARGET_DIR to the absolute path you want (relative paths in there make no sense), or put .cargo/config.toml with [build] target-dir at the root of the workspace to set a workspace-relative target dir path.

In asset paths cargo deb always recognizes target/release prefix as a magic variable that will automagically find where Cargo has put the files, even if the directory is actually elsewhere and has a different name.

@WhiteBlackGoose
Copy link

WhiteBlackGoose commented Nov 30, 2024

Hi, the workspace's relative target directory is by default ./target, which cargo-deb doesn't respect, at least from my understanding (feel free to correct me). This doesn't help:

[build]
target-dir = "target"

In asset paths cargo deb always recognizes target/release prefix as a magic variable that will automagically find where Cargo has put the files, even if the directory is actually elsewhere and has a different name.

It doesn't find for me, I keep getting the error above. It insists that it expects the target directory in my crate's folder, but it's in the workspace's root (which is the default)

@kornelski
Copy link
Owner

What's the output of cargo metadata?

@WhiteBlackGoose
Copy link

Okay so, I took some more time to find out myself, started debugging cargo-deb, found all places where it finds assets, found no place where it detects the binary, and then ... turns out I was chasing my own tail. Guess I just completely forgot that I myself specify where to look for the executable, and turns out that I'm the problem, I just specified the paths wrong in my Cargo toml:

assets = [
    ["./target/release/MYAPP", "usr/bin/MYAPP", ... ]

and now it should be ../target/release instead

I'm sorry for wasting your time, and thank you so much for this great tool.

@kornelski
Copy link
Owner

Use target/release without ../ or ./, and cargo-deb will correct the path for you.

kornelski added a commit that referenced this issue Nov 30, 2024
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

4 participants