]>
git.proxmox.com Git - rustc.git/blob - src/bootstrap/util.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Various utility functions used throughout rustbuild.
13 //! Simple things like testing the various filesystem operations here and there,
14 //! not a lot of interesting happenings here unfortunately.
17 use std
::ffi
::OsString
;
19 use std
::path
::{Path, PathBuf}
;
20 use std
::process
::Command
;
22 use filetime
::FileTime
;
24 /// Returns the `name` as the filename of a static library for `target`.
25 pub fn staticlib(name
: &str, target
: &str) -> String
{
26 if target
.contains("windows-msvc") {
27 format
!("{}.lib", name
)
29 format
!("lib{}.a", name
)
33 /// Returns the last-modified time for `path`, or zero if it doesn't exist.
34 pub fn mtime(path
: &Path
) -> FileTime
{
35 fs
::metadata(path
).map(|f
| {
36 FileTime
::from_last_modification_time(&f
)
37 }).unwrap_or(FileTime
::zero())
40 /// Copies a file from `src` to `dst`, attempting to use hard links and then
41 /// falling back to an actually filesystem copy if necessary.
42 pub fn copy(src
: &Path
, dst
: &Path
) {
43 let res
= fs
::hard_link(src
, dst
);
44 let res
= res
.or_else(|_
| fs
::copy(src
, dst
).map(|_
| ()));
46 panic
!("failed to copy `{}` to `{}`: {}", src
.display(),
51 /// Copies the `src` directory recursively to `dst`. Both are assumed to exist
52 /// when this function is called.
53 pub fn cp_r(src
: &Path
, dst
: &Path
) {
54 for f
in t
!(fs
::read_dir(src
)) {
57 let name
= path
.file_name().unwrap();
58 let dst
= dst
.join(name
);
59 if t
!(f
.file_type()).is_dir() {
60 let _
= fs
::remove_dir_all(&dst
);
61 t
!(fs
::create_dir(&dst
));
64 let _
= fs
::remove_file(&dst
);
70 /// Copies the `src` directory recursively to `dst`. Both are assumed to exist
71 /// when this function is called. Unwanted files or directories can be skipped
72 /// by returning `false` from the filter function.
73 pub fn cp_filtered
<F
: Fn(&Path
) -> bool
>(src
: &Path
, dst
: &Path
, filter
: &F
) {
74 // Inner function does the actual work
75 fn recurse
<F
: Fn(&Path
) -> bool
>(src
: &Path
, dst
: &Path
, relative
: &Path
, filter
: &F
) {
76 for f
in t
!(fs
::read_dir(src
)) {
79 let name
= path
.file_name().unwrap();
80 let dst
= dst
.join(name
);
81 let relative
= relative
.join(name
);
82 // Only copy file or directory if the filter function returns true
83 if filter(&relative
) {
84 if t
!(f
.file_type()).is_dir() {
85 let _
= fs
::remove_dir_all(&dst
);
86 t
!(fs
::create_dir(&dst
));
87 recurse(&path
, &dst
, &relative
, filter
);
89 let _
= fs
::remove_file(&dst
);
95 // Immediately recurse with an empty relative path
96 recurse(src
, dst
, Path
::new(""), filter
)
99 /// Given an executable called `name`, return the filename for the
100 /// executable for a particular target.
101 pub fn exe(name
: &str, target
: &str) -> String
{
102 if target
.contains("windows") {
103 format
!("{}.exe", name
)
109 /// Returns whether the file name given looks like a dynamic library.
110 pub fn is_dylib(name
: &str) -> bool
{
111 name
.ends_with(".dylib") || name
.ends_with(".so") || name
.ends_with(".dll")
114 /// Returns the corresponding relative library directory that the compiler's
115 /// dylibs will be found in.
116 pub fn libdir(target
: &str) -> &'
static str {
117 if target
.contains("windows") {"bin"}
else {"lib"}
120 /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
121 pub fn add_lib_path(path
: Vec
<PathBuf
>, cmd
: &mut Command
) {
122 let mut list
= dylib_path();
124 list
.insert(0, path
);
126 cmd
.env(dylib_path_var(), t
!(env
::join_paths(list
)));
129 /// Returns whether `dst` is up to date given that the file or files in `src`
130 /// are used to generate it.
132 /// Uses last-modified time checks to verify this.
133 pub fn up_to_date(src
: &Path
, dst
: &Path
) -> bool
{
134 let threshold
= mtime(dst
);
135 let meta
= match fs
::metadata(src
) {
137 Err(e
) => panic
!("source {:?} failed to get metadata: {}", src
, e
),
140 dir_up_to_date(src
, &threshold
)
142 FileTime
::from_last_modification_time(&meta
) <= threshold
146 fn dir_up_to_date(src
: &Path
, threshold
: &FileTime
) -> bool
{
147 t
!(fs
::read_dir(src
)).map(|e
| t
!(e
)).all(|e
| {
148 let meta
= t
!(e
.metadata());
150 dir_up_to_date(&e
.path(), threshold
)
152 FileTime
::from_last_modification_time(&meta
) < *threshold
157 /// Returns the environment variable which the dynamic library lookup path
158 /// resides in for this platform.
159 pub fn dylib_path_var() -> &'
static str {
160 if cfg
!(target_os
= "windows") {
162 } else if cfg
!(target_os
= "macos") {
169 /// Parses the `dylib_path_var()` environment variable, returning a list of
170 /// paths that are members of this lookup path.
171 pub fn dylib_path() -> Vec
<PathBuf
> {
172 env
::split_paths(&env
::var_os(dylib_path_var()).unwrap_or(OsString
::new()))