File tree Expand file tree Collapse file tree 6 files changed +83
-6
lines changed Expand file tree Collapse file tree 6 files changed +83
-6
lines changed Original file line number Diff line number Diff line change @@ -138,7 +138,7 @@ impl<'cfg> Workspace<'cfg> {
138
138
/// root and all member packages. It will then validate the workspace
139
139
/// before returning it, so `Ok` is only returned for valid workspaces.
140
140
pub fn new ( manifest_path : & Path , config : & ' cfg Config ) -> CargoResult < Workspace < ' cfg > > {
141
- let target_dir = config. target_dir ( ) ?;
141
+ let target_dir = config. target_dir ( manifest_path ) ?;
142
142
143
143
let mut ws = Workspace {
144
144
config,
@@ -198,13 +198,13 @@ impl<'cfg> Workspace<'cfg> {
198
198
{
199
199
let key = ws. current_manifest . parent ( ) . unwrap ( ) ;
200
200
let id = package. package_id ( ) ;
201
- let package = MaybePackage :: Package ( package) ;
202
- ws. packages . packages . insert ( key. to_path_buf ( ) , package) ;
203
201
ws. target_dir = if let Some ( dir) = target_dir {
204
202
Some ( dir)
205
203
} else {
206
- ws. config . target_dir ( ) ?
204
+ ws. config . target_dir ( package . manifest_path ( ) ) ?
207
205
} ;
206
+ let package = MaybePackage :: Package ( package) ;
207
+ ws. packages . packages . insert ( key. to_path_buf ( ) , package) ;
208
208
ws. members . push ( ws. current_manifest . clone ( ) ) ;
209
209
ws. member_ids . insert ( id) ;
210
210
ws. default_members . push ( ws. current_manifest . clone ( ) ) ;
Original file line number Diff line number Diff line change @@ -204,7 +204,7 @@ fn install_one(
204
204
let mut needs_cleanup = false ;
205
205
let overidden_target_dir = if source_id. is_path ( ) {
206
206
None
207
- } else if let Some ( dir) = config. target_dir ( ) ? {
207
+ } else if let Some ( dir) = config. target_dir ( pkg . manifest_path ( ) ) ? {
208
208
Some ( dir)
209
209
} else if let Ok ( td) = TempFileBuilder :: new ( ) . prefix ( "cargo-install" ) . tempdir ( ) {
210
210
let p = td. path ( ) . to_owned ( ) ;
Original file line number Diff line number Diff line change @@ -315,11 +315,26 @@ impl Config {
315
315
& self . cwd
316
316
}
317
317
318
- pub fn target_dir ( & self ) -> CargoResult < Option < Filesystem > > {
318
+ pub fn target_dir ( & self , manifest : impl Into < PathBuf > ) -> CargoResult < Option < Filesystem > > {
319
319
if let Some ( ref dir) = self . target_dir {
320
320
Ok ( Some ( dir. clone ( ) ) )
321
321
} else if let Some ( dir) = env:: var_os ( "CARGO_TARGET_DIR" ) {
322
322
Ok ( Some ( Filesystem :: new ( self . cwd . join ( dir) ) ) )
323
+ } else if let Some ( dir) = env:: var_os ( "CARGO_TARGET_DIR_PREFIX" ) {
324
+ let prefix = Path :: new ( & dir) ;
325
+ if !prefix. is_absolute ( ) {
326
+ failure:: bail!( "CARGO_TARGET_DIR_PREFIX must describe an absolute path" ) ;
327
+ }
328
+ let mut manifest = manifest. into ( ) ;
329
+ let result = manifest. pop ( ) ;
330
+ assert ! ( result) ;
331
+
332
+ match manifest. strip_prefix ( "/" ) {
333
+ Ok ( dir) => Ok ( Some ( Filesystem :: new ( prefix. join ( & dir) . join ( "target" ) ) ) ) ,
334
+ // FIXME: This logic is probably not safe on Windows. Not sure how
335
+ // to make a path relative there.
336
+ Err ( _) => failure:: bail!( "Current directory must be an absolute path" ) ,
337
+ }
323
338
} else if let Some ( val) = self . get_path ( "build.target-dir" ) ? {
324
339
let val = self . cwd . join ( val. val ) ;
325
340
Ok ( Some ( Filesystem :: new ( val) ) )
Original file line number Diff line number Diff line change @@ -13,6 +13,10 @@ system:
13
13
checkouts of crates. By default these are stored under ` $HOME/.cargo ` , but
14
14
this variable overrides the location of this directory. Once a crate is cached
15
15
it is not removed by the clean command.
16
+ * ` CARGO_TARGET_DIR_PREFIX ` — Prefix to the location where to place all
17
+ generated artifacts. The current working directory will be appended to this
18
+ prefix to form the final path for generated artifacts. Note that
19
+ ` CARGO_TARGET_DIR ` , if set, takes precedence over this variable.
16
20
* ` CARGO_TARGET_DIR ` — Location of where to place all generated artifacts,
17
21
relative to the current working directory.
18
22
* ` RUSTC ` — Instead of running ` rustc ` , Cargo will execute this specified
Original file line number Diff line number Diff line change @@ -3017,6 +3017,63 @@ fn explicit_color_config_is_propagated_to_rustc() {
3017
3017
. run ( ) ;
3018
3018
}
3019
3019
3020
+ #[ test]
3021
+ fn custom_target_dir_prefix ( ) {
3022
+ fn test ( cwd : & str ) {
3023
+ let tmpdir = tempfile:: Builder :: new ( )
3024
+ . tempdir ( )
3025
+ . unwrap ( )
3026
+ . path ( )
3027
+ . to_path_buf ( ) ;
3028
+
3029
+ let p = project ( )
3030
+ . file (
3031
+ "Cargo.toml" ,
3032
+ r#"
3033
+ [package]
3034
+ name = "foo"
3035
+ version = "0.0.1"
3036
+ authors = []
3037
+ "# ,
3038
+ )
3039
+ . file ( "src/main.rs" , "fn main() {}" )
3040
+ . build ( ) ;
3041
+
3042
+ let root = p. root ( ) ;
3043
+ let root_suffix = root. strip_prefix ( "/" ) . unwrap ( ) ;
3044
+ let exe_name = format ! ( "foo{}" , env:: consts:: EXE_SUFFIX ) ;
3045
+
3046
+ p. cargo ( "build" )
3047
+ . env ( "CARGO_TARGET_DIR_PREFIX" , tmpdir. clone ( ) )
3048
+ . cwd ( p. root ( ) . join ( cwd) )
3049
+ . run ( ) ;
3050
+
3051
+ assert ! (
3052
+ tmpdir
3053
+ . clone( )
3054
+ . join( root_suffix)
3055
+ . join( "target/debug" )
3056
+ . join( & exe_name)
3057
+ . is_file( )
3058
+ ) ;
3059
+ assert ! ( !& p. root( ) . join( "target/debug" ) . join( & exe_name) . is_file( ) ) ;
3060
+
3061
+ p. cargo ( "build" ) . run ( ) ;
3062
+ assert ! (
3063
+ tmpdir
3064
+ . clone( )
3065
+ . join( root_suffix)
3066
+ . join( "target/debug" )
3067
+ . join( & exe_name)
3068
+ . is_file( )
3069
+ ) ;
3070
+ assert ! ( & p. root( ) . join( "target/debug" ) . join( & exe_name) . is_file( ) )
3071
+ } ;
3072
+
3073
+ test ( "." ) ;
3074
+ test ( "src" ) ;
3075
+ }
3076
+
3020
3077
#[ test]
3021
3078
fn compiler_json_error_format ( ) {
3022
3079
let p = project ( )
Original file line number Diff line number Diff line change @@ -1688,6 +1688,7 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
1688
1688
. env_remove ( "GIT_AUTHOR_EMAIL" )
1689
1689
. env_remove ( "GIT_COMMITTER_NAME" )
1690
1690
. env_remove ( "GIT_COMMITTER_EMAIL" )
1691
+ . env_remove ( "CARGO_TARGET_DIR_PREFIX" ) // we assume no prefix
1691
1692
. env_remove ( "CARGO_TARGET_DIR" ) // we assume 'target'
1692
1693
. env_remove ( "MSYSTEM" ) ; // assume cmd.exe everywhere on windows
1693
1694
p
You can’t perform that action at this time.
0 commit comments