Skip to content

Commit

Permalink
Add --dep-info to write Makefile-compatible dependency info.
Browse files Browse the repository at this point in the history
When --dep-info is given, rustc will write out a `$input_base.d` file in the
output directory that contains Makefile compatible dependency information for
use with tools like make and ninja.
  • Loading branch information
metajack committed Dec 12, 2013
1 parent 5bd4d2e commit 9365375
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 8 deletions.
12 changes: 9 additions & 3 deletions src/librustc/back/link.rs
Expand Up @@ -720,7 +720,7 @@ pub fn link_binary(sess: Session,
trans: &CrateTranslation,
obj_filename: &Path,
out_filename: &Path,
lm: &LinkMeta) {
lm: &LinkMeta) -> ~[Path] {
// If we're generating a test executable, then ignore all other output
// styles at all other locations
let outputs = if sess.opts.test {
Expand All @@ -729,15 +729,19 @@ pub fn link_binary(sess: Session,
(*sess.outputs).clone()
};

let mut out_filenames = ~[];
for output in outputs.move_iter() {
link_binary_output(sess, trans, output, obj_filename, out_filename, lm);
let out_file = link_binary_output(sess, trans, output, obj_filename, out_filename, lm);
out_filenames.push(out_file);
}

// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.save_temps {
fs::unlink(obj_filename);
fs::unlink(&obj_filename.with_extension("metadata.o"));
}

out_filenames
}

fn is_writeable(p: &Path) -> bool {
Expand All @@ -754,7 +758,7 @@ fn link_binary_output(sess: Session,
output: session::OutputStyle,
obj_filename: &Path,
out_filename: &Path,
lm: &LinkMeta) {
lm: &LinkMeta) -> Path {
let libname = output_lib_filename(lm);
let out_filename = match output {
session::OutputRlib => {
Expand Down Expand Up @@ -805,6 +809,8 @@ fn link_binary_output(sess: Session,
link_natively(sess, true, obj_filename, &out_filename);
}
}

out_filename
}

// Create an 'rlib'
Expand Down
31 changes: 28 additions & 3 deletions src/librustc/driver/driver.rs
Expand Up @@ -384,13 +384,34 @@ pub fn phase_5_run_llvm_passes(sess: Session,
/// This should produce either a finished executable or library.
pub fn phase_6_link_output(sess: Session,
trans: &CrateTranslation,
input: &input,
outputs: &OutputFilenames) {
time(sess.time_passes(), "linking", (), |_|
let outputs = time(sess.time_passes(), "linking", (), |_|
link::link_binary(sess,
trans,
&outputs.obj_filename,
&outputs.out_filename,
&trans.link));

// Write out dependency rules to the .d file if requested
if sess.opts.write_dependency_info {
match *input {
file_input(ref input_path) => {
let files: ~[@str] = sess.codemap.files.iter()
.filter_map(|fmap| if fmap.is_real_file() { Some(fmap.name) } else { None })
.collect();
let mut output_path = outputs[0].dir_path();
let filestem = input_path.filestem().expect("input file must have stem");
output_path.push(Path::new(filestem).with_extension("d"));
let mut file = io::File::create(&output_path);
for output in outputs.iter() {
write!(&mut file as &mut Writer,
"{}: {}\n\n", output.display(), files.connect(" "));
}
}
str_input(_) => {}
}
}
}

pub fn stop_after_phase_3(sess: Session) -> bool {
Expand Down Expand Up @@ -438,7 +459,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
};
phase_5_run_llvm_passes(sess, &trans, outputs);
if stop_after_phase_5(sess) { return; }
phase_6_link_output(sess, &trans, outputs);
phase_6_link_output(sess, &trans, input, outputs);
}

struct IdentifiedAnnotation {
Expand Down Expand Up @@ -750,6 +771,7 @@ pub fn build_session_options(binary: @str,
let cfg = parse_cfgspecs(matches.opt_strs("cfg"), demitter);
let test = matches.opt_present("test");
let android_cross_path = matches.opt_str("android-cross-path");
let write_dependency_info = matches.opt_present("dep-info");

let custom_passes = match matches.opt_str("passes") {
None => ~[],
Expand Down Expand Up @@ -793,7 +815,8 @@ pub fn build_session_options(binary: @str,
parse_only: parse_only,
no_trans: no_trans,
debugging_opts: debugging_opts,
android_cross_path: android_cross_path
android_cross_path: android_cross_path,
write_dependency_info: write_dependency_info,
};
return sopts;
}
Expand Down Expand Up @@ -902,6 +925,8 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
or identified (fully parenthesized,
AST nodes and blocks with IDs)", "TYPE"),
optflag("S", "", "Compile only; do not assemble or link"),
optflag("", "dep-info",
"Output dependency info to .d file after compiling"),
optflag("", "save-temps",
"Write intermediate files (.bc, .opt.bc, .o)
in addition to normal output"),
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/driver/session.rs
Expand Up @@ -170,6 +170,8 @@ pub struct options {
no_trans: bool,
debugging_opts: uint,
android_cross_path: Option<~str>,
// Whether to write .d dependency files
write_dependency_info: bool,
}

pub struct crate_metadata {
Expand Down Expand Up @@ -393,6 +395,7 @@ pub fn basic_options() -> @options {
no_trans: false,
debugging_opts: 0u,
android_cross_path: None,
write_dependency_info: false,
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/librustpkg/util.rs
Expand Up @@ -353,7 +353,8 @@ pub fn compile_crate_from_input(input: &Path,

// bad copy
debug!("out_dir = {}", out_dir.display());
let mut outputs = driver::build_output_filenames(&driver::file_input(input.clone()),
let file_input = driver::file_input(input.clone());
let mut outputs = driver::build_output_filenames(&file_input,
&Some(out_dir.clone()), &None,
crate.attrs, sess);
match what {
Expand Down Expand Up @@ -388,7 +389,7 @@ pub fn compile_crate_from_input(input: &Path,
// -c
if driver::stop_after_phase_5(sess)
|| stop_before == Link || stop_before == Assemble { return Some(outputs.out_filename); }
driver::phase_6_link_output(sess, &translation, outputs);
driver::phase_6_link_output(sess, &translation, &file_input, outputs);

// Register dependency on the source file
// FIXME (#9639): This needs to handle non-utf8 paths
Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/codemap.rs
Expand Up @@ -260,6 +260,10 @@ impl FileMap {
};
self.multibyte_chars.push(mbc);
}

pub fn is_real_file(&self) -> bool {
!(self.name.starts_with("<") && self.name.ends_with(">"))
}
}

pub struct CodeMap {
Expand Down

0 comments on commit 9365375

Please sign in to comment.