]>
Commit | Line | Data |
---|---|---|
54a0048b SL |
1 | // Copyright 2014 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. | |
4 | // | |
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. | |
10 | ||
a7813a04 | 11 | use rustc::middle::cstore::LOCAL_CRATE; |
5bcae85e | 12 | use rustc::session::Session; |
a7813a04 XL |
13 | use rustc::ty::TyCtxt; |
14 | ||
54a0048b | 15 | use std::fs; |
a7813a04 XL |
16 | use std::io; |
17 | use std::path::{Path, PathBuf}; | |
18 | use syntax::ast; | |
19 | ||
20 | pub fn dep_graph_path(tcx: TyCtxt) -> Option<PathBuf> { | |
5bcae85e | 21 | tcx_path(tcx, LOCAL_CRATE, "local") |
a7813a04 | 22 | } |
54a0048b | 23 | |
a7813a04 | 24 | pub fn metadata_hash_path(tcx: TyCtxt, cnum: ast::CrateNum) -> Option<PathBuf> { |
5bcae85e | 25 | tcx_path(tcx, cnum, "metadata") |
a7813a04 XL |
26 | } |
27 | ||
5bcae85e SL |
28 | pub fn tcx_work_products_path(tcx: TyCtxt) -> Option<PathBuf> { |
29 | let crate_name = tcx.crate_name(LOCAL_CRATE); | |
30 | sess_work_products_path(tcx.sess, &crate_name) | |
31 | } | |
32 | ||
33 | pub fn sess_work_products_path(sess: &Session, | |
34 | local_crate_name: &str) | |
35 | -> Option<PathBuf> { | |
36 | let crate_disambiguator = sess.local_crate_disambiguator(); | |
37 | path(sess, local_crate_name, &crate_disambiguator, "work-products") | |
38 | } | |
39 | ||
40 | pub fn in_incr_comp_dir(sess: &Session, file_name: &str) -> Option<PathBuf> { | |
41 | sess.opts.incremental.as_ref().map(|incr_dir| incr_dir.join(file_name)) | |
42 | } | |
43 | ||
44 | fn tcx_path(tcx: TyCtxt, | |
45 | cnum: ast::CrateNum, | |
46 | middle: &str) | |
47 | -> Option<PathBuf> { | |
48 | path(tcx.sess, &tcx.crate_name(cnum), &tcx.crate_disambiguator(cnum), middle) | |
49 | } | |
50 | ||
51 | fn path(sess: &Session, | |
52 | crate_name: &str, | |
53 | crate_disambiguator: &str, | |
54 | middle: &str) | |
55 | -> Option<PathBuf> { | |
54a0048b SL |
56 | // For now, just save/load dep-graph from |
57 | // directory/dep_graph.rbml | |
5bcae85e | 58 | sess.opts.incremental.as_ref().and_then(|incr_dir| { |
a7813a04 | 59 | match create_dir_racy(&incr_dir) { |
54a0048b SL |
60 | Ok(()) => {} |
61 | Err(err) => { | |
5bcae85e | 62 | sess.err( |
54a0048b SL |
63 | &format!("could not create the directory `{}`: {}", |
64 | incr_dir.display(), err)); | |
65 | return None; | |
66 | } | |
67 | } | |
68 | ||
5bcae85e SL |
69 | let file_name = format!("{}-{}.{}.bin", crate_name, crate_disambiguator, middle); |
70 | ||
a7813a04 | 71 | Some(incr_dir.join(file_name)) |
54a0048b SL |
72 | }) |
73 | } | |
74 | ||
a7813a04 XL |
75 | // Like std::fs::create_dir_all, except handles concurrent calls among multiple |
76 | // threads or processes. | |
77 | fn create_dir_racy(path: &Path) -> io::Result<()> { | |
78 | match fs::create_dir(path) { | |
79 | Ok(()) => return Ok(()), | |
80 | Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return Ok(()), | |
81 | Err(ref e) if e.kind() == io::ErrorKind::NotFound => {} | |
82 | Err(e) => return Err(e), | |
83 | } | |
84 | match path.parent() { | |
85 | Some(p) => try!(create_dir_racy(p)), | |
86 | None => return Err(io::Error::new(io::ErrorKind::Other, | |
87 | "failed to create whole tree")), | |
88 | } | |
89 | match fs::create_dir(path) { | |
90 | Ok(()) => Ok(()), | |
91 | Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()), | |
92 | Err(e) => Err(e), | |
93 | } | |
94 | } | |
95 |