66import rustc:: syntax:: { ast, codemap} ;
77import rustc:: syntax:: parse:: parser;
88import rustc:: util:: filesearch:: { get_cargo_root, get_cargo_root_nearest,
9- get_cargo_sysroot} ;
9+ get_cargo_sysroot, libdir } ;
1010import rustc:: driver:: diagnostic;
1111
1212import std:: fs;
@@ -346,39 +346,35 @@ fn build_cargo_options(argv: [str]) -> options {
346346 } ;
347347
348348 let test = opt_present ( match , "test" ) ;
349- let mode = if opt_present ( match , "G" ) {
350- if opt_present( match , "mode" ) { fail "--mode and -G both provided" ; }
351- if opt_present( match, "g" ) { fail "-G and -g both provided" ; }
352- system_mode
353- } else if opt_present( match , "g" ) {
354- if opt_present( match, "mode" ) { fail "--mode and -g both provided" ; }
355- if opt_present( match, "G" ) { fail "-G and -g both provided" ; }
356- user_mode
357- } else if opt_present ( match , "mode" ) {
358- alt getopts:: opt_str( match, "mode" ) {
359- "system" { system_mode }
360- "user" { user_mode }
361- "local" { local_mode }
362- _ { fail "argument to `mode` must be one of `system`" +
363- ", `user`, or `normal`" ;
349+ let G = opt_present ( match , "G" ) ;
350+ let g = opt_present ( match , "g" ) ;
351+ let m = opt_present ( match , "mode" ) ;
352+ let is_install = vec:: len( match . free) > 1 u && match . free[ 1 ] == "install" ;
353+
354+ if G && g { fail "-G and -g both provided" ; }
355+ if g && m { fail "--mode and -g both provided" ; }
356+ if G && m { fail "--mode and -G both provided" ; }
357+
358+ let mode = if is_install {
359+ if G { system_mode }
360+ else if g { user_mode }
361+ else if m {
362+ alt getopts:: opt_str ( match , "mode" ) {
363+ "system" { system_mode }
364+ "user" { user_mode }
365+ "local" { local_mode }
366+ _ { fail "argument to `mode` must be one of `system`" +
367+ ", `user`, or `local`" ;
368+ }
364369 }
365- }
366- } else {
367- local_mode
368- } ;
369-
370- if mode == system_mode {
371- // FIXME: Per discussion on #1760, we need to think about how
372- // system mode works. It should install files to the normal
373- // sysroot paths, but it also needsd an area to place various
374- // cargo configuration and work files.
375- fail "system mode does not exist yet" ;
376- }
370+ } else { local_mode }
371+ } else { system_mode } ;
377372
378373 { test: test, mode: mode, free: match . free}
379374}
380375
381376fn configure ( opts : options ) -> cargo {
377+ let syscargo = result:: get ( get_cargo_sysroot ( ) ) ;
382378 let get_cargo_dir = alt opts. mode {
383379 system_mode { get_cargo_sysroot }
384380 user_mode { get_cargo_root }
@@ -391,15 +387,15 @@ fn configure(opts: options) -> cargo {
391387 } ;
392388
393389 let sources = map:: new_str_hash :: < source > ( ) ;
394- try_parse_sources ( fs:: connect ( p , "sources.json" ) , sources) ;
395- try_parse_sources ( fs:: connect ( p , "local-sources.json" ) , sources) ;
390+ try_parse_sources ( fs:: connect ( syscargo , "sources.json" ) , sources) ;
391+ try_parse_sources ( fs:: connect ( syscargo , "local-sources.json" ) , sources) ;
396392 let c = {
397393 pgp: pgp:: supported ( ) ,
398394 root: p,
399395 bindir: fs:: connect ( p, "bin" ) ,
400396 libdir: fs:: connect ( p, "lib" ) ,
401397 workdir: fs:: connect ( p, "work" ) ,
402- sourcedir: fs:: connect ( p , "sources" ) ,
398+ sourcedir: fs:: connect ( syscargo , "sources" ) ,
403399 sources: sources,
404400 opts: opts
405401 } ;
@@ -471,10 +467,31 @@ fn install_one_crate(c: cargo, _path: str, cf: str, _p: pkg) {
471467 #debug ( " bin: %s" , ct) ;
472468 // FIXME: need libstd fs::copy or something
473469 run:: run_program ( "cp" , [ ct, c. bindir ] ) ;
470+ if c. opts . mode == system_mode {
471+ install_one_crate_to_sysroot ( ct, "bin" ) ;
472+ }
474473 } else {
475474 #debug ( " lib: %s" , ct) ;
476475 run:: run_program ( "cp" , [ ct, c. libdir ] ) ;
476+ if c. opts . mode == system_mode {
477+ install_one_crate_to_sysroot ( ct, libdir ( ) ) ;
478+ }
479+ }
480+ }
481+ }
482+
483+ fn install_one_crate_to_sysroot ( ct : str , target : str ) {
484+ alt os:: get_exe_path ( ) {
485+ some ( _path) {
486+ let path = [ _path, ".." , target] ;
487+ check vec:: is_not_empty ( path) ;
488+ let target_dir = fs:: normalize ( fs:: connect_many ( path) ) ;
489+ let p = run:: program_output ( "cp" , [ ct, target_dir] ) ;
490+ if p. status != 0 {
491+ warn ( #fmt[ "Copying %s to %s is failed" , ct, target_dir] ) ;
492+ }
477493 }
494+ none { }
478495 }
479496}
480497
@@ -831,23 +848,25 @@ fn cmd_usage() {
831848 "
832849
833850 init Set up .cargo
834- install [--test ] [source/]package-name Install by name
835- install [--test ] uuid:[source/]package-uuid Install by uuid
851+ install [options ] [source/]package-name Install by name
852+ install [options ] uuid:[source/]package-uuid Install by uuid
836853 list [source] List packages
837854 search <name | '*'> [tags...] Search packages
838855 sync Sync all sources
839856 usage This
840857
841858Options:
842859
860+ cargo install
861+
843862 --mode=[system,user,local] change mode as (system/user/local)
844863 -g equivalent to --mode=user
845864 -G equivalent to --mode=system
846865
847866NOTE:
848- This command creates/uses local-level .cargo by default.
849- To create/use user-level .cargo, use option -g/--mode=user.
850- To create/use system-level .cargo , use option -G/--mode=system.
867+ \" cargo install \" installs bin/libs to local-level .cargo by default.
868+ To install them into user-level .cargo, use option -g/--mode=user.
869+ To install them into bin/lib on sysroot , use option -G/--mode=system.
851870" ) ;
852871}
853872
0 commit comments