Specify the name of the crate being built.
.TP
\fB\-\-emit\fR [asm|llvm\-bc|llvm\-ir|obj|link|dep\-info]
-Configure the output that \fBrustc\fR will produce.
+Configure the output that \fBrustc\fR will produce. Each option may also be of
+the form KIND=PATH to specify the explicit output location for that particular
+emission kind.
.TP
\fB\-\-print\fR [crate\-name|file\-names|sysroot]
Comma separated list of compiler information to print on stdout.
.TP
\fB\-o\fR \fIFILENAME\fR
Write output to \fIFILENAME\fR.
-Ignored if multiple \fI\-\-emit\fR outputs are specified.
+Ignored if multiple \fI\-\-emit\fR outputs are specified which don't have an
+explicit path otherwise.
.TP
\fB\-\-out\-dir\fR \fIDIR\fR
Write output to compiler\[hy]chosen filename in \fIDIR\fR.
pub use self::CrateType::*;
pub use self::Passes::*;
pub use self::OptLevel::*;
-pub use self::OutputType::*;
pub use self::DebugInfoLevel::*;
use session::{early_error, early_warn, Session};
FullDebugInfo,
}
-#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum OutputType {
- OutputTypeBitcode,
- OutputTypeAssembly,
- OutputTypeLlvmAssembly,
- OutputTypeObject,
- OutputTypeExe,
- OutputTypeDepInfo,
+ Bitcode,
+ Assembly,
+ LlvmAssembly,
+ Object,
+ Exe,
+ DepInfo,
}
#[derive(Clone)]
pub lint_opts: Vec<(String, lint::Level)>,
pub lint_cap: Option<lint::Level>,
pub describe_lints: bool,
- pub output_types: Vec<OutputType>,
+ pub output_types: HashMap<OutputType, Option<PathBuf>>,
// This was mutable for rustpkg, which updates search paths based on the
// parsed code. It remains mutable in case its replacements wants to use
// this.
pub always_build_mir: bool,
pub no_analysis: bool,
pub debugging_opts: DebuggingOptions,
- /// Whether to write dependency files. It's (enabled, optional filename).
- pub write_dependency_info: (bool, Option<PathBuf>),
pub prints: Vec<PrintRequest>,
pub cg: CodegenOptions,
pub color: ColorConfig,
pub out_filestem: String,
pub single_output_file: Option<PathBuf>,
pub extra: String,
+ pub outputs: HashMap<OutputType, Option<PathBuf>>,
}
impl OutputFilenames {
pub fn path(&self, flavor: OutputType) -> PathBuf {
- match self.single_output_file {
- Some(ref path) => return path.clone(),
- None => {}
- }
- self.temp_path(flavor)
+ self.outputs.get(&flavor).and_then(|p| p.to_owned())
+ .or_else(|| self.single_output_file.clone())
+ .unwrap_or_else(|| self.temp_path(flavor))
}
pub fn temp_path(&self, flavor: OutputType) -> PathBuf {
let base = self.out_directory.join(&self.filestem());
match flavor {
- OutputTypeBitcode => base.with_extension("bc"),
- OutputTypeAssembly => base.with_extension("s"),
- OutputTypeLlvmAssembly => base.with_extension("ll"),
- OutputTypeObject => base.with_extension("o"),
- OutputTypeDepInfo => base.with_extension("d"),
- OutputTypeExe => base,
+ OutputType::Bitcode => base.with_extension("bc"),
+ OutputType::Assembly => base.with_extension("s"),
+ OutputType::LlvmAssembly => base.with_extension("ll"),
+ OutputType::Object => base.with_extension("o"),
+ OutputType::DepInfo => base.with_extension("d"),
+ OutputType::Exe => base,
}
}
lint_opts: Vec::new(),
lint_cap: None,
describe_lints: false,
- output_types: Vec::new(),
+ output_types: HashMap::new(),
search_paths: SearchPaths::new(),
maybe_sysroot: None,
target_triple: host_triple().to_string(),
always_build_mir: false,
no_analysis: false,
debugging_opts: basic_debugging_options(),
- write_dependency_info: (false, None),
prints: Vec::new(),
cg: basic_codegen_options(),
color: Auto,
unsafe { llvm::LLVMSetDebug(1); }
}
- let mut output_types = Vec::new();
+ let mut output_types = HashMap::new();
if !debugging_opts.parse_only && !no_trans {
- let unparsed_output_types = matches.opt_strs("emit");
- for unparsed_output_type in &unparsed_output_types {
- for part in unparsed_output_type.split(',') {
- let output_type = match part {
- "asm" => OutputTypeAssembly,
- "llvm-ir" => OutputTypeLlvmAssembly,
- "llvm-bc" => OutputTypeBitcode,
- "obj" => OutputTypeObject,
- "link" => OutputTypeExe,
- "dep-info" => OutputTypeDepInfo,
- _ => {
+ for list in matches.opt_strs("emit") {
+ for output_type in list.split(',') {
+ let mut parts = output_type.splitn(2, '=');
+ let output_type = match parts.next().unwrap() {
+ "asm" => OutputType::Assembly,
+ "llvm-ir" => OutputType::LlvmAssembly,
+ "llvm-bc" => OutputType::Bitcode,
+ "obj" => OutputType::Object,
+ "link" => OutputType::Exe,
+ "dep-info" => OutputType::DepInfo,
+ part => {
early_error(color, &format!("unknown emission type: `{}`",
part))
}
};
- output_types.push(output_type)
+ let path = parts.next().map(PathBuf::from);
+ output_types.insert(output_type, path);
}
}
};
- output_types.sort();
- output_types.dedup();
if output_types.is_empty() {
- output_types.push(OutputTypeExe);
+ output_types.insert(OutputType::Exe, None);
}
let cg = build_codegen_options(matches, color);
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
let test = matches.opt_present("test");
- let write_dependency_info = (output_types.contains(&OutputTypeDepInfo), None);
let prints = matches.opt_strs("print").into_iter().map(|s| {
match &*s {
always_build_mir: always_build_mir,
no_analysis: no_analysis,
debugging_opts: debugging_opts,
- write_dependency_info: write_dependency_info,
prints: prints,
cg: cg,
color: color,
use rustc::front::map as hir_map;
use rustc_mir as mir;
use rustc::session::Session;
-use rustc::session::config::{self, Input, OutputFilenames};
+use rustc::session::config::{self, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
use rustc::lint;
use rustc::metadata;
use serialize::json;
+use std::collections::HashMap;
use std::env;
use std::ffi::{OsString, OsStr};
use std::fs;
let arenas = ty::CtxtArenas::new();
let ast_map = make_map(&sess, &mut hir_forest);
- write_out_deps(&sess, input, &outputs, &id[..]);
+ write_out_deps(&sess, &outputs, &id);
controller_entry_point!(after_write_deps,
sess,
trans: &trans::CrateTranslation,
outputs: &OutputFilenames) {
if sess.opts.cg.no_integrated_as {
- let output_type = config::OutputTypeAssembly;
-
+ let mut map = HashMap::new();
+ map.insert(OutputType::Assembly, None);
time(sess.time_passes(), "LLVM passes", ||
- write::run_passes(sess, trans, &[output_type], outputs));
+ write::run_passes(sess, trans, &map, outputs));
write::run_assembler(sess, outputs);
// Remove assembly source, unless --save-temps was specified
if !sess.opts.cg.save_temps {
- fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
+ fs::remove_file(&outputs.temp_path(OutputType::Assembly)).unwrap();
}
} else {
time(sess.time_passes(), "LLVM passes", ||
filename.replace(" ", "\\ ")
}
-fn write_out_deps(sess: &Session,
- input: &Input,
- outputs: &OutputFilenames,
- id: &str) {
-
+fn write_out_deps(sess: &Session, outputs: &OutputFilenames, id: &str) {
let mut out_filenames = Vec::new();
- for output_type in &sess.opts.output_types {
+ for output_type in sess.opts.output_types.keys() {
let file = outputs.path(*output_type);
match *output_type {
- config::OutputTypeExe => {
+ OutputType::Exe => {
for output in sess.crate_types.borrow().iter() {
let p = link::filename_for_input(sess, *output, id,
outputs);
}
}
- // Write out dependency rules to the dep-info file if requested with
- // --dep-info
- let deps_filename = match sess.opts.write_dependency_info {
- // Use filename from --dep-file argument if given
- (true, Some(ref filename)) => filename.clone(),
- // Use default filename: crate source filename with extension replaced
- // by ".d"
- (true, None) => match *input {
- Input::File(..) => outputs.with_extension("d"),
- Input::Str(..) => {
- sess.warn("can not write --dep-info without a filename \
- when compiling stdin.");
- return
- },
- },
- _ => return,
- };
+ // Write out dependency rules to the dep-info file if requested
+ if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
+ return
+ }
+ let deps_filename = outputs.path(OutputType::DepInfo);
let result = (|| -> io::Result<()> {
// Build a list of files used to compile the output and
out_filestem: stem,
single_output_file: None,
extra: sess.opts.cg.extra_filename.clone(),
+ outputs: sess.opts.output_types.clone(),
}
}
Some(ref out_file) => {
- let ofile = if sess.opts.output_types.len() > 1 {
+ let unnamed_output_types = sess.opts.output_types.values()
+ .filter(|a| a.is_none())
+ .count();
+ let ofile = if unnamed_output_types > 1 {
sess.warn("ignoring specified output filename because multiple \
outputs were requested");
None
.to_str().unwrap().to_string(),
single_output_file: ofile,
extra: sess.opts.cg.extra_filename.clone(),
+ outputs: sess.opts.output_types.clone(),
}
}
}
use rustc_trans::back::link;
use rustc_trans::save;
use rustc::session::{config, Session, build_session};
-use rustc::session::config::{Input, PrintRequest};
+use rustc::session::config::{Input, PrintRequest, OutputType};
use rustc::lint::Lint;
use rustc::lint;
use rustc::metadata;
control.after_analysis.stop = Compilation::Stop;
}
- if !sess.opts.output_types.iter().any(|&i| i == config::OutputTypeExe) {
+ if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
control.after_llvm.stop = Compilation::Stop;
}
use super::svh::Svh;
use session::config;
use session::config::NoDebugInfo;
-use session::config::{OutputFilenames, Input, OutputTypeBitcode, OutputTypeExe, OutputTypeObject};
+use session::config::{OutputFilenames, Input, OutputType};
use session::search_paths::PathKind;
use session::Session;
use metadata::common::LinkMeta;
}
config::CrateTypeExecutable => {
let suffix = &sess.target.target.options.exe_suffix;
- let out_filename = outputs.path(OutputTypeExe);
+ let out_filename = outputs.path(OutputType::Exe);
if suffix.is_empty() {
out_filename.to_path_buf()
} else {
outputs: &OutputFilenames,
crate_name: &str) -> PathBuf {
let objects = object_filenames(sess, outputs);
- let out_filename = match outputs.single_output_file {
- Some(ref file) => file.clone(),
- None => filename_for_input(sess, crate_type, crate_name, outputs),
- };
+ let default_filename = filename_for_input(sess, crate_type, crate_name,
+ outputs);
+ let out_filename = outputs.outputs.get(&OutputType::Exe)
+ .and_then(|s| s.to_owned())
+ .or_else(|| outputs.single_output_file.clone())
+ .unwrap_or(default_filename);
// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
// check this already -- however, the Linux linker will happily overwrite a
fn object_filenames(sess: &Session, outputs: &OutputFilenames) -> Vec<PathBuf> {
(0..sess.opts.cg.codegen_units).map(|i| {
let ext = format!("{}.o", i);
- outputs.temp_path(OutputTypeObject).with_extension(&ext)
+ outputs.temp_path(OutputType::Object).with_extension(&ext)
}).collect()
}
// See the bottom of back::write::run_passes for an explanation
// of when we do and don't keep .0.bc files around.
let user_wants_numbered_bitcode =
- sess.opts.output_types.contains(&OutputTypeBitcode) &&
+ sess.opts.output_types.contains_key(&OutputType::Bitcode) &&
sess.opts.cg.codegen_units > 1;
if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode {
remove(sess, &bc_filename);
use back::link::{get_linker, remove};
use session::config::{OutputFilenames, Passes, SomePasses, AllPasses};
use session::Session;
-use session::config;
+use session::config::{self, OutputType};
use llvm;
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
use llvm::SMDiagnosticRef;
use syntax::diagnostic;
use syntax::diagnostic::{Emitter, Handler, Level};
+use std::collections::HashMap;
use std::ffi::{CStr, CString};
use std::fs;
-use std::path::Path;
+use std::path::{Path, PathBuf};
use std::ptr;
use std::str;
use std::sync::{Arc, Mutex};
use std::thread;
use libc::{self, c_uint, c_int, c_void};
-#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
-pub enum OutputType {
- OutputTypeBitcode,
- OutputTypeAssembly,
- OutputTypeLlvmAssembly,
- OutputTypeObject,
- OutputTypeExe,
-}
-
pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
unsafe {
let cstr = llvm::LLVMRustGetLastError();
pub fn run_passes(sess: &Session,
trans: &CrateTranslation,
- output_types: &[config::OutputType],
+ output_types: &HashMap<OutputType, Option<PathBuf>>,
crate_output: &OutputFilenames) {
// It's possible that we have `codegen_units > 1` but only one item in
// `trans.modules`. We could theoretically proceed and do LTO in that
// archive in order to allow LTO against it.
let needs_crate_bitcode =
sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
- sess.opts.output_types.contains(&config::OutputTypeExe);
+ sess.opts.output_types.contains_key(&OutputType::Exe);
let needs_crate_object =
- sess.opts.output_types.contains(&config::OutputTypeExe);
+ sess.opts.output_types.contains_key(&OutputType::Exe);
if needs_crate_bitcode {
modules_config.emit_bc = true;
}
- for output_type in output_types {
+ for output_type in output_types.keys() {
match *output_type {
- config::OutputTypeBitcode => { modules_config.emit_bc = true; },
- config::OutputTypeLlvmAssembly => { modules_config.emit_ir = true; },
- config::OutputTypeAssembly => {
+ OutputType::Bitcode => { modules_config.emit_bc = true; },
+ OutputType::LlvmAssembly => { modules_config.emit_ir = true; },
+ OutputType::Assembly => {
modules_config.emit_asm = true;
// If we're not using the LLVM assembler, this function
// could be invoked specially with output_type_assembly, so
// in this case we still want the metadata object file.
- if !sess.opts.output_types.contains(&config::OutputTypeAssembly) {
+ if !sess.opts.output_types.contains_key(&OutputType::Assembly) {
metadata_config.emit_obj = true;
}
},
- config::OutputTypeObject => { modules_config.emit_obj = true; },
- config::OutputTypeExe => {
+ OutputType::Object => { modules_config.emit_obj = true; },
+ OutputType::Exe => {
modules_config.emit_obj = true;
metadata_config.emit_obj = true;
},
- config::OutputTypeDepInfo => {}
+ OutputType::DepInfo => {}
}
}
}
};
- let copy_if_one_unit = |ext: &str, output_type: config::OutputType, keep_numbered: bool| {
- // Three cases:
+ let copy_if_one_unit = |ext: &str,
+ output_type: OutputType,
+ keep_numbered: bool| {
if sess.opts.cg.codegen_units == 1 {
// 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`.
// The user just wants `foo.x`, not `foo.0.x`.
remove(sess, &crate_output.with_extension(ext));
}
+ } else if crate_output.outputs.contains_key(&output_type) {
+ // 2) Multiple codegen units, with `--emit foo=some_name`. We have
+ // no good solution for this case, so warn the user.
+ sess.warn(&format!("ignoring emit path because multiple .{} files \
+ were produced", ext));
+ } else if crate_output.single_output_file.is_some() {
+ // 3) Multiple codegen units, with `-o some_name`. We have
+ // no good solution for this case, so warn the user.
+ sess.warn(&format!("ignoring -o because multiple .{} files \
+ were produced", ext));
} else {
- if crate_output.single_output_file.is_some() {
- // 2) Multiple codegen units, with `-o some_name`. We have
- // no good solution for this case, so warn the user.
- sess.warn(&format!("ignoring -o because multiple .{} files were produced",
- ext));
- } else {
- // 3) Multiple codegen units, but no `-o some_name`. We
- // just leave the `foo.0.x` files in place.
- // (We don't have to do any work in this case.)
- }
+ // 4) Multiple codegen units, but no explicit name. We
+ // just leave the `foo.0.x` files in place.
+ // (We don't have to do any work in this case.)
}
};
// to get rid of it.
let mut user_wants_bitcode = false;
let mut user_wants_objects = false;
- for output_type in output_types {
+ for output_type in output_types.keys() {
match *output_type {
- config::OutputTypeBitcode => {
+ OutputType::Bitcode => {
user_wants_bitcode = true;
// Copy to .bc, but always keep the .0.bc. There is a later
// check to figure out if we should delete .0.bc files, or keep
// them for making an rlib.
- copy_if_one_unit("0.bc", config::OutputTypeBitcode, true);
+ copy_if_one_unit("0.bc", OutputType::Bitcode, true);
}
- config::OutputTypeLlvmAssembly => {
- copy_if_one_unit("0.ll", config::OutputTypeLlvmAssembly, false);
+ OutputType::LlvmAssembly => {
+ copy_if_one_unit("0.ll", OutputType::LlvmAssembly, false);
}
- config::OutputTypeAssembly => {
- copy_if_one_unit("0.s", config::OutputTypeAssembly, false);
+ OutputType::Assembly => {
+ copy_if_one_unit("0.s", OutputType::Assembly, false);
}
- config::OutputTypeObject => {
+ OutputType::Object => {
user_wants_objects = true;
- copy_if_one_unit("0.o", config::OutputTypeObject, true);
+ copy_if_one_unit("0.o", OutputType::Object, true);
}
- config::OutputTypeExe |
- config::OutputTypeDepInfo => {}
+ OutputType::Exe |
+ OutputType::DepInfo => {}
}
}
let user_wants_bitcode = user_wants_bitcode;
pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
let (pname, mut cmd) = get_linker(sess);
- cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject))
- .arg(&outputs.temp_path(config::OutputTypeAssembly));
+ cmd.arg("-c").arg("-o").arg(&outputs.path(OutputType::Object))
+ .arg(&outputs.temp_path(OutputType::Assembly));
debug!("{:?}", cmd);
match cmd.output() {
use testing;
use rustc_lint;
use rustc::session::{self, config};
-use rustc::session::config::get_unstable_features_setting;
+use rustc::session::config::{get_unstable_features_setting, OutputType};
use rustc::session::search_paths::{SearchPaths, PathKind};
use rustc_front::lowering::lower_crate;
use rustc_back::tempdir::TempDir;
// never wrap the test in `fn main() { ... }`
let test = maketest(test, Some(cratename), as_test_harness, opts);
let input = config::Input::Str(test.to_string());
+ let mut outputs = HashMap::new();
+ outputs.insert(OutputType::Exe, None);
let sessopts = config::Options {
maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
.parent().unwrap().to_path_buf()),
search_paths: libs,
crate_types: vec!(config::CrateTypeExecutable),
- output_types: vec!(config::OutputTypeExe),
+ output_types: outputs,
externs: externs,
cg: config::CodegenOptions {
prefer_dynamic: true,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_private, path, convert)]
+#![feature(rustc_private)]
extern crate rustc;
extern crate rustc_driver;
extern crate syntax;
use rustc::session::{build_session, Session};
-use rustc::session::config::{basic_options, build_configuration, Input, OutputTypeExe};
+use rustc::session::config::{basic_options, build_configuration, Input, OutputType};
use rustc_driver::driver::{compile_input, CompileController};
use syntax::diagnostics::registry::Registry;
fn basic_sess(sysroot: PathBuf) -> Session {
let mut opts = basic_options();
- opts.output_types = vec![OutputTypeExe];
+ opts.output_types.insert(OutputType::Exe, None);
opts.maybe_sysroot = Some(sysroot);
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
rm -f $(TMPDIR)/bar.pdb
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
- $(RUSTC) foo.rs --emit=asm -o $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit asm -o $(TMPDIR)/foo
+ rm $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit asm=$(TMPDIR)/foo
rm $(TMPDIR)/foo
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
- $(RUSTC) foo.rs --emit=llvm-bc -o $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit llvm-bc -o $(TMPDIR)/foo
+ rm $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit llvm-bc=$(TMPDIR)/foo
rm $(TMPDIR)/foo
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
- $(RUSTC) foo.rs --emit=llvm-ir -o $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit llvm-ir -o $(TMPDIR)/foo
+ rm $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/foo
rm $(TMPDIR)/foo
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
- $(RUSTC) foo.rs --emit=obj -o $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit obj -o $(TMPDIR)/foo
+ rm $(TMPDIR)/foo
+ $(RUSTC) foo.rs --emit obj=$(TMPDIR)/foo
rm $(TMPDIR)/foo
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
- $(RUSTC) foo.rs --emit=link -o $(TMPDIR)/$(call BIN,foo)
+ $(RUSTC) foo.rs --emit link -o $(TMPDIR)/$(call BIN,foo)
+ rm $(TMPDIR)/$(call BIN,foo)
+ $(RUSTC) foo.rs --emit link=$(TMPDIR)/$(call BIN,foo)
rm $(TMPDIR)/$(call BIN,foo)
rm -f $(TMPDIR)/foo.pdb
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
$(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo
rm $(TMPDIR)/foo
+ $(RUSTC) foo.rs --crate-type=rlib --emit link=$(TMPDIR)/foo
+ rm $(TMPDIR)/foo
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
$(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo)
rm $(TMPDIR)/$(call BIN,foo)
+ $(RUSTC) foo.rs --crate-type=dylib --emit link=$(TMPDIR)/$(call BIN,foo)
+ rm $(TMPDIR)/$(call BIN,foo)
rm -f $(TMPDIR)/foo.{exp,lib,pdb}
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
$(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo
rm $(TMPDIR)/foo
+ $(RUSTC) foo.rs --crate-type=staticlib --emit link=$(TMPDIR)/foo
+ rm $(TMPDIR)/foo
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
$(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo)
rm $(TMPDIR)/$(call BIN,foo)
+ $(RUSTC) foo.rs --crate-type=bin --emit link=$(TMPDIR)/$(call BIN,foo)
+ rm $(TMPDIR)/$(call BIN,foo)
rm -f $(TMPDIR)/foo.pdb
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
+ $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/ir \
+ --emit link \
+ --crate-type=rlib
+ rm $(TMPDIR)/ir
+ rm $(TMPDIR)/libbar.rlib
+ [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
+
+ $(RUSTC) foo.rs --emit asm=$(TMPDIR)/asm \
+ --emit llvm-ir=$(TMPDIR)/ir \
+ --emit llvm-bc=$(TMPDIR)/bc \
+ --emit obj=$(TMPDIR)/obj \
+ --emit link=$(TMPDIR)/link \
+ --crate-type=staticlib
+ rm $(TMPDIR)/asm
+ rm $(TMPDIR)/ir
+ rm $(TMPDIR)/bc
+ rm $(TMPDIR)/obj
+ rm $(TMPDIR)/link
+ [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
+
$(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib
rm $(TMPDIR)/bar.ll
rm $(TMPDIR)/bar.s