5
5
6
6
use std:: env;
7
7
use std:: fs;
8
- use std:: path:: { Component , Path , PathBuf } ;
8
+ use std:: path:: { Component , PathBuf } ;
9
9
use std:: process:: Command ;
10
10
11
11
use build_helper:: t;
@@ -26,74 +26,63 @@ fn install_sh(
26
26
) {
27
27
builder. info ( & format ! ( "Install {} stage{} ({:?})" , package, stage, host) ) ;
28
28
29
- let prefix_default = PathBuf :: from ( "/usr/local" ) ;
30
- let sysconfdir_default = PathBuf :: from ( "/etc" ) ;
31
- let datadir_default = PathBuf :: from ( "share" ) ;
32
- let docdir_default = datadir_default. join ( "doc/rust" ) ;
33
- let libdir_default = PathBuf :: from ( "lib" ) ;
34
- let mandir_default = datadir_default. join ( "man" ) ;
35
- let prefix = builder. config . prefix . as_ref ( ) . unwrap_or ( & prefix_default) ;
36
- let sysconfdir = builder. config . sysconfdir . as_ref ( ) . unwrap_or ( & sysconfdir_default) ;
37
- let datadir = builder. config . datadir . as_ref ( ) . unwrap_or ( & datadir_default) ;
38
- let docdir = builder. config . docdir . as_ref ( ) . unwrap_or ( & docdir_default) ;
39
- let bindir = & builder. config . bindir ;
40
- let libdir = builder. config . libdir . as_ref ( ) . unwrap_or ( & libdir_default) ;
41
- let mandir = builder. config . mandir . as_ref ( ) . unwrap_or ( & mandir_default) ;
42
-
43
- let sysconfdir = prefix. join ( sysconfdir) ;
44
- let datadir = prefix. join ( datadir) ;
45
- let docdir = prefix. join ( docdir) ;
46
- let bindir = prefix. join ( bindir) ;
47
- let libdir = prefix. join ( libdir) ;
48
- let mandir = prefix. join ( mandir) ;
49
-
50
- let destdir = env:: var_os ( "DESTDIR" ) . map ( PathBuf :: from) ;
51
-
52
- let prefix = add_destdir ( & prefix, & destdir) ;
53
- let sysconfdir = add_destdir ( & sysconfdir, & destdir) ;
54
- let datadir = add_destdir ( & datadir, & destdir) ;
55
- let docdir = add_destdir ( & docdir, & destdir) ;
56
- let bindir = add_destdir ( & bindir, & destdir) ;
57
- let libdir = add_destdir ( & libdir, & destdir) ;
58
- let mandir = add_destdir ( & mandir, & destdir) ;
59
-
60
- let prefix = {
61
- fs:: create_dir_all ( & prefix)
62
- . unwrap_or_else ( |err| panic ! ( "could not create {}: {}" , prefix. display( ) , err) ) ;
63
- fs:: canonicalize ( & prefix)
64
- . unwrap_or_else ( |err| panic ! ( "could not canonicalize {}: {}" , prefix. display( ) , err) )
65
- } ;
29
+ let prefix = default_path ( & builder. config . prefix , "/usr/local" ) ;
30
+ let sysconfdir = prefix. join ( default_path ( & builder. config . sysconfdir , "/etc" ) ) ;
31
+ let datadir = prefix. join ( default_path ( & builder. config . datadir , "share" ) ) ;
32
+ let docdir = prefix. join ( default_path ( & builder. config . docdir , "share/doc" ) ) ;
33
+ let mandir = prefix. join ( default_path ( & builder. config . mandir , "share/man" ) ) ;
34
+ let libdir = prefix. join ( default_path ( & builder. config . libdir , "lib" ) ) ;
35
+ let bindir = prefix. join ( & builder. config . bindir ) ; // Default in config.rs
66
36
67
37
let empty_dir = builder. out . join ( "tmp/empty_dir" ) ;
68
-
69
38
t ! ( fs:: create_dir_all( & empty_dir) ) ;
70
39
71
40
let mut cmd = Command :: new ( "sh" ) ;
72
41
cmd. current_dir ( & empty_dir)
73
42
. arg ( sanitize_sh ( & tarball. decompressed_output ( ) . join ( "install.sh" ) ) )
74
- . arg ( format ! ( "--prefix={}" , sanitize_sh ( & prefix) ) )
75
- . arg ( format ! ( "--sysconfdir={}" , sanitize_sh ( & sysconfdir) ) )
76
- . arg ( format ! ( "--datadir={}" , sanitize_sh ( & datadir) ) )
77
- . arg ( format ! ( "--docdir={}" , sanitize_sh ( & docdir) ) )
78
- . arg ( format ! ( "--bindir={}" , sanitize_sh ( & bindir) ) )
79
- . arg ( format ! ( "--libdir={}" , sanitize_sh ( & libdir) ) )
80
- . arg ( format ! ( "--mandir={}" , sanitize_sh ( & mandir) ) )
43
+ . arg ( format ! ( "--prefix={}" , prepare_dir ( prefix) ) )
44
+ . arg ( format ! ( "--sysconfdir={}" , prepare_dir ( sysconfdir) ) )
45
+ . arg ( format ! ( "--datadir={}" , prepare_dir ( datadir) ) )
46
+ . arg ( format ! ( "--docdir={}" , prepare_dir ( docdir) ) )
47
+ . arg ( format ! ( "--bindir={}" , prepare_dir ( bindir) ) )
48
+ . arg ( format ! ( "--libdir={}" , prepare_dir ( libdir) ) )
49
+ . arg ( format ! ( "--mandir={}" , prepare_dir ( mandir) ) )
81
50
. arg ( "--disable-ldconfig" ) ;
82
51
builder. run ( & mut cmd) ;
83
52
t ! ( fs:: remove_dir_all( & empty_dir) ) ;
84
53
}
85
54
86
- fn add_destdir ( path : & Path , destdir : & Option < PathBuf > ) -> PathBuf {
87
- let mut ret = match * destdir {
88
- Some ( ref dest) => dest. clone ( ) ,
89
- None => return path. to_path_buf ( ) ,
90
- } ;
91
- for part in path. components ( ) {
92
- if let Component :: Normal ( s) = part {
93
- ret. push ( s)
55
+ fn default_path ( config : & Option < PathBuf > , default : & str ) -> PathBuf {
56
+ PathBuf :: from ( config. as_ref ( ) . cloned ( ) . unwrap_or_else ( || PathBuf :: from ( default) ) )
57
+ }
58
+
59
+ fn prepare_dir ( mut path : PathBuf ) -> String {
60
+ // The DESTDIR environment variable is a standard way to install software in a subdirectory
61
+ // while keeping the original directory structure, even if the prefix or other directories
62
+ // contain absolute paths.
63
+ //
64
+ // More information on the environment variable is available here:
65
+ // https://www.gnu.org/prep/standards/html_node/DESTDIR.html
66
+ if let Some ( destdir) = env:: var_os ( "DESTDIR" ) . map ( PathBuf :: from) {
67
+ let without_destdir = path. clone ( ) ;
68
+ path = destdir;
69
+ // Custom .join() which ignores disk roots.
70
+ for part in without_destdir. components ( ) {
71
+ if let Component :: Normal ( s) = part {
72
+ path. push ( s)
73
+ }
94
74
}
95
75
}
96
- ret
76
+
77
+ // The installation command is not executed from the current directory, but from a temporary
78
+ // directory. To prevent relative paths from breaking this converts relative paths to absolute
79
+ // paths. std::fs::canonicalize is not used as that requires the path to actually be present.
80
+ if path. is_relative ( ) {
81
+ path = std:: env:: current_dir ( ) . expect ( "failed to get the current directory" ) . join ( path) ;
82
+ assert ! ( path. is_absolute( ) , "could not make the path relative" ) ;
83
+ }
84
+
85
+ sanitize_sh ( & path)
97
86
}
98
87
99
88
macro_rules! install {
0 commit comments