Skip to content

Commit 8f0c475

Browse files
committed
Add an --out-dir option to rustc.
1 parent ce24ce1 commit 8f0c475

File tree

1 file changed

+70
-34
lines changed

1 file changed

+70
-34
lines changed

src/comp/driver/rustc.rs

Lines changed: 70 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ fn inject_libcore_reference(sess: session::session,
132132

133133

134134
fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
135-
output: option::t<str>) {
135+
outdir: option::t<str>, output: option::t<str>) {
136136

137137
let time_passes = sess.get_opts().time_passes;
138138
let crate =
@@ -192,7 +192,7 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
192192
bind kind::check_crate(ty_cx, last_uses, crate));
193193
if sess.get_opts().no_trans { ret; }
194194

195-
let outputs = build_output_filenames(input, output, sess);
195+
let outputs = build_output_filenames(input, outdir, output, sess);
196196

197197
let (llmod, link_meta) =
198198
time(time_passes, "translation",
@@ -300,6 +300,7 @@ options:
300300
-v --version print version info and exit
301301
302302
-o <filename> write output to <filename>
303+
--out-dir <dir> write output to compiler-chosen filename in <dir>
303304
--lib compile a library crate
304305
--bin compile an executable crate (default)
305306
--static use or produce static libraries
@@ -515,7 +516,8 @@ fn opts() -> [getopts::opt] {
515516
optflag("emit-llvm"), optflagopt("pretty"),
516517
optflag("ls"), optflag("parse-only"), optflag("no-trans"),
517518
optflag("O"), optopt("opt-level"), optmulti("L"), optflag("S"),
518-
optflag("c"), optopt("o"), optflag("g"), optflag("save-temps"),
519+
optopt("o"), optopt("out-dir"),
520+
optflag("c"), optflag("g"), optflag("save-temps"),
519521
optopt("sysroot"), optopt("target"), optflag("stats"),
520522
optflag("time-passes"), optflag("time-llvm-passes"),
521523
optflag("no-verify"),
@@ -527,56 +529,89 @@ fn opts() -> [getopts::opt] {
527529
optflag("warn-unused-imports")];
528530
}
529531

530-
fn build_output_filenames(ifile: str, ofile: option::t<str>,
532+
fn build_output_filenames(ifile: str,
533+
odir: option::t<str>,
534+
ofile: option::t<str>,
531535
sess: session::session)
532536
-> @{out_filename: str, obj_filename:str} {
533-
let obj_filename = "";
534-
let saved_out_filename: str = "";
537+
let obj_path = "";
538+
let out_path: str = "";
535539
let sopts = sess.get_opts();
536540
let stop_after_codegen =
537541
sopts.output_type != link::output_type_exe ||
538542
sopts.static && sess.building_library();
543+
544+
545+
let obj_suffix =
546+
alt sopts.output_type {
547+
link::output_type_none. { "none" }
548+
link::output_type_bitcode. { "bc" }
549+
link::output_type_assembly. { "s" }
550+
link::output_type_llvm_assembly. { "ll" }
551+
// Object and exe output both use the '.o' extension here
552+
link::output_type_object. | link::output_type_exe. {
553+
"o"
554+
}
555+
};
556+
539557
alt ofile {
540558
none. {
541559
// "-" as input file will cause the parser to read from stdin so we
542560
// have to make up a name
543561
// We want to toss everything after the final '.'
544-
let parts =
545-
if !input_is_stdin(ifile) {
546-
str::split(ifile, '.' as u8)
547-
} else { ["default", "rs"] };
548-
vec::pop(parts);
549-
let base_filename = str::connect(parts, ".");
550-
let suffix =
551-
alt sopts.output_type {
552-
link::output_type_none. { "none" }
553-
link::output_type_bitcode. { "bc" }
554-
link::output_type_assembly. { "s" }
555-
link::output_type_llvm_assembly. { "ll" }
556-
// Object and exe output both use the '.o' extension here
557-
link::output_type_object. | link::output_type_exe. {
558-
"o"
559-
}
560-
};
561-
obj_filename = base_filename + "." + suffix;
562+
let dirname = alt odir {
563+
some(d) { d }
564+
none. {
565+
if input_is_stdin(ifile) {
566+
std::os::getcwd()
567+
} else {
568+
fs::dirname(ifile)
569+
}
570+
}
571+
};
572+
573+
let (base_path, _) = if !input_is_stdin(ifile) {
574+
fs::splitext(ifile)
575+
} else {
576+
(fs::connect(dirname, "rust_out"), "")
577+
};
578+
562579

563580
if sess.building_library() {
564-
let dirname = fs::dirname(base_filename);
565-
let basename = fs::basename(base_filename);
581+
let basename = fs::basename(base_path);
566582
let dylibname = std::os::dylib_filename(basename);
567-
saved_out_filename = fs::connect(dirname, dylibname);
583+
out_path = fs::connect(dirname, dylibname);
584+
obj_path = fs::connect(dirname, basename + "." + obj_path);
568585
} else {
569-
saved_out_filename = base_filename;
586+
out_path = base_path;
587+
obj_path = base_path + "." + obj_suffix;
570588
}
571589
}
590+
572591
some(out_file) {
573-
// FIXME: what about windows? This will create a foo.exe.o.
574-
saved_out_filename = out_file;
575-
obj_filename =
576-
if stop_after_codegen { out_file } else { out_file + ".o" };
592+
out_path = out_file;
593+
obj_path = if stop_after_codegen {
594+
out_file
595+
} else {
596+
let (base, _) = fs::splitext(out_file);
597+
let modified = base + "." + obj_suffix;
598+
modified
599+
};
600+
601+
if sess.building_library() {
602+
// FIXME: We might want to warn here; we're actually not going to
603+
// respect the user's choice of library name when it comes time to
604+
// link, we'll be linking to lib<basename>-<hash>-<version>.so no
605+
// matter what.
606+
}
607+
608+
if odir != none {
609+
sess.warn("Ignoring --out-dir flag due to -o flag.");
610+
}
577611
}
578612
}
579-
ret @{out_filename: saved_out_filename, obj_filename: obj_filename};
613+
ret @{out_filename: out_path,
614+
obj_filename: obj_path};
580615
}
581616

582617
fn early_error(msg: str) -> ! {
@@ -609,6 +644,7 @@ fn main(args: [str]) {
609644

610645
let sopts = build_session_options(match);
611646
let sess = build_session(sopts);
647+
let odir = getopts::opt_maybe_str(match, "out-dir");
612648
let ofile = getopts::opt_maybe_str(match, "o");
613649
let cfg = build_configuration(sess, binary, ifile);
614650
let pretty =
@@ -626,7 +662,7 @@ fn main(args: [str]) {
626662
ret;
627663
}
628664

629-
compile_input(sess, cfg, ifile, ofile);
665+
compile_input(sess, cfg, ifile, odir, ofile);
630666
}
631667

632668
#[cfg(test)]

0 commit comments

Comments
 (0)