Skip to content

Commit 9bbef13

Browse files
committed
auto merge of #10698 : metajack/rust/dep-info, r=alexcrichton
This isn't super useful for libraries yet without #10593. Fixes #7633.
2 parents 09bb3c0 + b2ccd4c commit 9bbef13

File tree

11 files changed

+90
-9
lines changed

11 files changed

+90
-9
lines changed

src/librustc/back/link.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ pub fn link_binary(sess: Session,
721721
trans: &CrateTranslation,
722722
obj_filename: &Path,
723723
out_filename: &Path,
724-
lm: &LinkMeta) {
724+
lm: &LinkMeta) -> ~[Path] {
725725
// If we're generating a test executable, then ignore all other output
726726
// styles at all other locations
727727
let outputs = if sess.opts.test {
@@ -730,15 +730,19 @@ pub fn link_binary(sess: Session,
730730
(*sess.outputs).clone()
731731
};
732732

733+
let mut out_filenames = ~[];
733734
for output in outputs.move_iter() {
734-
link_binary_output(sess, trans, output, obj_filename, out_filename, lm);
735+
let out_file = link_binary_output(sess, trans, output, obj_filename, out_filename, lm);
736+
out_filenames.push(out_file);
735737
}
736738

737739
// Remove the temporary object file and metadata if we aren't saving temps
738740
if !sess.opts.save_temps {
739741
fs::unlink(obj_filename);
740742
fs::unlink(&obj_filename.with_extension("metadata.o"));
741743
}
744+
745+
out_filenames
742746
}
743747

744748
fn is_writeable(p: &Path) -> bool {
@@ -755,7 +759,7 @@ fn link_binary_output(sess: Session,
755759
output: session::OutputStyle,
756760
obj_filename: &Path,
757761
out_filename: &Path,
758-
lm: &LinkMeta) {
762+
lm: &LinkMeta) -> Path {
759763
let libname = output_lib_filename(lm);
760764
let out_filename = match output {
761765
session::OutputRlib => {
@@ -812,6 +816,8 @@ fn link_binary_output(sess: Session,
812816
link_natively(sess, true, obj_filename, &out_filename);
813817
}
814818
}
819+
820+
out_filename
815821
}
816822

817823
// Create an 'rlib'

src/librustc/driver/driver.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,34 @@ pub fn phase_5_run_llvm_passes(sess: Session,
384384
/// This should produce either a finished executable or library.
385385
pub fn phase_6_link_output(sess: Session,
386386
trans: &CrateTranslation,
387+
input: &input,
387388
outputs: &OutputFilenames) {
388-
time(sess.time_passes(), "linking", (), |_|
389+
let outputs = time(sess.time_passes(), "linking", (), |_|
389390
link::link_binary(sess,
390391
trans,
391392
&outputs.obj_filename,
392393
&outputs.out_filename,
393394
&trans.link));
395+
396+
// Write out dependency rules to the .d file if requested
397+
if sess.opts.write_dependency_info {
398+
match *input {
399+
file_input(ref input_path) => {
400+
let files: ~[@str] = sess.codemap.files.iter()
401+
.filter_map(|fmap| if fmap.is_real_file() { Some(fmap.name) } else { None })
402+
.collect();
403+
let mut output_path = outputs[0].dir_path();
404+
let filestem = input_path.filestem().expect("input file must have stem");
405+
output_path.push(Path::new(filestem).with_extension("d"));
406+
let mut file = io::File::create(&output_path);
407+
for output in outputs.iter() {
408+
write!(&mut file as &mut Writer,
409+
"{}: {}\n\n", output.display(), files.connect(" "));
410+
}
411+
}
412+
str_input(_) => {}
413+
}
414+
}
394415
}
395416

396417
pub fn stop_after_phase_3(sess: Session) -> bool {
@@ -438,7 +459,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
438459
};
439460
phase_5_run_llvm_passes(sess, &trans, outputs);
440461
if stop_after_phase_5(sess) { return; }
441-
phase_6_link_output(sess, &trans, outputs);
462+
phase_6_link_output(sess, &trans, input, outputs);
442463
}
443464

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

754776
let custom_passes = match matches.opt_str("passes") {
755777
None => ~[],
@@ -793,7 +815,8 @@ pub fn build_session_options(binary: @str,
793815
parse_only: parse_only,
794816
no_trans: no_trans,
795817
debugging_opts: debugging_opts,
796-
android_cross_path: android_cross_path
818+
android_cross_path: android_cross_path,
819+
write_dependency_info: write_dependency_info,
797820
};
798821
return sopts;
799822
}
@@ -902,6 +925,8 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
902925
or identified (fully parenthesized,
903926
AST nodes and blocks with IDs)", "TYPE"),
904927
optflag("S", "", "Compile only; do not assemble or link"),
928+
optflag("", "dep-info",
929+
"Output dependency info to .d file after compiling"),
905930
optflag("", "save-temps",
906931
"Write intermediate files (.bc, .opt.bc, .o)
907932
in addition to normal output"),

src/librustc/driver/session.rs

+3
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ pub struct options {
170170
no_trans: bool,
171171
debugging_opts: uint,
172172
android_cross_path: Option<~str>,
173+
// Whether to write .d dependency files
174+
write_dependency_info: bool,
173175
}
174176

175177
pub struct crate_metadata {
@@ -393,6 +395,7 @@ pub fn basic_options() -> @options {
393395
no_trans: false,
394396
debugging_opts: 0u,
395397
android_cross_path: None,
398+
write_dependency_info: false,
396399
}
397400
}
398401

src/librustpkg/util.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ pub fn compile_crate_from_input(input: &Path,
353353

354354
// bad copy
355355
debug!("out_dir = {}", out_dir.display());
356-
let mut outputs = driver::build_output_filenames(&driver::file_input(input.clone()),
356+
let file_input = driver::file_input(input.clone());
357+
let mut outputs = driver::build_output_filenames(&file_input,
357358
&Some(out_dir.clone()), &None,
358359
crate.attrs, sess);
359360
match what {
@@ -388,7 +389,7 @@ pub fn compile_crate_from_input(input: &Path,
388389
// -c
389390
if driver::stop_after_phase_5(sess)
390391
|| stop_before == Link || stop_before == Assemble { return Some(outputs.out_filename); }
391-
driver::phase_6_link_output(sess, &translation, outputs);
392+
driver::phase_6_link_output(sess, &translation, &file_input, outputs);
392393

393394
// Register dependency on the source file
394395
// FIXME (#9639): This needs to handle non-utf8 paths

src/libsyntax/codemap.rs

+4
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ impl FileMap {
260260
};
261261
self.multibyte_chars.push(mbc);
262262
}
263+
264+
pub fn is_real_file(&self) -> bool {
265+
!(self.name.starts_with("<") && self.name.ends_with(">"))
266+
}
263267
}
264268

265269
pub struct CodeMap {

src/libsyntax/ext/source_util.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub fn expand_mod(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
8080
pub fn expand_include(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
8181
-> base::MacResult {
8282
let file = get_single_str_from_tts(cx, sp, tts, "include!");
83+
// The file will be added to the code map by the parser
8384
let p = parse::new_sub_parser_from_file(
8485
cx.parse_sess(), cx.cfg(),
8586
&res_rel_file(cx, sp, &Path::new(file)), sp);
@@ -99,7 +100,20 @@ pub fn expand_include_str(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
99100
Ok(bytes) => bytes,
100101
};
101102
match str::from_utf8_owned_opt(bytes) {
102-
Some(s) => base::MRExpr(cx.expr_str(sp, s.to_managed())),
103+
Some(s) => {
104+
let s = s.to_managed();
105+
// Add this input file to the code map to make it available as
106+
// dependency information
107+
cx.parse_sess.cm.files.push(@codemap::FileMap {
108+
name: file.display().to_str().to_managed(),
109+
substr: codemap::FssNone,
110+
src: s,
111+
start_pos: codemap::BytePos(0),
112+
lines: @mut ~[],
113+
multibyte_chars: @mut ~[],
114+
});
115+
base::MRExpr(cx.expr_str(sp, s))
116+
}
103117
None => {
104118
cx.span_fatal(sp, format!("{} wasn't a utf-8 file", file.display()));
105119
}

src/test/run-make/dep-info/Makefile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-include ../tools.mk
2+
all:
3+
$(RUSTC) --dep-info --lib lib.rs
4+
sleep 1
5+
touch foo.rs
6+
-rm -f $(TMPDIR)/done
7+
$(MAKE) -f Makefile.foo
8+
rm $(TMPDIR)/done
9+
pwd
10+
$(MAKE) -df Makefile.foo
11+
rm $(TMPDIR)/done && exit 1 || exit 0
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
ifeq ($(shell uname),Darwin)
2+
LIBEXT=dylib
3+
else
4+
LIBEXT=so
5+
endif
6+
7+
$(TMPDIR)/libfoo-b517899a-0.1.$(LIBEXT):
8+
$(RUSTC) --dep-info --lib lib.rs
9+
touch $(TMPDIR)/done
10+
11+
-include $(TMPDIR)/lib.d

src/test/run-make/dep-info/bar.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub fn bar() {}

src/test/run-make/dep-info/foo.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub fn foo() {}

src/test/run-make/dep-info/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[pkgid="foo#0.1"];
2+
3+
pub mod foo;
4+
pub mod bar;

0 commit comments

Comments
 (0)