diff --git a/man/rustc.1 b/man/rustc.1 index 885ec37f374..0f84c26df2b 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -12,17 +12,14 @@ This program is a compiler for the Rust language, available at .SH OPTIONS .TP -\fB\-\-bin\fR -Compile an executable crate (default) -.TP -\fB\-c\fR -Compile and assemble, but do not link +\fB\-\-crate-type=[bin|lib|dylib|rlib|staticlib]\fR +Configure the flavor of rust crate that is generated (default `bin`) .TP \fB\-\-cfg\fR SPEC Configure the compilation environment .TP -\fB\-\-emit\-llvm\fR -Produce an LLVM bitcode file +\fB\-\-emit=[asm,ir,bc,obj,link]\fR +Configure the output that rustc will produce .TP \fB\-h\fR, \fB\-\-help\fR Display this message @@ -30,9 +27,6 @@ Display this message \fB\-L\fR PATH Add a directory to the library search path .TP -\fB\-\-lib\fR -Compile a library crate -.TP \fB\-\-linker\fR LINKER Program to use for linking instead of the default .TP @@ -49,7 +43,7 @@ Run all passes except translation; no output Equivalent to \fI\-\-opt\-level=2\fR .TP \fB\-o\fR FILENAME -Write output to +Write output to . Ignored if more than one --emit is specified. .TP \fB\-\-opt\-level\fR LEVEL Optimize with possible levels 0-3 @@ -60,7 +54,8 @@ the default passes for the optimization level. A value of 'list' will list the available passes. .TP \fB\-\-out\-dir\fR DIR -Write output to compiler-chosen filename in +Write output to compiler-chosen filename in . Ignored if -o is specified. +(default the current directory) .TP \fB\-\-parse\-only\fR Parse only; do not compile, assemble, or link @@ -71,9 +66,6 @@ Pretty-print the input instead of compiling; valid types are: normal expanded, with type annotations), or identified (fully parenthesized, AST nodes and blocks with IDs) .TP -\fB\-S\fR -Compile only; do not assemble or link -.TP \fB\-\-save\-temps\fR Write intermediate files (.bc, .opt.bc, .o) in addition to normal output .TP @@ -120,7 +112,7 @@ To build an executable from a source file with a main function: $ rustc -o hello hello.rs To build a library from a source file: - $ rustc --lib hello-lib.rs + $ rustc --crate-type=lib hello-lib.rs To build either with a crate (.rs) file: $ rustc hello.rs diff --git a/mk/crates.mk b/mk/crates.mk index ea573b9db8d..652d7629bda 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -102,7 +102,7 @@ $(foreach crate,$(CRATES),$(eval $(call RUST_CRATE,$(crate)))) # # $(1) is the crate to generate variables for define RUST_TOOL -TOOL_INPUTS_$(1) := $$(wildcard $$(addprefix $(S)$$(dir $$(TOOL_SOURCE_$(1))), \ +TOOL_INPUTS_$(1) := $$(wildcard $$(addprefix $$(dir $$(TOOL_SOURCE_$(1))), \ *.rs */*.rs */*/*.rs */*/*/*.rs)) endef diff --git a/mk/tests.mk b/mk/tests.mk index 85c63acb0f1..f8898ee8d06 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -835,7 +835,7 @@ $$(TLIB2_T_$(2)_H_$(3))/$$(FT_LIB): \ tmp/$$(FT).rc \ $$(SREQ2_T_$(2)_H_$(3)) @$$(call E, compile_and_link: $$@) - $$(STAGE2_T_$(2)_H_$(3)) --lib -o $$@ $$< \ + $$(STAGE2_T_$(2)_H_$(3)) --crate-type=dylib --out-dir $$(@D) $$< \ -L "$$(RT_OUTPUT_DIR_$(2))" $(3)/test/$$(FT_DRIVER)-$(2)$$(X_$(2)): \ diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 0503790ae94..adb81803ab0 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -245,7 +245,7 @@ actual:\n\ }; // FIXME (#9639): This needs to handle non-utf8 paths let mut args = ~[~"-", - ~"--no-trans", ~"--lib", + ~"--no-trans", ~"--crate-type=lib", ~"--target=" + target, ~"-L", config.build_base.as_str().unwrap().to_owned(), ~"-L", @@ -659,7 +659,7 @@ fn compile_test_(config: &config, props: &TestProps, // FIXME (#9639): This needs to handle non-utf8 paths let link_args = ~[~"-L", aux_dir.as_str().unwrap().to_owned()]; let args = make_compile_args(config, props, link_args + extra_args, - make_exe_name, testfile); + |a, b| ThisFile(make_exe_name(a, b)), testfile); compose_and_run_compiler(config, props, testfile, args, None) } @@ -702,8 +702,12 @@ fn compose_and_run_compiler( let abs_ab = config.aux_base.join(rel_ab.as_slice()); let aux_props = load_props(&abs_ab); let aux_args = - make_compile_args(config, &aux_props, ~[~"--dylib"] + extra_link_args, - |a,b| make_lib_name(a, b, testfile), &abs_ab); + make_compile_args(config, &aux_props, ~[~"--crate-type=dylib"] + + extra_link_args, + |a,b| { + let f = make_lib_name(a, b, testfile); + ThisDirectory(f.dir_path()) + }, &abs_ab); let auxres = compose_and_run(config, &abs_ab, aux_args, ~[], config.compile_lib_path, None); if !auxres.status.success() { @@ -741,10 +745,15 @@ fn compose_and_run(config: &config, testfile: &Path, prog, args, procenv, input); } +enum TargetLocation { + ThisFile(Path), + ThisDirectory(Path), +} + fn make_compile_args(config: &config, props: &TestProps, extras: ~[~str], - xform: |&config, &Path| -> Path, + xform: |&config, &Path| -> TargetLocation, testfile: &Path) -> ProcArgs { let xform_file = xform(config, testfile); @@ -755,10 +764,14 @@ fn make_compile_args(config: &config, }; // FIXME (#9639): This needs to handle non-utf8 paths let mut args = ~[testfile.as_str().unwrap().to_owned(), - ~"-o", xform_file.as_str().unwrap().to_owned(), ~"-L", config.build_base.as_str().unwrap().to_owned(), ~"--target=" + target] + extras; + let path = match xform_file { + ThisFile(path) => { args.push(~"-o"); path } + ThisDirectory(path) => { args.push(~"--out-dir"); path } + }; + args.push(path.as_str().unwrap().to_owned()); args.push_all_move(split_maybe_args(&config.rustcflags)); args.push_all_move(split_maybe_args(&props.compile_flags)); return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args}; @@ -1043,10 +1056,10 @@ fn compile_test_and_save_bitcode(config: &config, props: &TestProps, let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths let link_args = ~[~"-L", aux_dir.as_str().unwrap().to_owned()]; - let llvm_args = ~[~"-c", ~"--lib", ~"--save-temps"]; + let llvm_args = ~[~"--emit=obj", ~"--crate-type=lib", ~"--save-temps"]; let args = make_compile_args(config, props, link_args + llvm_args, - make_o_name, testfile); + |a, b| ThisFile(make_o_name(a, b)), testfile); compose_and_run_compiler(config, props, testfile, args, None) } diff --git a/src/doc/rust.md b/src/doc/rust.md index c95bfee4ace..b412fa4967d 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -3678,43 +3678,43 @@ found in the [ffi tutorial][ffi]. In one session of compilation, the compiler can generate multiple artifacts through the usage of command line flags and the `crate_type` attribute. -* `--bin`, `#[crate_type = "bin"]` - A runnable executable will be produced. - This requires that there is a `main` function in the crate which will be run - when the program begins executing. This will link in all Rust and native - dependencies, producing a distributable binary. +* `--crate-type=bin`, `#[crate_type = "bin"]` - A runnable executable will be + produced. This requires that there is a `main` function in the crate which + will be run when the program begins executing. This will link in all Rust and + native dependencies, producing a distributable binary. -* `--lib`, `#[crate_type = "lib"]` - A Rust library will be produced. This is - an ambiguous concept as to what exactly is produced because a library can - manifest itself in several forms. The purpose of this generic `lib` option is - to generate the "compiler recommended" style of library. The output library - will always be usable by rustc, but the actual type of library may change - from time-to-time. The remaining output types are all different flavors of - libraries, and the `lib` type can be seen as an alias for one of them (but - the actual one is compiler-defined). +* `--crate-type=lib`, `#[crate_type = "lib"]` - A Rust library will be produced. + This is an ambiguous concept as to what exactly is produced because a library + can manifest itself in several forms. The purpose of this generic `lib` option + is to generate the "compiler recommended" style of library. The output library + will always be usable by rustc, but the actual type of library may change from + time-to-time. The remaining output types are all different flavors of + libraries, and the `lib` type can be seen as an alias for one of them (but the + actual one is compiler-defined). -* `--dylib`, `#[crate_type = "dylib"]` - A dynamic Rust library will be - produced. This is different from the `lib` output type in that this forces +* `--crate-type=dylib`, `#[crate_type = "dylib"]` - A dynamic Rust library will + be produced. This is different from the `lib` output type in that this forces dynamic library generation. The resulting dynamic library can be used as a dependency for other libraries and/or executables. This output type will create `*.so` files on linux, `*.dylib` files on osx, and `*.dll` files on windows. -* `--staticlib`, `#[crate_type = "staticlib"]` - A static system library will - be produced. This is different from other library outputs in that the Rust - compiler will never attempt to link to `staticlib` outputs. The purpose of - this output type is to create a static library containing all of the local - crate's code along with all upstream dependencies. The static library is - actually a `*.a` archive on linux and osx and a `*.lib` file on windows. This - format is recommended for use in situtations such as linking Rust code into an - existing non-Rust application because it will not have dynamic dependencies on - other Rust code. +* `--crate-type=staticlib`, `#[crate_type = "staticlib"]` - A static system + library will be produced. This is different from other library outputs in that + the Rust compiler will never attempt to link to `staticlib` outputs. The + purpose of this output type is to create a static library containing all of + the local crate's code along with all upstream dependencies. The static + library is actually a `*.a` archive on linux and osx and a `*.lib` file on + windows. This format is recommended for use in situtations such as linking + Rust code into an existing non-Rust application because it will not have + dynamic dependencies on other Rust code. -* `--rlib`, `#[crate_type = "rlib"]` - A "Rust library" file will be produced. - This is used as an intermediate artifact and can be thought of as a "static - Rust library". These `rlib` files, unlike `staticlib` files, are interpreted - by the Rust compiler in future linkage. This essentially means that `rustc` - will look for metadata in `rlib` files like it looks for metadata in dynamic - libraries. This form of output is used to produce statically linked +* `--crate-type=rlib`, `#[crate_type = "rlib"]` - A "Rust library" file will be + produced. This is used as an intermediate artifact and can be thought of as a + "static Rust library". These `rlib` files, unlike `staticlib` files, are + interpreted by the Rust compiler in future linkage. This essentially means + that `rustc` will look for metadata in `rlib` files like it looks for metadata + in dynamic libraries. This form of output is used to produce statically linked executables as well as `staticlib` outputs. Note that these outputs are stackable in the sense that if multiple are @@ -3769,9 +3769,9 @@ dependencies will be used: then the compiler will force all dependencies to be dynamic and will generate errors if dynamic versions could not be found. -In general, `--bin` or `--lib` should be sufficient for all compilation needs, -and the other options are just available if more fine-grained control is desired -over the output format of a Rust crate. +In general, `--crate-type=bin` or `--crate-type=lib` should be sufficient for +all compilation needs, and the other options are just available if more +fine-grained control is desired over the output format of a Rust crate. ### Logging system diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 75a5840a1ef..7010eb4e48d 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -3162,8 +3162,8 @@ fn main() { println!("hello {}", world::explore()); } Now compile and run like this (adjust to your platform if necessary): ~~~~ {.notrust} -> rustc --lib world.rs # compiles libworld--0.42.so -> rustc main.rs -L . # compiles main +> rustc --crate-type=lib world.rs # compiles libworld--0.42.so +> rustc main.rs -L . # compiles main > ./main "hello world" ~~~~ diff --git a/src/etc/zsh/_rust b/src/etc/zsh/_rust index 03a8712283c..f1f9e88f7c9 100644 --- a/src/etc/zsh/_rust +++ b/src/etc/zsh/_rust @@ -7,18 +7,15 @@ typeset -A opt_args _rustc_opts_switches=( --android-cross-path'[The path to the Android NDK]' --ar'[Program to use for managing archives instead of the default.]' - --bin'[Compile an executable crate (default)]' -c'[Compile and assemble, but do not link]' --cfg'[Configure the compilation environment]' --crate-id'[Output the crate id and exit]' --crate-file-name'[Output the file(s) that would be written if compilation continued and exit]' --crate-name'[Output the crate name and exit]' --dep-info'[Output dependency info to after compiling]' - --dylib'[Compile a dynamic library crate]' - --emit-llvm'[Produce an LLVM bitcode file]' + --crate-type'[Specify the type of crate to crate]' {-h,--help}'[Display this message]' -L'[Add a directory to the library search path]' - --lib'[Compile a library crate]' --linker'[Program to use for linking instead of the default.]' --link-args'[FLAGS is a space-separated list of flags passed to the linker]' --llvm-args'[A list of arguments to pass to llvm, comma separated]' @@ -33,10 +30,7 @@ _rustc_opts_switches=( --parse-only'[Parse only; do not compile, assemble, or link]' --passes'[Comma or space separated list of pass names to use]' --pretty'[Pretty-print the input instead of compiling]' - --rlib'[Compile a rust library crate as an rlib file]' - -S'[Compile only; do not assemble or link]' --save-temps'[Write intermediate files (.bc, .opt.bc, .o) in addition to normal output]' - --staticlib'[Compile a static library crate]' --sysroot'[Override the system root]' --test'[Build a test harness]' --target'[Target triple cpu-manufacturer-kernel\[-os\] to compile]' diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index aea9b65087d..62fdff49168 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -11,7 +11,7 @@ use back::archive::{Archive, METADATA_FILENAME}; use back::rpath; -use driver::driver::CrateTranslation; +use driver::driver::{CrateTranslation, OutputFilenames}; use driver::session::Session; use driver::session; use lib::llvm::llvm; @@ -44,9 +44,8 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::crateid::CrateId; -#[deriving(Clone, Eq)] +#[deriving(Clone, Eq, TotalOrd, TotalEq)] pub enum OutputType { - OutputTypeNone, OutputTypeBitcode, OutputTypeAssembly, OutputTypeLlvmAssembly, @@ -90,7 +89,7 @@ pub mod write { use back::link::{OutputTypeAssembly, OutputTypeBitcode}; use back::link::{OutputTypeExe, OutputTypeLlvmAssembly}; use back::link::{OutputTypeObject}; - use driver::driver::CrateTranslation; + use driver::driver::{CrateTranslation, OutputFilenames}; use driver::session::Session; use driver::session; use lib::llvm::llvm; @@ -101,7 +100,6 @@ pub mod write { use std::c_str::ToCStr; use std::libc::{c_uint, c_int}; - use std::path::Path; use std::run; use std::str; @@ -125,8 +123,8 @@ pub mod write { pub fn run_passes(sess: Session, trans: &CrateTranslation, - output_type: OutputType, - output: &Path) { + output_types: &[OutputType], + output: &OutputFilenames) { let llmod = trans.module; let llcx = trans.context; unsafe { @@ -209,10 +207,11 @@ pub mod write { // Emit the bytecode if we're either saving our temporaries or // emitting an rlib. Whenever an rlib is created, the bytecode is // inserted into the archive in order to allow LTO against it. - let outputs = sess.outputs.borrow(); + let crate_types = sess.crate_types.borrow(); if sess.opts.save_temps || - outputs.get().iter().any(|&o| o == session::OutputRlib) { - output.with_extension("bc").with_c_str(|buf| { + (crate_types.get().contains(&session::CrateTypeRlib) && + sess.opts.output_types.contains(&OutputTypeExe)) { + output.temp_path(OutputTypeBitcode).with_c_str(|buf| { llvm::LLVMWriteBitcodeToFile(llmod, buf); }) } @@ -247,52 +246,68 @@ pub mod write { } } - time(sess.time_passes(), "codegen passes", (), |()| { - match output_type { - OutputTypeNone => {} + let mut object_file = None; + let mut needs_metadata = false; + for output_type in output_types.iter() { + let path = output.path(*output_type); + match *output_type { OutputTypeBitcode => { - output.with_c_str(|buf| { + path.with_c_str(|buf| { llvm::LLVMWriteBitcodeToFile(llmod, buf); }) } OutputTypeLlvmAssembly => { - output.with_c_str(|output| { + path.with_c_str(|output| { with_codegen(tm, llmod, |cpm| { llvm::LLVMRustPrintModule(cpm, llmod, output); }) }) } OutputTypeAssembly => { - with_codegen(tm, llmod, |cpm| { - WriteOutputFile(sess, tm, cpm, llmod, output, - lib::llvm::AssemblyFile); - }); - // 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_type != OutputTypeAssembly { - with_codegen(tm, trans.metadata_module, |cpm| { - let out = output.with_extension("metadata.o"); - WriteOutputFile(sess, tm, cpm, - trans.metadata_module, &out, - lib::llvm::ObjectFile); - }) - } - } - OutputTypeExe | OutputTypeObject => { + let ty = OutputTypeAssembly; + let path = if sess.opts.output_types.contains(&ty) { + path + } else { + needs_metadata = true; + output.temp_path(OutputTypeAssembly) + }; with_codegen(tm, llmod, |cpm| { - WriteOutputFile(sess, tm, cpm, llmod, output, + WriteOutputFile(sess, tm, cpm, llmod, &path, + lib::llvm::AssemblyFile); + }); + } + OutputTypeObject => { + object_file = Some(path); + } + OutputTypeExe => { + object_file = Some(output.temp_path(OutputTypeObject)); + needs_metadata = true; + } + } + } + + time(sess.time_passes(), "codegen passes", (), |()| { + match object_file { + Some(ref path) => { + with_codegen(tm, llmod, |cpm| { + WriteOutputFile(sess, tm, cpm, llmod, path, lib::llvm::ObjectFile); }); - with_codegen(tm, trans.metadata_module, |cpm| { - let out = output.with_extension("metadata.o"); - WriteOutputFile(sess, tm, cpm, - trans.metadata_module, &out, - lib::llvm::ObjectFile); - }) } + None => {} + } + if needs_metadata { + with_codegen(tm, trans.metadata_module, |cpm| { + let out = output.temp_path(OutputTypeObject) + .with_extension("metadata.o"); + WriteOutputFile(sess, tm, cpm, + trans.metadata_module, &out, + lib::llvm::ObjectFile); + }) } }); @@ -304,8 +319,10 @@ pub mod write { } } - pub fn run_assembler(sess: Session, assembly: &Path, object: &Path) { + pub fn run_assembler(sess: Session, outputs: &OutputFilenames) { let cc = super::get_cc_prog(sess); + let assembly = outputs.temp_path(OutputTypeAssembly); + let object = outputs.path(OutputTypeObject); // FIXME (#9639): This needs to handle non-utf8 paths let args = [ @@ -480,9 +497,8 @@ pub mod write { * system linkers understand. */ -pub fn build_link_meta(sess: Session, - attrs: &[ast::Attribute], - output: &Path, +pub fn build_link_meta(attrs: &[ast::Attribute], + output: &OutputFilenames, symbol_hasher: &mut Sha256) -> LinkMeta { // This calculates CMH as defined above @@ -493,14 +509,7 @@ pub fn build_link_meta(sess: Session, } let crateid = match attr::find_crateid(attrs) { - None => { - let stem = session::expect( - sess, - output.filestem_str(), - || format!("output file name '{}' doesn't appear to have a stem", - output.display())); - from_str(stem).unwrap() - } + None => from_str(output.out_filestem).unwrap(), Some(s) => s, }; @@ -794,20 +803,21 @@ fn remove(sess: Session, path: &Path) { /// of the requested outputs for this compilation session. pub fn link_binary(sess: Session, trans: &CrateTranslation, - obj_filename: &Path, - out_filename: &Path, + outputs: &OutputFilenames, lm: &LinkMeta) -> ~[Path] { let mut out_filenames = ~[]; - let outputs = sess.outputs.borrow(); - for &output in outputs.get().iter() { - let out_file = link_binary_output(sess, trans, output, obj_filename, - out_filename, lm); + let crate_types = sess.crate_types.borrow(); + for &crate_type in crate_types.get().iter() { + let out_file = link_binary_output(sess, trans, crate_type, outputs, lm); out_filenames.push(out_file); } // Remove the temporary object file and metadata if we aren't saving temps if !sess.opts.save_temps { - remove(sess, obj_filename); + let obj_filename = outputs.temp_path(OutputTypeObject); + if !sess.opts.output_types.contains(&OutputTypeObject) { + remove(sess, &obj_filename); + } remove(sess, &obj_filename.with_extension("metadata.o")); } @@ -821,14 +831,14 @@ fn is_writeable(p: &Path) -> bool { } } -pub fn filename_for_input(sess: &Session, output: session::OutputStyle, lm: &LinkMeta, - out_filename: &Path) -> Path { +pub fn filename_for_input(sess: &Session, crate_type: session::CrateType, + lm: &LinkMeta, out_filename: &Path) -> Path { let libname = output_lib_filename(lm); - match output { - session::OutputRlib => { + match crate_type { + session::CrateTypeRlib => { out_filename.with_filename(format!("lib{}.rlib", libname)) } - session::OutputDylib => { + session::CrateTypeDylib => { let (prefix, suffix) = match sess.targ_cfg.os { abi::OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), abi::OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), @@ -838,27 +848,32 @@ pub fn filename_for_input(sess: &Session, output: session::OutputStyle, lm: &Lin }; out_filename.with_filename(format!("{}{}{}", prefix, libname, suffix)) } - session::OutputStaticlib => { + session::CrateTypeStaticlib => { out_filename.with_filename(format!("lib{}.a", libname)) } - session::OutputExecutable => out_filename.clone(), + session::CrateTypeExecutable => out_filename.clone(), } - } fn link_binary_output(sess: Session, trans: &CrateTranslation, - output: session::OutputStyle, - obj_filename: &Path, - out_filename: &Path, + crate_type: session::CrateType, + outputs: &OutputFilenames, lm: &LinkMeta) -> Path { - let out_filename = filename_for_input(&sess, output, lm, out_filename); + let obj_filename = outputs.temp_path(OutputTypeObject); + let out_filename = match outputs.single_output_file { + Some(ref file) => file.clone(), + None => { + let out_filename = outputs.path(OutputTypeExe); + filename_for_input(&sess, crate_type, lm, &out_filename) + } + }; // Make sure the output and obj_filename are both writeable. // Mac, FreeBSD, and Windows system linkers check this already -- // however, the Linux linker will happily overwrite a read-only file. // We should be consistent. - let obj_is_writeable = is_writeable(obj_filename); + let obj_is_writeable = is_writeable(&obj_filename); let out_is_writeable = is_writeable(&out_filename); if !out_is_writeable { sess.fatal(format!("Output file {} is not writeable -- check its permissions.", @@ -869,18 +884,18 @@ fn link_binary_output(sess: Session, obj_filename.display())); } - match output { - session::OutputRlib => { - link_rlib(sess, Some(trans), obj_filename, &out_filename); + match crate_type { + session::CrateTypeRlib => { + link_rlib(sess, Some(trans), &obj_filename, &out_filename); } - session::OutputStaticlib => { - link_staticlib(sess, obj_filename, &out_filename); + session::CrateTypeStaticlib => { + link_staticlib(sess, &obj_filename, &out_filename); } - session::OutputExecutable => { - link_natively(sess, false, obj_filename, &out_filename); + session::CrateTypeExecutable => { + link_natively(sess, false, &obj_filename, &out_filename); } - session::OutputDylib => { - link_natively(sess, true, obj_filename, &out_filename); + session::CrateTypeDylib => { + link_natively(sess, true, &obj_filename, &out_filename); } } @@ -954,7 +969,8 @@ fn link_rlib(sess: Session, // into the archive. let bc = obj_filename.with_extension("bc"); a.add_file(&bc, false); - if !sess.opts.save_temps { + if !sess.opts.save_temps && + !sess.opts.output_types.contains(&OutputTypeBitcode) { remove(sess, &bc); } diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 3fbcd377b8b..3c7d804435f 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -26,10 +26,10 @@ pub fn run(sess: session::Session, llmod: ModuleRef, } // Make sure we actually can run LTO - let outputs = sess.outputs.borrow(); - for output in outputs.get().iter() { - match *output { - session::OutputExecutable | session::OutputStaticlib => {} + let crate_types = sess.crate_types.borrow(); + for crate_type in crate_types.get().iter() { + match *crate_type { + session::CrateTypeExecutable | session::CrateTypeStaticlib => {} _ => { sess.fatal("lto can only be run for executables and \ static library outputs"); diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index c3b851b76ac..9d03fbb6061 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -11,7 +11,7 @@ use back::link; use back::{arm, x86, x86_64, mips}; -use driver::session::{Aggressive, OutputExecutable}; +use driver::session::{Aggressive, CrateTypeExecutable}; use driver::session::{Session, Session_, No, Less, Default}; use driver::session; use front; @@ -182,7 +182,7 @@ pub fn phase_2_configure_and_expand(sess: Session, let time_passes = sess.time_passes(); sess.building_library.set(session::building_library(sess.opts, &crate)); - sess.outputs.set(session::collect_outputs(&sess, crate.attrs)); + sess.crate_types.set(session::collect_crate_types(&sess, crate.attrs)); time(time_passes, "gated feature checking", (), |_| front::feature_gate::check_crate(sess, &crate)); @@ -373,8 +373,7 @@ pub fn phase_4_translate_to_llvm(sess: Session, analysis: &CrateAnalysis, outputs: &OutputFilenames) -> CrateTranslation { time(sess.time_passes(), "translation", crate, |crate| - trans::base::trans_crate(sess, crate, analysis, - &outputs.obj_filename)) + trans::base::trans_crate(sess, crate, analysis, outputs)) } /// Run LLVM itself, producing a bitcode file, assembly file or object file @@ -382,29 +381,24 @@ pub fn phase_4_translate_to_llvm(sess: Session, pub fn phase_5_run_llvm_passes(sess: Session, trans: &CrateTranslation, outputs: &OutputFilenames) { - if sess.no_integrated_as() { let output_type = link::OutputTypeAssembly; - let asm_filename = outputs.obj_filename.with_extension("s"); time(sess.time_passes(), "LLVM passes", (), |_| - link::write::run_passes(sess, - trans, - output_type, - &asm_filename)); + link::write::run_passes(sess, trans, [output_type], outputs)); - link::write::run_assembler(sess, &asm_filename, &outputs.obj_filename); + link::write::run_assembler(sess, outputs); // Remove assembly source, unless --save-temps was specified if !sess.opts.save_temps { - fs::unlink(&asm_filename).unwrap(); + fs::unlink(&outputs.temp_path(link::OutputTypeAssembly)).unwrap(); } } else { time(sess.time_passes(), "LLVM passes", (), |_| link::write::run_passes(sess, trans, - sess.opts.output_type, - &outputs.obj_filename)); + sess.opts.output_types, + outputs)); } } @@ -416,8 +410,7 @@ pub fn phase_6_link_output(sess: Session, time(sess.time_passes(), "linking", (), |_| link::link_binary(sess, trans, - &outputs.obj_filename, - &outputs.out_filename, + outputs, &trans.link)); } @@ -446,24 +439,34 @@ pub fn stop_after_phase_2(sess: Session) -> bool { } pub fn stop_after_phase_5(sess: Session) -> bool { - if sess.opts.output_type != link::OutputTypeExe { + if !sess.opts.output_types.iter().any(|&i| i == link::OutputTypeExe) { debug!("not building executable, returning early from compile_input"); return true; } return false; } -fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, - crate: &ast::Crate) -> io::IoResult<()> -{ - let lm = link::build_link_meta(sess, crate.attrs, &outputs.obj_filename, +fn write_out_deps(sess: Session, + input: &Input, + outputs: &OutputFilenames, + crate: &ast::Crate) -> io::IoResult<()> { + let lm = link::build_link_meta(crate.attrs, outputs, &mut ::util::sha2::Sha256::new()); - let sess_outputs = sess.outputs.borrow(); - let out_filenames = sess_outputs.get().iter() - .map(|&output| link::filename_for_input(&sess, output, &lm, - &outputs.out_filename)) - .to_owned_vec(); + let mut out_filenames = ~[]; + for output_type in sess.opts.output_types.iter() { + let file = outputs.path(*output_type); + match *output_type { + link::OutputTypeExe => { + let crate_types = sess.crate_types.borrow(); + for output in crate_types.get().iter() { + let p = link::filename_for_input(&sess, *output, &lm, &file); + out_filenames.push(p); + } + } + _ => { out_filenames.push(file); } + } + } // Write out dependency rules to the dep-info file if requested with // --dep-info @@ -473,12 +476,7 @@ fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, // Use default filename: crate source filename with extension replaced // by ".d" (true, None) => match *input { - FileInput(ref input_path) => { - let filestem = input_path.filestem().expect("input file must \ - have stem"); - let filename = out_filenames[0].dir_path().join(filestem); - filename.with_extension("d") - }, + FileInput(..) => outputs.with_extension("d"), StrInput(..) => { sess.warn("can not write --dep-info without a filename \ when compiling stdin."); @@ -526,19 +524,19 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input, let outputs = build_output_filenames(input, outdir, output, expanded_crate.attrs, sess); - write_out_deps(sess, input, outputs, &expanded_crate).unwrap(); + write_out_deps(sess, input, &outputs, &expanded_crate).unwrap(); if stop_after_phase_2(sess) { return; } let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map); if stop_after_phase_3(sess) { return; } let trans = phase_4_translate_to_llvm(sess, expanded_crate, - &analysis, outputs); + &analysis, &outputs); (outputs, trans) }; - phase_5_run_llvm_passes(sess, &trans, outputs); + 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, &outputs); } struct IdentifiedAnnotation { @@ -735,22 +733,19 @@ pub fn build_session_options(binary: ~str, matches: &getopts::Matches, demitter: @diagnostic::Emitter) -> @session::Options { - let mut outputs = ~[]; - if matches.opt_present("lib") { - outputs.push(session::default_lib_output()); - } - if matches.opt_present("rlib") { - outputs.push(session::OutputRlib) - } - if matches.opt_present("staticlib") { - outputs.push(session::OutputStaticlib) - } - if matches.opt_present("dylib") { - outputs.push(session::OutputDylib) - } - if matches.opt_present("bin") { - outputs.push(session::OutputExecutable) - } + let crate_types = matches.opt_strs("crate-type").flat_map(|s| { + s.split(',').map(|part| { + match part { + "lib" => session::default_lib_output(), + "rlib" => session::CrateTypeRlib, + "staticlib" => session::CrateTypeStaticlib, + "dylib" => session::CrateTypeDylib, + "bin" => session::CrateTypeExecutable, + _ => early_error(demitter, + format!("unknown crate type: `{}`", part)) + } + }).collect() + }); let parse_only = matches.opt_present("parse-only"); let no_trans = matches.opt_present("no-trans"); @@ -801,19 +796,30 @@ pub fn build_session_options(binary: ~str, unsafe { llvm::LLVMSetDebug(1); } } - let output_type = - if parse_only || no_trans { - link::OutputTypeNone - } else if matches.opt_present("S") && - matches.opt_present("emit-llvm") { - link::OutputTypeLlvmAssembly - } else if matches.opt_present("S") { - link::OutputTypeAssembly - } else if matches.opt_present("c") { - link::OutputTypeObject - } else if matches.opt_present("emit-llvm") { - link::OutputTypeBitcode - } else { link::OutputTypeExe }; + let mut output_types = if parse_only || no_trans { + ~[] + } else { + matches.opt_strs("emit").flat_map(|s| { + s.split(',').map(|part| { + match part.as_slice() { + "asm" => link::OutputTypeAssembly, + "ir" => link::OutputTypeLlvmAssembly, + "bc" => link::OutputTypeBitcode, + "obj" => link::OutputTypeObject, + "link" => link::OutputTypeExe, + _ => early_error(demitter, + format!("unknown emission type: `{}`", + part)) + } + }).collect() + }) + }; + output_types.sort(); + output_types.dedup(); + if output_types.len() == 0 { + output_types.push(link::OutputTypeExe); + } + let sysroot_opt = matches.opt_str("sysroot").map(|m| @Path::new(m)); let target = matches.opt_str("target").unwrap_or(host_triple()); let target_cpu = matches.opt_str("target-cpu").unwrap_or(~"generic"); @@ -886,7 +892,7 @@ pub fn build_session_options(binary: ~str, matches.opt_present("crate-file-name")); let sopts = @session::Options { - outputs: outputs, + crate_types: crate_types, gc: gc, optimize: opt_level, custom_passes: custom_passes, @@ -895,7 +901,7 @@ pub fn build_session_options(binary: ~str, extra_debuginfo: extra_debuginfo, lint_opts: lint_opts, save_temps: save_temps, - output_type: output_type, + output_types: output_types, addl_lib_search_paths: @RefCell::new(addl_lib_search_paths), ar: ar, linker: linker, @@ -972,7 +978,7 @@ pub fn build_session_(sopts: @session::Options, working_dir: os::getcwd(), lints: RefCell::new(HashMap::new()), node_id: Cell::new(1), - outputs: @RefCell::new(~[]), + crate_types: @RefCell::new(~[]), } } @@ -994,20 +1000,15 @@ pub fn parse_pretty(sess: Session, name: &str) -> PpMode { // rustc command line options pub fn optgroups() -> ~[getopts::groups::OptGroup] { ~[ - optflag("c", "", "Compile and assemble, but do not link"), - optmulti("", "cfg", "Configure the compilation - environment", "SPEC"), - optflag("", "emit-llvm", - "Produce an LLVM assembly file if used with -S option; - produce an LLVM bitcode file otherwise"), - optflag("h", "help","Display this message"), - optmulti("L", "", "Add a directory to the library search path", - "PATH"), - optflag("", "bin", "Compile an executable crate (default)"), - optflag("", "lib", "Compile a rust library crate using the compiler's default"), - optflag("", "rlib", "Compile a rust library crate as an rlib file"), - optflag("", "staticlib", "Compile a static library crate"), - optflag("", "dylib", "Compile a dynamic library crate"), + optflag("h", "help", "Display this message"), + optmulti("", "cfg", "Configure the compilation environment", "SPEC"), + optmulti("L", "", "Add a directory to the library search path", "PATH"), + optmulti("", "crate-type", "Comma separated list of types of crates for the \ + compiler to emit", + "[bin|lib|rlib|dylib|staticlib]"), + optmulti("", "emit", "Comma separated list of types of output for the compiler + to emit", + "[asm|bc|ir|obj|link]"), optopt("", "linker", "Program to use for linking instead of the default.", "LINKER"), optopt("", "ar", "Program to use for managing archives instead of the default.", "AR"), optflag("", "crate-id", "Output the crate id and exit"), @@ -1045,7 +1046,6 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] { typed (crates expanded, with type annotations), or identified (fully parenthesized, AST nodes and blocks with IDs)", "TYPE"), - optflag("S", "", "Compile only; do not assemble or link"), optflagopt("", "dep-info", "Output dependency info to after compiling", "FILENAME"), optflag("", "save-temps", @@ -1081,8 +1081,35 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] { } pub struct OutputFilenames { - out_filename: Path, - obj_filename: Path + out_directory: Path, + out_filestem: ~str, + single_output_file: Option, +} + +impl OutputFilenames { + pub fn path(&self, flavor: link::OutputType) -> Path { + match self.single_output_file { + Some(ref path) => return path.clone(), + None => {} + } + self.temp_path(flavor) + } + + pub fn temp_path(&self, flavor: link::OutputType) -> Path { + let base = self.out_directory.join(self.out_filestem.as_slice()); + match flavor { + link::OutputTypeBitcode => base.with_extension("bc"), + link::OutputTypeAssembly => base.with_extension("s"), + link::OutputTypeLlvmAssembly => base.with_extension("ll"), + link::OutputTypeObject => base.with_extension("o"), + link::OutputTypeExe => base, + } + } + + pub fn with_extension(&self, extension: &str) -> Path { + let stem = self.out_filestem.as_slice(); + self.out_directory.join(stem).with_extension(extension) + } } pub fn build_output_filenames(input: &Input, @@ -1090,83 +1117,53 @@ pub fn build_output_filenames(input: &Input, ofile: &Option, attrs: &[ast::Attribute], sess: Session) - -> ~OutputFilenames { - let obj_path; - let out_path; - let sopts = sess.opts; - let stop_after_codegen = sopts.output_type != link::OutputTypeExe; - - let obj_suffix = match sopts.output_type { - link::OutputTypeNone => ~"none", - link::OutputTypeBitcode => ~"bc", - link::OutputTypeAssembly => ~"s", - link::OutputTypeLlvmAssembly => ~"ll", - // Object and exe output both use the '.o' extension here - link::OutputTypeObject | link::OutputTypeExe => ~"o" - }; - + -> OutputFilenames { match *ofile { - None => { - // "-" as input file will cause the parser to read from stdin so we - // have to make up a name - // We want to toss everything after the final '.' - let dirpath = match *odir { - Some(ref d) => (*d).clone(), - None => match *input { - StrInput(_) => os::getcwd(), - FileInput(ref ifile) => (*ifile).dir_path() - } - }; + None => { + // "-" as input file will cause the parser to read from stdin so we + // have to make up a name + // We want to toss everything after the final '.' + let dirpath = match *odir { + Some(ref d) => d.clone(), + None => os::getcwd(), + }; - let mut stem = match *input { - // FIXME (#9639): This needs to handle non-utf8 paths - FileInput(ref ifile) => { - (*ifile).filestem_str().unwrap().to_str() - } - StrInput(_) => ~"rust_out" - }; + let mut stem = match *input { + // FIXME (#9639): This needs to handle non-utf8 paths + FileInput(ref ifile) => ifile.filestem_str().unwrap().to_str(), + StrInput(_) => ~"rust_out" + }; - // If a crateid is present, we use it as the link name - let crateid = attr::find_crateid(attrs); - match crateid { - None => {} - Some(crateid) => stem = crateid.name.to_str(), - } - - if sess.building_library.get() { - out_path = dirpath.join(os::dll_filename(stem)); - obj_path = { - let mut p = dirpath.join(stem); - p.set_extension(obj_suffix); - p - }; - } else { - out_path = dirpath.join(stem); - obj_path = out_path.with_extension(obj_suffix); - } - } - - Some(ref out_file) => { - out_path = out_file.clone(); - obj_path = if stop_after_codegen { - out_file.clone() - } else { - out_file.with_extension(obj_suffix) - }; - - if sess.building_library.get() { - sess.warn("ignoring specified output filename for library."); + // If a crateid is present, we use it as the link name + let crateid = attr::find_crateid(attrs); + match crateid { + None => {} + Some(crateid) => stem = crateid.name.to_str(), + } + OutputFilenames { + out_directory: dirpath, + out_filestem: stem, + single_output_file: None, + } } - if *odir != None { - sess.warn("ignoring --out-dir flag due to -o flag."); + Some(ref out_file) => { + let ofile = if sess.opts.output_types.len() > 1 { + sess.warn("ignoring specified output filename because multiple \ + outputs were requested"); + None + } else { + Some(out_file.clone()) + }; + if *odir != None { + sess.warn("ignoring --out-dir flag due to -o flag."); + } + OutputFilenames { + out_directory: out_file.dir_path(), + out_filestem: out_file.filestem_str().unwrap().to_str(), + single_output_file: ofile, + } } - } - } - - ~OutputFilenames { - out_filename: out_path, - obj_filename: obj_path } } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 4ef97e9234a..859d09b5962 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -9,7 +9,6 @@ // except according to those terms. -use back::link; use back::target_strs; use back; use driver::driver::host_triple; @@ -139,7 +138,7 @@ pub enum OptLevel { pub struct Options { // The crate config requested for the session, which may be combined // with additional crate configurations during the compile process - outputs: ~[OutputStyle], + crate_types: ~[CrateType], gc: bool, optimize: OptLevel, @@ -149,7 +148,7 @@ pub struct Options { extra_debuginfo: bool, lint_opts: ~[(lint::Lint, lint::level)], save_temps: bool, - output_type: back::link::OutputType, + output_types: ~[back::link::OutputType], // 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. @@ -192,11 +191,11 @@ pub enum EntryFnType { } #[deriving(Eq, Clone, TotalOrd, TotalEq)] -pub enum OutputStyle { - OutputExecutable, - OutputDylib, - OutputRlib, - OutputStaticlib, +pub enum CrateType { + CrateTypeExecutable, + CrateTypeDylib, + CrateTypeRlib, + CrateTypeStaticlib, } pub struct Session_ { @@ -219,7 +218,7 @@ pub struct Session_ { lints: RefCell>, node_id: Cell, - outputs: @RefCell<~[OutputStyle]>, + crate_types: @RefCell<~[CrateType]>, } pub type Session = @Session_; @@ -374,7 +373,7 @@ impl Session_ { /// Some reasonable defaults pub fn basic_options() -> @Options { @Options { - outputs: ~[], + crate_types: ~[], gc: false, optimize: No, custom_passes: ~[], @@ -383,7 +382,7 @@ pub fn basic_options() -> @Options { extra_debuginfo: false, lint_opts: ~[], save_temps: false, - output_type: link::OutputTypeExe, + output_types: ~[], addl_lib_search_paths: @RefCell::new(HashSet::new()), ar: None, linker: None, @@ -413,10 +412,10 @@ pub fn expect(sess: Session, opt: Option, msg: || -> ~str) -> T { pub fn building_library(options: &Options, crate: &ast::Crate) -> bool { if options.test { return false } - for output in options.outputs.iter() { + for output in options.crate_types.iter() { match *output { - OutputExecutable => {} - OutputStaticlib | OutputDylib | OutputRlib => return true + CrateTypeExecutable => {} + CrateTypeStaticlib | CrateTypeDylib | CrateTypeRlib => return true } } match syntax::attr::first_attr_value_str_by_name(crate.attrs, "crate_type") { @@ -430,30 +429,30 @@ pub fn building_library(options: &Options, crate: &ast::Crate) -> bool { } } -pub fn default_lib_output() -> OutputStyle { - OutputRlib +pub fn default_lib_output() -> CrateType { + CrateTypeRlib } -pub fn collect_outputs(session: &Session, - attrs: &[ast::Attribute]) -> ~[OutputStyle] { +pub fn collect_crate_types(session: &Session, + attrs: &[ast::Attribute]) -> ~[CrateType] { // If we're generating a test executable, then ignore all other output // styles at all other locations if session.opts.test { - return ~[OutputExecutable]; + return ~[CrateTypeExecutable]; } - let mut base = session.opts.outputs.clone(); + let mut base = session.opts.crate_types.clone(); let mut iter = attrs.iter().filter_map(|a| { if a.name().equiv(&("crate_type")) { match a.value_str() { - Some(ref n) if n.equiv(&("rlib")) => Some(OutputRlib), - Some(ref n) if n.equiv(&("dylib")) => Some(OutputDylib), + Some(ref n) if n.equiv(&("rlib")) => Some(CrateTypeRlib), + Some(ref n) if n.equiv(&("dylib")) => Some(CrateTypeDylib), Some(ref n) if n.equiv(&("lib")) => { Some(default_lib_output()) } Some(ref n) if n.equiv(&("staticlib")) => { - Some(OutputStaticlib) + Some(CrateTypeStaticlib) } - Some(ref n) if n.equiv(&("bin")) => Some(OutputExecutable), + Some(ref n) if n.equiv(&("bin")) => Some(CrateTypeExecutable), Some(_) => { session.add_lint(lint::UnknownCrateType, ast::CRATE_NODE_ID, @@ -473,7 +472,7 @@ pub fn collect_outputs(session: &Session, }); base.extend(&mut iter); if base.len() == 0 { - base.push(OutputExecutable); + base.push(CrateTypeExecutable); } base.sort(); base.dedup(); diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 52ddc8c8108..13b38d2e2bc 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -302,12 +302,12 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) { } if crate_file_name { - let lm = link::build_link_meta(sess, attrs, &t_outputs.obj_filename, + let lm = link::build_link_meta(attrs, &t_outputs, &mut ::util::sha2::Sha256::new()); - let outputs = session::collect_outputs(&sess, attrs); - for &style in outputs.iter() { + let crate_types = session::collect_crate_types(&sess, attrs); + for &style in crate_types.iter() { let fname = link::filename_for_input(&sess, style, &lm, - &t_outputs.out_filename); + &t_outputs.with_extension("")); println!("{}", fname.filename_display()); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 5b4a9617612..485daf3d387 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -28,6 +28,7 @@ use back::link::{mangle_exported_name}; use back::{link, abi}; use driver::session; use driver::session::Session; +use driver::driver::OutputFilenames; use driver::driver::{CrateAnalysis, CrateTranslation}; use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef}; use lib::llvm::{llvm, True, Vector}; @@ -2657,7 +2658,7 @@ pub fn write_metadata(cx: &CrateContext, crate: &ast::Crate) -> ~[u8] { pub fn trans_crate(sess: session::Session, crate: ast::Crate, analysis: &CrateAnalysis, - output: &Path) -> CrateTranslation { + output: &OutputFilenames) -> CrateTranslation { // Before we touch LLVM, make sure that multithreading is enabled. unsafe { use sync::one::{Once, ONCE_INIT}; @@ -2677,7 +2678,7 @@ pub fn trans_crate(sess: session::Session, } let mut symbol_hasher = Sha256::new(); - let link_meta = link::build_link_meta(sess, crate.attrs, output, + let link_meta = link::build_link_meta(crate.attrs, output, &mut symbol_hasher); // Append ".rs" to crate name as LLVM module identifier. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1ad60960de6..174841f282a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -55,7 +55,7 @@ fn get_ast_and_resolve(cpath: &Path, binary: ~"rustdoc", maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()), addl_lib_search_paths: @RefCell::new(libs), - outputs: ~[driver::session::OutputDylib], + crate_types: ~[driver::session::CrateTypeDylib], .. (*rustc::driver::session::basic_options()).clone() }; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 28e62f8fb29..153ab8afaa8 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -18,6 +18,7 @@ use std::str; use extra::tempfile::TempDir; use extra::getopts; use extra::test; +use rustc::back::link; use rustc::driver::driver; use rustc::driver::session; use rustc::metadata::creader::Loader; @@ -43,7 +44,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int { binary: ~"rustdoc", maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()), addl_lib_search_paths: libs, - outputs: ~[session::OutputDylib], + crate_types: ~[session::CrateTypeDylib], .. (*session::basic_options()).clone() }; @@ -104,8 +105,9 @@ fn runtest(test: &str, cratename: &str, libs: HashSet) { binary: ~"rustdoctest", maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()), addl_lib_search_paths: @RefCell::new(libs), - outputs: ~[session::OutputExecutable], + crate_types: ~[session::CrateTypeExecutable], debugging_opts: session::PREFER_DYNAMIC, + output_types: ~[link::OutputTypeExe], .. (*session::basic_options()).clone() }; diff --git a/src/test/run-make/crate-data-smoke/Makefile b/src/test/run-make/crate-data-smoke/Makefile index 09ae0998202..5009ed15ee6 100644 --- a/src/test/run-make/crate-data-smoke/Makefile +++ b/src/test/run-make/crate-data-smoke/Makefile @@ -4,7 +4,7 @@ all: [ `$(RUSTC) --crate-id crate.rs` = "foo#0.10-pre" ] [ `$(RUSTC) --crate-name crate.rs` = "foo" ] [ `$(RUSTC) --crate-file-name crate.rs` = "foo" ] - [ `$(RUSTC) --crate-file-name --lib --test crate.rs` = "foo" ] + [ `$(RUSTC) --crate-file-name --crate-type=lib --test crate.rs` = "foo" ] [ `$(RUSTC) --crate-file-name --test lib.rs` = "mylib" ] $(RUSTC) --crate-file-name lib.rs $(RUSTC) --crate-file-name rlib.rs diff --git a/src/test/run-make/dep-info-custom/Makefile b/src/test/run-make/dep-info-custom/Makefile index 7a1f99ac2d5..72ce26ee6c6 100644 --- a/src/test/run-make/dep-info-custom/Makefile +++ b/src/test/run-make/dep-info-custom/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk all: - $(RUSTC) --dep-info $(TMPDIR)/custom-deps-file.d --lib lib.rs + $(RUSTC) --dep-info $(TMPDIR)/custom-deps-file.d --crate-type=lib lib.rs sleep 1 touch foo.rs -rm -f $(TMPDIR)/done diff --git a/src/test/run-make/dep-info-custom/Makefile.foo b/src/test/run-make/dep-info-custom/Makefile.foo index 95e736deb41..302bb84908b 100644 --- a/src/test/run-make/dep-info-custom/Makefile.foo +++ b/src/test/run-make/dep-info-custom/Makefile.foo @@ -1,7 +1,7 @@ -LIB := $(shell $(RUSTC) --crate-file-name --lib lib.rs) +LIB := $(shell $(RUSTC) --crate-file-name --crate-type=lib lib.rs) $(TMPDIR)/$(LIB): - $(RUSTC) --dep-info $(TMPDIR)/custom-deps-file.d --lib lib.rs + $(RUSTC) --dep-info $(TMPDIR)/custom-deps-file.d --crate-type=lib lib.rs touch $(TMPDIR)/done -include $(TMPDIR)/custom-deps-file.d diff --git a/src/test/run-make/dep-info/Makefile b/src/test/run-make/dep-info/Makefile index 36a43b4c455..00a59383176 100644 --- a/src/test/run-make/dep-info/Makefile +++ b/src/test/run-make/dep-info/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk all: - $(RUSTC) --dep-info --lib lib.rs + $(RUSTC) --dep-info --crate-type=lib lib.rs sleep 1 touch foo.rs -rm -f $(TMPDIR)/done diff --git a/src/test/run-make/dep-info/Makefile.foo b/src/test/run-make/dep-info/Makefile.foo index 2a1ce715e28..2b43dd0ec70 100644 --- a/src/test/run-make/dep-info/Makefile.foo +++ b/src/test/run-make/dep-info/Makefile.foo @@ -1,7 +1,7 @@ -LIB := $(shell $(RUSTC) --crate-file-name --lib lib.rs) +LIB := $(shell $(RUSTC) --crate-file-name --crate-type=lib lib.rs) $(TMPDIR)/$(LIB): - $(RUSTC) --dep-info --lib lib.rs + $(RUSTC) --dep-info --crate-type=lib lib.rs touch $(TMPDIR)/done --include $(TMPDIR)/lib.d +-include $(TMPDIR)/foo.d diff --git a/src/test/run-make/duplicate-output-flavors/Makefile b/src/test/run-make/duplicate-output-flavors/Makefile index a93a7ce8448..d40b6862a01 100644 --- a/src/test/run-make/duplicate-output-flavors/Makefile +++ b/src/test/run-make/duplicate-output-flavors/Makefile @@ -1,4 +1,4 @@ include ../tools.mk all: - $(RUSTC) --rlib foo.rs + $(RUSTC) --crate-type=rlib foo.rs diff --git a/src/test/run-make/mixing-libs/Makefile b/src/test/run-make/mixing-libs/Makefile index eb00c801390..533a6933a6d 100644 --- a/src/test/run-make/mixing-libs/Makefile +++ b/src/test/run-make/mixing-libs/Makefile @@ -3,7 +3,7 @@ all: $(RUSTC) rlib.rs $(RUSTC) dylib.rs && exit 1 || exit 0 - $(RUSTC) rlib.rs --dylib + $(RUSTC) rlib.rs --crate-type=dylib $(RUSTC) dylib.rs rm $(call DYLIB,rlib-*) $(RUSTC) prog.rs && exit 1 || exit 0 diff --git a/src/test/run-make/no-intermediate-extras/Makefile b/src/test/run-make/no-intermediate-extras/Makefile index 89186b2ad4d..258cbf04c61 100644 --- a/src/test/run-make/no-intermediate-extras/Makefile +++ b/src/test/run-make/no-intermediate-extras/Makefile @@ -3,5 +3,5 @@ -include ../tools.mk all: - $(RUSTC) --rlib --test foo.rs + $(RUSTC) --crate-type=rlib --test foo.rs rm $(TMPDIR)/foo.bc && exit 1 || exit 0 diff --git a/src/test/run-make/output-type-permutations/Makefile b/src/test/run-make/output-type-permutations/Makefile new file mode 100644 index 00000000000..72f96b21fa8 --- /dev/null +++ b/src/test/run-make/output-type-permutations/Makefile @@ -0,0 +1,42 @@ +-include ../tools.mk + +all: + $(RUSTC) foo.rs --crate-type=rlib,dylib,staticlib + rm $(TMPDIR)/$(call RLIB_GLOB,bar) + rm $(TMPDIR)/$(call DYLIB_GLOB,bar) + rm $(TMPDIR)/$(call STATICLIB_GLOB,bar) + $(RUSTC) foo.rs --crate-type=bin + rm $(TMPDIR)/bar + $(RUSTC) foo.rs --emit=asm,ir,bc,obj,link + rm $(TMPDIR)/bar.ll + rm $(TMPDIR)/bar.bc + rm $(TMPDIR)/bar.s + rm $(TMPDIR)/bar.o + rm $(TMPDIR)/bar + $(RUSTC) foo.rs --emit=asm,ir,bc,obj,link --crate-type=staticlib + rm $(TMPDIR)/bar.ll + rm $(TMPDIR)/bar.bc + rm $(TMPDIR)/bar.s + rm $(TMPDIR)/bar.o + rm $(TMPDIR)/$(call STATICLIB_GLOB,bar) + $(RUSTC) foo.rs --emit=asm -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit=bc -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit=ir -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit=obj -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit=link -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit=bc,link --crate-type=rlib + rm $(TMPDIR)/bar.bc + rm $(TMPDIR)/$(call RLIB_GLOB,bar) diff --git a/src/test/run-make/output-type-permutations/foo.rs b/src/test/run-make/output-type-permutations/foo.rs new file mode 100644 index 00000000000..3d944fd7a58 --- /dev/null +++ b/src/test/run-make/output-type-permutations/foo.rs @@ -0,0 +1,3 @@ +#[crate_id = "bar"]; + +fn main() {} diff --git a/src/test/run-make/prefer-dylib/Makefile b/src/test/run-make/prefer-dylib/Makefile index 8229547176a..6fb7434e68a 100644 --- a/src/test/run-make/prefer-dylib/Makefile +++ b/src/test/run-make/prefer-dylib/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk all: - $(RUSTC) bar.rs --dylib --rlib + $(RUSTC) bar.rs --crate-type=dylib --crate-type=rlib $(RUSTC) foo.rs -Z prefer-dynamic $(call RUN,foo) rm $(TMPDIR)/*bar* diff --git a/src/test/run-make/prefer-rlib/Makefile b/src/test/run-make/prefer-rlib/Makefile index eedb70c4efd..c6a239eef08 100644 --- a/src/test/run-make/prefer-rlib/Makefile +++ b/src/test/run-make/prefer-rlib/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk all: - $(RUSTC) bar.rs --dylib --rlib + $(RUSTC) bar.rs --crate-type=dylib --crate-type=rlib ls $(TMPDIR)/$(call RLIB_GLOB,bar) $(RUSTC) foo.rs rm $(TMPDIR)/*bar* diff --git a/src/test/run-make/simple-dylib/Makefile b/src/test/run-make/simple-dylib/Makefile index d4f215c69f0..84e6e079e6f 100644 --- a/src/test/run-make/simple-dylib/Makefile +++ b/src/test/run-make/simple-dylib/Makefile @@ -1,5 +1,5 @@ -include ../tools.mk all: - $(RUSTC) bar.rs --dylib + $(RUSTC) bar.rs --crate-type=dylib $(RUSTC) foo.rs $(call RUN,foo) diff --git a/src/test/run-make/simple-rlib/Makefile b/src/test/run-make/simple-rlib/Makefile index e8909ef134b..7b156cb8748 100644 --- a/src/test/run-make/simple-rlib/Makefile +++ b/src/test/run-make/simple-rlib/Makefile @@ -1,5 +1,5 @@ -include ../tools.mk all: - $(RUSTC) bar.rs --rlib + $(RUSTC) bar.rs --crate-type=rlib $(RUSTC) foo.rs $(call RUN,foo) diff --git a/src/test/run-make/volatile-intrinsics/Makefile b/src/test/run-make/volatile-intrinsics/Makefile index fc19412e2ef..bf79ca68c94 100644 --- a/src/test/run-make/volatile-intrinsics/Makefile +++ b/src/test/run-make/volatile-intrinsics/Makefile @@ -5,6 +5,6 @@ all: $(RUSTC) main.rs $(call RUN,main) # ... and the loads/stores must not be optimized out. - $(RUSTC) main.rs --emit-llvm -S + $(RUSTC) main.rs --emit=ir grep "load volatile" $(TMPDIR)/main.ll grep "store volatile" $(TMPDIR)/main.ll