@@ -309,49 +309,55 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
309309
310310 /// Get the metadata for a target in a specific profile
311311 pub fn target_metadata ( & self , unit : & Unit ) -> Option < Metadata > {
312- let metadata = unit. target . metadata ( ) ;
312+ // No metadata for dylibs because of a couple issues
313+ // - OSX encodes the dylib name in the executable
314+ // - Windows rustc multiple files of which we can't easily link all of them
315+ if !unit. profile . test && unit. target . is_dylib ( ) {
316+ return None ;
317+ }
318+
319+ let metadata = unit. target . metadata ( ) . cloned ( ) . map ( |mut m| {
320+ if let Some ( features) = self . resolve . features ( unit. pkg . package_id ( ) ) {
321+ let mut feat_vec: Vec < & String > = features. iter ( ) . collect ( ) ;
322+ feat_vec. sort ( ) ;
323+ for feat in feat_vec {
324+ m. mix ( feat) ;
325+ }
326+ }
327+ m. mix ( unit. profile ) ;
328+ m
329+ } ) ;
330+ let mut pkg_metadata = {
331+ let mut m = unit. pkg . generate_metadata ( ) ;
332+ if let Some ( features) = self . resolve . features ( unit. pkg . package_id ( ) ) {
333+ let mut feat_vec: Vec < & String > = features. iter ( ) . collect ( ) ;
334+ feat_vec. sort ( ) ;
335+ for feat in feat_vec {
336+ m. mix ( feat) ;
337+ }
338+ }
339+ m. mix ( unit. profile ) ;
340+ m
341+ } ;
342+
313343 if unit. target . is_lib ( ) && unit. profile . test {
314344 // Libs and their tests are built in parallel, so we need to make
315345 // sure that their metadata is different.
316- metadata. cloned ( ) . map ( |mut m| {
346+ metadata. map ( |mut m| {
317347 m. mix ( & "test" ) ;
318348 m
319349 } )
320350 } else if unit. target . is_bin ( ) && unit. profile . test {
321351 // Make sure that the name of this test executable doesn't
322352 // conflict with a library that has the same name and is
323353 // being tested
324- let mut metadata = unit. pkg . generate_metadata ( ) ;
325- metadata. mix ( & format ! ( "bin-{}" , unit. target. name( ) ) ) ;
326- Some ( metadata)
354+ pkg_metadata. mix ( & format ! ( "bin-{}" , unit. target. name( ) ) ) ;
355+ Some ( pkg_metadata)
327356 } else if unit. pkg . package_id ( ) . source_id ( ) . is_path ( ) &&
328357 !unit. profile . test {
329- // If we're not building a unit test but we're building a path
330- // dependency, then we're likely compiling the "current package" or
331- // some package in a workspace. In this situation we pass no
332- // metadata by default so we'll have predictable
333- // file names like `target/debug/libfoo.{a,so,rlib}` and such.
334- //
335- // Note, though, that the compiler's build system at least wants
336- // path dependencies to have hashes in filenames. To account for
337- // that we have an extra hack here which reads the
338- // `__CARGO_DEFAULT_METADATA` environment variable and creates a
339- // hash in the filename if that's present.
340- //
341- // This environment variable should not be relied on! It's basically
342- // just here for rustbuild. We need a more principled method of
343- // doing this eventually.
344- if unit. target . is_lib ( ) {
345- env:: var ( "__CARGO_DEFAULT_LIB_METADATA" ) . ok ( ) . map ( |meta| {
346- let mut metadata = unit. pkg . generate_metadata ( ) ;
347- metadata. mix ( & meta) ;
348- metadata
349- } )
350- } else {
351- None
352- }
358+ Some ( pkg_metadata)
353359 } else {
354- metadata. cloned ( )
360+ metadata
355361 }
356362 }
357363
@@ -360,19 +366,57 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
360366 match self . target_metadata ( unit) {
361367 Some ( ref metadata) => format ! ( "{}{}" , unit. target. crate_name( ) ,
362368 metadata. extra_filename) ,
363- None if unit. target . allows_underscores ( ) => {
364- unit. target . name ( ) . to_string ( )
369+ None => self . bin_stem ( unit) ,
370+ }
371+ }
372+
373+ fn bin_stem ( & self , unit : & Unit ) -> String {
374+ if unit. target . allows_underscores ( ) {
375+ unit. target . name ( ) . to_string ( )
376+ } else {
377+ unit. target . crate_name ( )
378+ }
379+ }
380+
381+ pub fn link_stem ( & self , unit : & Unit ) -> Option < ( PathBuf , String ) > {
382+ let src_dir = self . out_dir ( unit) ;
383+ let bin_stem = self . bin_stem ( unit) ;
384+ let file_stem = self . file_stem ( unit) ;
385+
386+ // We currently only lift files up from the `deps` directory. If
387+ // it was compiled into something like `example/` or `doc/` then
388+ // we don't want to link it up.
389+ if src_dir. ends_with ( "deps" ) {
390+ // Don't lift up library dependencies
391+ if unit. pkg . package_id ( ) != & self . current_package && !unit. target . is_bin ( ) {
392+ None
393+ } else {
394+ Some ( (
395+ src_dir. parent ( ) . unwrap ( ) . to_owned ( ) ,
396+ if unit. profile . test { file_stem} else { bin_stem} ,
397+ ) )
365398 }
366- None => unit. target . crate_name ( ) ,
399+ } else if bin_stem == file_stem {
400+ None
401+ } else if src_dir. ends_with ( "examples" ) {
402+ Some ( ( src_dir, bin_stem) )
403+ } else if src_dir. parent ( ) . unwrap ( ) . ends_with ( "build" ) {
404+ Some ( ( src_dir, bin_stem) )
405+ } else {
406+ None
367407 }
368408 }
369409
370410 /// Return the filenames that the given target for the given profile will
371- /// generate, along with whether you can link against that file (e.g. it's a
372- /// library).
411+ /// generate as a list of 3-tuples (filename, link_dst, linkable)
412+ /// filename: filename rustc compiles to. (Often has metadata suffix).
413+ /// link_dst: Optional file to link/copy the result to (without metadata suffix)
414+ /// linkable: Whether possible to link against file (eg it's a library)
373415 pub fn target_filenames ( & self , unit : & Unit )
374- -> CargoResult < Vec < ( String , bool ) > > {
416+ -> CargoResult < Vec < ( PathBuf , Option < PathBuf > , bool ) > > {
417+ let out_dir = self . out_dir ( unit) ;
375418 let stem = self . file_stem ( unit) ;
419+ let link_stem = self . link_stem ( unit) ;
376420 let info = if unit. target . for_host ( ) {
377421 & self . host_info
378422 } else {
@@ -386,8 +430,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
386430 let crate_type = if crate_type == "lib" { "rlib" } else { crate_type} ;
387431 match info. crate_types . get ( crate_type) {
388432 Some ( & Some ( ( ref prefix, ref suffix) ) ) => {
389- ret. push ( ( format ! ( "{}{}{}" , prefix, stem, suffix) ,
390- linkable) ) ;
433+ let filename = out_dir. join ( format ! ( "{}{}{}" , prefix, stem, suffix) ) ;
434+ let link_dst = link_stem. clone ( ) . map ( |( ld, ls) | {
435+ ld. join ( format ! ( "{}{}{}" , prefix, ls, suffix) )
436+ } ) ;
437+ ret. push ( ( filename, link_dst, linkable) ) ;
391438 Ok ( ( ) )
392439 }
393440 // not supported, don't worry about it
@@ -429,6 +476,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
429476 support any of the output crate types",
430477 unit. pkg, self . target_triple( ) ) ;
431478 }
479+ info ! ( "Target filenames: {:?}" , ret) ;
432480 Ok ( ret)
433481 }
434482
0 commit comments