auto merge of #15319 : alexcrichton/rust/no-crate-id, r=brson
This is an implementation of [RFC 35](https://github.com/rust-lang/rfcs/blob/master/active/0035-remove-crate-id.md). The summary for this PR is the same as that of the RFC, with one addendum: * Removes the `#[crate_id]` attribute and knowledge of versions from rustc. * Added a `#[crate_name]` attribute similar to the old `#[crate_id]` attribute * Output filenames no longer have versions or hashes * Symbols no longer have versions (they still have hashes) * A new flag, `--extern`, is used to override searching for external crates * A new flag, `-C metadata=foo`, used when hashing symbols * [added] An old flag, `--crate-name`, was re purposed to specify the crate name from the command line. I tried to maintain backwards compatibility wherever possible (with warnings being printed). If I missed anywhere, however, please let me know! [breaking-change] Closes #14468 Closes #14469 Closes #14470 Closes #14471
This commit is contained in:
commit
c3ef04be55
@ -16,6 +16,8 @@
|
||||
CFG_RELEASE_NUM=0.11.0
|
||||
CFG_RELEASE_LABEL=
|
||||
|
||||
CFG_FILENAME_EXTRA=4e7c5e5c
|
||||
|
||||
ifndef CFG_ENABLE_NIGHTLY
|
||||
# This is the normal version string
|
||||
CFG_RELEASE=$(CFG_RELEASE_NUM)$(CFG_RELEASE_LABEL)
|
||||
|
11
mk/target.mk
11
mk/target.mk
@ -44,6 +44,13 @@ $(foreach host,$(CFG_HOST), \
|
||||
$(foreach crate,$(CRATES), \
|
||||
$(eval $(call RUST_CRATE_FULLDEPS,$(stage),$(target),$(host),$(crate)))))))
|
||||
|
||||
# NOTE: after a stage0 snap this should be just EXTRA_FILENAME, not with a stage
|
||||
# bound
|
||||
EXTRA_FILENAME_0 =
|
||||
EXTRA_FILENAME_1 = -C extra-filename=-$(CFG_FILENAME_EXTRA)
|
||||
EXTRA_FILENAME_2 = -C extra-filename=-$(CFG_FILENAME_EXTRA)
|
||||
EXTRA_FILENAME_3 = -C extra-filename=-$(CFG_FILENAME_EXTRA)
|
||||
|
||||
# RUST_TARGET_STAGE_N template: This defines how target artifacts are built
|
||||
# for all stage/target architecture combinations. This is one giant rule which
|
||||
# works as follows:
|
||||
@ -85,7 +92,9 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
|
||||
-L "$$(LLVM_LIBDIR_$(2))" \
|
||||
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
|
||||
$$(RUSTFLAGS_$(4)) \
|
||||
--out-dir $$(@D) $$<
|
||||
--out-dir $$(@D) \
|
||||
$$(EXTRA_FILENAME_$(1)) \
|
||||
$$<
|
||||
@touch $$@
|
||||
$$(call LIST_ALL_OLD_GLOB_MATCHES,\
|
||||
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
|
||||
|
@ -60,7 +60,8 @@
|
||||
//! by libc malloc/free. The `libc_heap` module is defined to be wired up to
|
||||
//! the system malloc/free.
|
||||
|
||||
#![crate_id = "alloc#0.11.0"]
|
||||
#![crate_id = "alloc#0.11.0"] // NOTE: remove after a stage0 snap
|
||||
#![crate_name = "alloc"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -70,6 +71,7 @@
|
||||
|
||||
#![no_std]
|
||||
#![feature(lang_items, phase, unsafe_destructor)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[phase(plugin, link)]
|
||||
extern crate core;
|
||||
|
@ -20,6 +20,7 @@
|
||||
//! more complex, slower Arena which can hold objects of any type.
|
||||
|
||||
#![crate_id = "arena#0.11.0"]
|
||||
#![crate_name = "arena"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -30,6 +31,7 @@
|
||||
|
||||
#![feature(unsafe_destructor)]
|
||||
#![allow(missing_doc)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp;
|
||||
|
@ -12,7 +12,8 @@
|
||||
* Collection types.
|
||||
*/
|
||||
|
||||
#![crate_id = "collections#0.11.0"]
|
||||
#![crate_id = "collections#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "collections"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![license = "MIT/ASL2"]
|
||||
@ -24,6 +25,7 @@
|
||||
#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
|
||||
#![feature(unsafe_destructor)]
|
||||
#![no_std]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[phase(plugin, link)] extern crate core;
|
||||
extern crate alloc;
|
||||
|
@ -48,6 +48,7 @@
|
||||
// separate crate, libcoretest, to avoid bizarre issues.
|
||||
|
||||
#![crate_id = "core#0.11.0"]
|
||||
#![crate_name = "core"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -60,6 +61,7 @@
|
||||
#![feature(globs, intrinsics, lang_items, macro_rules, managed_boxes, phase)]
|
||||
#![feature(simd, unsafe_destructor)]
|
||||
#![deny(missing_doc)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
mod macros;
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
//! Additionally, it is not guaranteed that functionality such as reflection
|
||||
//! will persist into the future.
|
||||
|
||||
#![crate_id = "debug#0.11.0"]
|
||||
#![crate_id = "debug#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "debug"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -27,6 +28,7 @@
|
||||
#![experimental]
|
||||
#![feature(managed_boxes, macro_rules)]
|
||||
#![allow(experimental)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
pub mod fmt;
|
||||
pub mod reflect;
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "flate#0.11.0"]
|
||||
#![crate_id = "flate#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "flate"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -27,6 +28,7 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![feature(phase)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
||||
|
@ -14,12 +14,14 @@
|
||||
//! Parsing does not happen at runtime: structures of `std::fmt::rt` are
|
||||
//! generated instead.
|
||||
|
||||
#![crate_id = "fmt_macros#0.11.0"]
|
||||
#![crate_id = "fmt_macros#0.11.0"] // NOTE: remove after stage0c
|
||||
#![crate_name = "fmt_macros"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
#![feature(macro_rules, globs)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
use std::char;
|
||||
use std::str;
|
||||
|
@ -39,7 +39,8 @@ fn main() {
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "fourcc#0.11.0"]
|
||||
#![crate_id = "fourcc#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "fourcc"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -47,6 +48,7 @@ fn main() {
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![feature(plugin_registrar, managed_boxes)]
|
||||
|
||||
|
@ -76,7 +76,8 @@
|
||||
//! }
|
||||
//! ~~~
|
||||
|
||||
#![crate_id = "getopts#0.11.0"]
|
||||
#![crate_id = "getopts#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "getopts"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -87,6 +88,7 @@
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(globs, phase)]
|
||||
#![deny(missing_doc)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] extern crate debug;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
@ -23,7 +23,8 @@
|
||||
* `glob`/`fnmatch` functions.
|
||||
*/
|
||||
|
||||
#![crate_id = "glob#0.11.0"]
|
||||
#![crate_id = "glob#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "glob"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -32,6 +33,7 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::{cmp, os, path};
|
||||
|
@ -266,7 +266,8 @@ pub fn main() {
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "graphviz#0.11.0"]
|
||||
#![crate_id = "graphviz#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "graphviz"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -274,8 +275,7 @@ pub fn main() {
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
|
||||
#![experimental]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
use std::io;
|
||||
use std::str;
|
||||
|
@ -197,7 +197,8 @@
|
||||
//! pool.shutdown();
|
||||
//! ```
|
||||
|
||||
#![crate_id = "green#0.11.0"]
|
||||
#![crate_id = "green#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "green"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -208,10 +209,9 @@
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
// NB this does *not* include globs, please keep it that way.
|
||||
#![feature(macro_rules, phase)]
|
||||
#![allow(visible_private_types)]
|
||||
#![allow(deprecated)]
|
||||
#![feature(default_type_params)]
|
||||
#![feature(macro_rules, phase, default_type_params)]
|
||||
#![allow(visible_private_types, deprecated)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
#[cfg(test)] extern crate rustuv;
|
||||
|
@ -36,7 +36,8 @@ fn main() {
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "hexfloat#0.11.0"]
|
||||
#![crate_id = "hexfloat#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "hexfloat"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -45,6 +46,7 @@ fn main() {
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![feature(plugin_registrar, managed_boxes)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
extern crate syntax;
|
||||
extern crate rustc;
|
||||
|
@ -9,7 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(globs)]
|
||||
#![crate_id = "libc#0.11.0"]
|
||||
#![crate_id = "libc#0.11.0"] // NOTE: remove after a stage0 snap
|
||||
#![crate_name = "libc"]
|
||||
#![experimental]
|
||||
#![no_std] // we don't need std, and we can't have std, since it doesn't exist
|
||||
// yet. std depends on us.
|
||||
@ -18,6 +19,7 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
/*!
|
||||
* Bindings for the C standard library and other platform libraries
|
||||
|
@ -105,7 +105,8 @@ fn main() {
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "log#0.11.0"]
|
||||
#![crate_id = "log#0.11.0"] // NOTE: Remove after stage0
|
||||
#![crate_name = "log"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -114,7 +115,7 @@ fn main() {
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
#![feature(macro_rules)]
|
||||
#![deny(missing_doc)]
|
||||
|
||||
|
@ -46,7 +46,8 @@
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![crate_id = "native#0.11.0"]
|
||||
#![crate_id = "native#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "native"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -57,6 +58,7 @@
|
||||
|
||||
#![deny(unused_result, unused_must_use)]
|
||||
#![allow(non_camel_case_types, deprecated)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
#![feature(default_type_params, lang_items)]
|
||||
|
||||
// NB this crate explicitly does *not* allow glob imports, please seriously
|
||||
|
@ -44,7 +44,8 @@
|
||||
|
||||
#![feature(macro_rules)]
|
||||
|
||||
#![crate_id = "num#0.11.0"]
|
||||
#![crate_id = "num#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "num"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -53,7 +54,7 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
#![allow(deprecated)] // from_str_radix
|
||||
|
||||
extern crate rand;
|
||||
|
@ -16,7 +16,8 @@
|
||||
//! is not recommended to use this library directly, but rather the official
|
||||
//! interface through `std::rand`.
|
||||
|
||||
#![crate_id = "rand#0.11.0"]
|
||||
#![crate_id = "rand#0.11.0"] // NOTE: remove after a stage0 snap
|
||||
#![crate_name = "rand"]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
||||
@ -25,6 +26,7 @@
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, phase, globs)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
#![no_std]
|
||||
#![experimental]
|
||||
|
||||
|
@ -353,7 +353,8 @@
|
||||
//! characters in the search text and `m` is the number of instructions in a
|
||||
//! compiled expression.
|
||||
|
||||
#![crate_id = "regex#0.11.0"]
|
||||
#![crate_id = "regex#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "regex"]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
#![experimental]
|
||||
@ -364,6 +365,7 @@
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, phase)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
#![deny(missing_doc)]
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -11,13 +11,15 @@
|
||||
//! This crate provides the `regex!` macro. Its use is documented in the
|
||||
//! `regex` crate.
|
||||
|
||||
#![crate_id = "regex_macros#0.11.0"]
|
||||
#![crate_id = "regex_macros#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "regex_macros"]
|
||||
#![crate_type = "dylib"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![feature(plugin_registrar, managed_boxes, quote)]
|
||||
|
||||
|
@ -20,13 +20,15 @@
|
||||
//! necessary. It is an error to include this library when also linking with
|
||||
//! the system libc library.
|
||||
|
||||
#![crate_id = "rlibc#0.11.0"]
|
||||
#![crate_id = "rlibc#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "rlibc"]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![no_std]
|
||||
#![experimental]
|
||||
|
@ -11,7 +11,7 @@
|
||||
use back::archive::{Archive, METADATA_FILENAME};
|
||||
use back::rpath;
|
||||
use back::svh::Svh;
|
||||
use driver::driver::{CrateTranslation, OutputFilenames};
|
||||
use driver::driver::{CrateTranslation, OutputFilenames, Input, FileInput};
|
||||
use driver::config::NoDebugInfo;
|
||||
use driver::session::Session;
|
||||
use driver::config;
|
||||
@ -19,7 +19,7 @@
|
||||
use lib::llvm::ModuleRef;
|
||||
use lib;
|
||||
use metadata::common::LinkMeta;
|
||||
use metadata::{encoder, cstore, filesearch, csearch, loader};
|
||||
use metadata::{encoder, cstore, filesearch, csearch, loader, creader};
|
||||
use middle::trans::context::CrateContext;
|
||||
use middle::trans::common::gensym_name;
|
||||
use middle::ty;
|
||||
@ -40,9 +40,8 @@
|
||||
use syntax::ast;
|
||||
use syntax::ast_map::{PathElem, PathElems, PathName};
|
||||
use syntax::ast_map;
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
|
||||
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
|
||||
@ -546,32 +545,69 @@ unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
|
||||
* system linkers understand.
|
||||
*/
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
|
||||
pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
|
||||
match attr::find_crateid(attrs) {
|
||||
None => from_str(out_filestem).unwrap_or_else(|| {
|
||||
let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
|
||||
from_str(s.collect::<String>().as_slice())
|
||||
.or(from_str("rust-out")).unwrap()
|
||||
}),
|
||||
Some(s) => s,
|
||||
pub fn find_crate_name(sess: Option<&Session>,
|
||||
attrs: &[ast::Attribute],
|
||||
input: &Input) -> String {
|
||||
use syntax::crateid::CrateId;
|
||||
|
||||
let validate = |s: String, span: Option<Span>| {
|
||||
creader::validate_crate_name(sess, s.as_slice(), span);
|
||||
s
|
||||
};
|
||||
|
||||
match sess {
|
||||
Some(sess) => {
|
||||
match sess.opts.crate_name {
|
||||
Some(ref s) => return validate(s.clone(), None),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
|
||||
.and_then(|at| at.value_str().map(|s| (at, s)));
|
||||
match crate_name {
|
||||
Some((attr, s)) => return validate(s.get().to_string(), Some(attr.span)),
|
||||
None => {}
|
||||
}
|
||||
let crate_id = attrs.iter().find(|at| at.check_name("crate_id"))
|
||||
.and_then(|at| at.value_str().map(|s| (at, s)))
|
||||
.and_then(|(at, s)| {
|
||||
from_str::<CrateId>(s.get()).map(|id| (at, id))
|
||||
});
|
||||
match crate_id {
|
||||
Some((attr, id)) => {
|
||||
match sess {
|
||||
Some(sess) => {
|
||||
sess.span_warn(attr.span, "the #[crate_id] attribute is \
|
||||
deprecated for the \
|
||||
#[crate_name] attribute");
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
return validate(id.name, Some(attr.span))
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
match *input {
|
||||
FileInput(ref path) => {
|
||||
match path.filestem_str() {
|
||||
Some(s) => return validate(s.to_string(), None),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
"rust-out".to_string()
|
||||
}
|
||||
|
||||
pub fn crate_id_hash(crate_id: &CrateId) -> String {
|
||||
// This calculates CMH as defined above. Note that we don't use the path of
|
||||
// the crate id in the hash because lookups are only done by (name/vers),
|
||||
// not by path.
|
||||
let mut s = Sha256::new();
|
||||
s.input_str(crate_id.short_name_with_version().as_slice());
|
||||
truncated_hash_result(&mut s).as_slice().slice_to(8).to_string()
|
||||
}
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
|
||||
pub fn build_link_meta(krate: &ast::Crate, out_filestem: &str) -> LinkMeta {
|
||||
pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
|
||||
name: String) -> LinkMeta {
|
||||
let r = LinkMeta {
|
||||
crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
|
||||
crate_hash: Svh::calculate(krate),
|
||||
crate_name: name,
|
||||
crate_hash: Svh::calculate(sess, krate),
|
||||
};
|
||||
info!("{}", r);
|
||||
return r;
|
||||
@ -594,9 +630,12 @@ fn symbol_hash(tcx: &ty::ctxt,
|
||||
// to be independent of one another in the crate.
|
||||
|
||||
symbol_hasher.reset();
|
||||
symbol_hasher.input_str(link_meta.crateid.name.as_slice());
|
||||
symbol_hasher.input_str(link_meta.crate_name.as_slice());
|
||||
symbol_hasher.input_str("-");
|
||||
symbol_hasher.input_str(link_meta.crate_hash.as_str());
|
||||
for meta in tcx.sess.crate_metadata.borrow().iter() {
|
||||
symbol_hasher.input_str(meta.as_slice());
|
||||
}
|
||||
symbol_hasher.input_str("-");
|
||||
symbol_hasher.input_str(encoder::encoded_ty(tcx, t).as_slice());
|
||||
// Prefix with 'h' so that it never blends into adjacent digits
|
||||
@ -666,8 +705,7 @@ pub fn sanitize(s: &str) -> String {
|
||||
}
|
||||
|
||||
pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
|
||||
hash: Option<&str>,
|
||||
vers: Option<&str>) -> String {
|
||||
hash: Option<&str>) -> String {
|
||||
// Follow C++ namespace-mangling style, see
|
||||
// http://en.wikipedia.org/wiki/Name_mangling for more info.
|
||||
//
|
||||
@ -698,25 +736,13 @@ fn push(n: &mut String, s: &str) {
|
||||
Some(s) => push(&mut n, s),
|
||||
None => {}
|
||||
}
|
||||
match vers {
|
||||
Some(s) => push(&mut n, s),
|
||||
None => {}
|
||||
}
|
||||
|
||||
n.push_char('E'); // End name-sequence.
|
||||
n
|
||||
}
|
||||
|
||||
pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> String {
|
||||
// The version will get mangled to have a leading '_', but it makes more
|
||||
// sense to lead with a 'v' b/c this is a version...
|
||||
let vers = if vers.len() > 0 && !char::is_XID_start(vers.char_at(0)) {
|
||||
format!("v{}", vers)
|
||||
} else {
|
||||
vers.to_string()
|
||||
};
|
||||
|
||||
mangle(path, Some(hash), Some(vers.as_slice()))
|
||||
pub fn exported_name(path: PathElems, hash: &str) -> String {
|
||||
mangle(path, Some(hash))
|
||||
}
|
||||
|
||||
pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
|
||||
@ -741,9 +767,7 @@ pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
|
||||
hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char);
|
||||
hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char);
|
||||
|
||||
exported_name(path,
|
||||
hash.as_slice(),
|
||||
ccx.link_meta.crateid.version_or_default())
|
||||
exported_name(path, hash.as_slice())
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
|
||||
@ -753,15 +777,11 @@ pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
|
||||
let path = [PathName(token::intern(s.as_slice())),
|
||||
gensym_name(name)];
|
||||
let hash = get_symbol_hash(ccx, t);
|
||||
mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
|
||||
mangle(ast_map::Values(path.iter()), Some(hash.as_slice()))
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
|
||||
mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
|
||||
}
|
||||
|
||||
pub fn output_lib_filename(id: &CrateId) -> String {
|
||||
format!("{}-{}-{}", id.name, crate_id_hash(id), id.version_or_default())
|
||||
mangle(path.chain(Some(gensym_name(flav)).move_iter()), None)
|
||||
}
|
||||
|
||||
pub fn get_cc_prog(sess: &Session) -> String {
|
||||
@ -803,14 +823,15 @@ fn remove(sess: &Session, path: &Path) {
|
||||
pub fn link_binary(sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
outputs: &OutputFilenames,
|
||||
id: &CrateId) -> Vec<Path> {
|
||||
crate_name: &str) -> Vec<Path> {
|
||||
let mut out_filenames = Vec::new();
|
||||
for &crate_type in sess.crate_types.borrow().iter() {
|
||||
if invalid_output_for_target(sess, crate_type) {
|
||||
sess.bug(format!("invalid output type `{}` for target os `{}`",
|
||||
crate_type, sess.targ_cfg.os).as_slice());
|
||||
}
|
||||
let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
|
||||
let out_file = link_binary_output(sess, trans, crate_type, outputs,
|
||||
crate_name);
|
||||
out_filenames.push(out_file);
|
||||
}
|
||||
|
||||
@ -859,9 +880,11 @@ fn is_writeable(p: &Path) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
|
||||
id: &CrateId, out_filename: &Path) -> Path {
|
||||
let libname = output_lib_filename(id);
|
||||
pub fn filename_for_input(sess: &Session,
|
||||
crate_type: config::CrateType,
|
||||
name: &str,
|
||||
out_filename: &Path) -> Path {
|
||||
let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
|
||||
match crate_type {
|
||||
config::CrateTypeRlib => {
|
||||
out_filename.with_filename(format!("lib{}.rlib", libname))
|
||||
@ -891,13 +914,13 @@ fn link_binary_output(sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
crate_type: config::CrateType,
|
||||
outputs: &OutputFilenames,
|
||||
id: &CrateId) -> Path {
|
||||
crate_name: &str) -> Path {
|
||||
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, id, &out_filename)
|
||||
filename_for_input(sess, crate_type, crate_name, &out_filename)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -53,6 +53,8 @@
|
||||
use syntax::ast;
|
||||
use syntax::visit;
|
||||
|
||||
use driver::session::Session;
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
pub struct Svh {
|
||||
hash: String,
|
||||
@ -68,7 +70,7 @@ pub fn as_str<'a>(&'a self) -> &'a str {
|
||||
self.hash.as_slice()
|
||||
}
|
||||
|
||||
pub fn calculate(krate: &ast::Crate) -> Svh {
|
||||
pub fn calculate(sess: &Session, krate: &ast::Crate) -> Svh {
|
||||
// FIXME (#14132): This is better than it used to be, but it still not
|
||||
// ideal. We now attempt to hash only the relevant portions of the
|
||||
// Crate AST as well as the top-level crate attributes. (However,
|
||||
@ -80,6 +82,10 @@ pub fn calculate(krate: &ast::Crate) -> Svh {
|
||||
// avoid collisions.
|
||||
let mut state = SipState::new();
|
||||
|
||||
for data in sess.opts.cg.metadata.iter() {
|
||||
data.hash(&mut state);
|
||||
}
|
||||
|
||||
{
|
||||
let mut visit = svh_visitor::make(&mut state);
|
||||
visit::walk_crate(&mut visit, krate, ());
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Contains infrastructure for configuring the compiler, including parsing
|
||||
//! command line options.
|
||||
|
||||
use driver::early_error;
|
||||
use driver::{early_error, early_warn};
|
||||
use driver::driver;
|
||||
use driver::session::Session;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
use syntax::parse;
|
||||
use syntax::parse::token::InternedString;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use getopts::{optopt, optmulti, optflag, optflagopt};
|
||||
use getopts;
|
||||
use lib::llvm::llvm;
|
||||
@ -91,10 +91,12 @@ pub struct Options {
|
||||
pub debugging_opts: u64,
|
||||
/// Whether to write dependency files. It's (enabled, optional filename).
|
||||
pub write_dependency_info: (bool, Option<Path>),
|
||||
/// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name).
|
||||
pub print_metas: (bool, bool, bool),
|
||||
/// Crate id-related things to maybe print. It's (crate_name, crate_file_name).
|
||||
pub print_metas: (bool, bool),
|
||||
pub cg: CodegenOptions,
|
||||
pub color: ColorConfig,
|
||||
pub externs: HashMap<String, Vec<String>>,
|
||||
pub crate_name: Option<String>,
|
||||
}
|
||||
|
||||
/// Some reasonable defaults
|
||||
@ -117,9 +119,11 @@ pub fn basic_options() -> Options {
|
||||
no_analysis: false,
|
||||
debugging_opts: 0,
|
||||
write_dependency_info: (false, None),
|
||||
print_metas: (false, false, false),
|
||||
print_metas: (false, false),
|
||||
cg: basic_codegen_options(),
|
||||
color: Auto,
|
||||
externs: HashMap::new(),
|
||||
crate_name: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,6 +322,10 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
|
||||
"use an external assembler rather than LLVM's integrated one"),
|
||||
relocation_model: String = ("pic".to_string(), parse_string,
|
||||
"choose the relocation model to use (llc -relocation-model for details)"),
|
||||
metadata: Vec<String> = (Vec::new(), parse_list,
|
||||
"metadata to mangle symbol names with"),
|
||||
extra_filename: String = ("".to_string(), parse_string,
|
||||
"extra data to put in each output filename"),
|
||||
)
|
||||
|
||||
pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
|
||||
@ -505,10 +513,12 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
|
||||
"[bin|lib|rlib|dylib|staticlib]"),
|
||||
optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
|
||||
"[asm|bc|ir|obj|link]"),
|
||||
optflag("", "crate-id", "Output the crate id and exit"),
|
||||
optflag("", "crate-name", "Output the crate name and exit"),
|
||||
optflag("", "crate-file-name", "Output the file(s) that would be written if compilation \
|
||||
optopt("", "crate-name", "Specify the name of the crate being built",
|
||||
"NAME"),
|
||||
optflag("", "print-crate-name", "Output the crate name and exit"),
|
||||
optflag("", "print-file-name", "Output the file(s) that would be written if compilation \
|
||||
continued and exit"),
|
||||
optflag("", "crate-file-name", "deprecated in favor of --print-file-name"),
|
||||
optflag("g", "", "Equivalent to --debuginfo=2"),
|
||||
optopt("", "debuginfo", "Emit DWARF debug info to the objects created:
|
||||
0 = no debug info,
|
||||
@ -548,7 +558,9 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
|
||||
optopt("", "color", "Configure coloring of output:
|
||||
auto = colorize, if output goes to a tty (default);
|
||||
always = always colorize output;
|
||||
never = never colorize output", "auto|always|never")
|
||||
never = never colorize output", "auto|always|never"),
|
||||
optmulti("", "extern", "Specify where an external rust library is located",
|
||||
"PATH"),
|
||||
)
|
||||
}
|
||||
|
||||
@ -709,9 +721,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
matches.opt_str("dep-info")
|
||||
.map(|p| Path::new(p)));
|
||||
|
||||
let print_metas = (matches.opt_present("crate-id"),
|
||||
matches.opt_present("crate-name"),
|
||||
let print_metas = (matches.opt_present("print-crate-name"),
|
||||
matches.opt_present("print-file-name") ||
|
||||
matches.opt_present("crate-file-name"));
|
||||
if matches.opt_present("crate-file-name") {
|
||||
early_warn("the --crate-file-name argument has been renamed to \
|
||||
--print-file-name");
|
||||
}
|
||||
let cg = build_codegen_options(matches);
|
||||
|
||||
let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
|
||||
@ -728,6 +744,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
}
|
||||
};
|
||||
|
||||
let mut externs = HashMap::new();
|
||||
for arg in matches.opt_strs("extern").iter() {
|
||||
let mut parts = arg.as_slice().splitn('=', 1);
|
||||
let name = match parts.next() {
|
||||
Some(s) => s,
|
||||
None => early_error("--extern value must not be empty"),
|
||||
};
|
||||
let location = match parts.next() {
|
||||
Some(s) => s,
|
||||
None => early_error("--extern value must be of the format `foo=bar`"),
|
||||
};
|
||||
let locs = externs.find_or_insert(name.to_string(), Vec::new());
|
||||
locs.push(location.to_string());
|
||||
}
|
||||
|
||||
let crate_name = matches.opt_str("crate-name");
|
||||
|
||||
Options {
|
||||
crate_types: crate_types,
|
||||
gc: gc,
|
||||
@ -748,7 +781,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
write_dependency_info: write_dependency_info,
|
||||
print_metas: print_metas,
|
||||
cg: cg,
|
||||
color: color
|
||||
color: color,
|
||||
externs: externs,
|
||||
crate_name: crate_name,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::attr::{AttrMetaMethods};
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::parse;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::{pp, pprust};
|
||||
@ -69,7 +68,7 @@ pub fn compile_input(sess: Session,
|
||||
// large chunks of memory alive and we want to free them as soon as
|
||||
// possible to keep the peak memory usage low
|
||||
let (outputs, trans, sess) = {
|
||||
let (outputs, expanded_crate, ast_map) = {
|
||||
let (outputs, expanded_crate, ast_map, id) = {
|
||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||
if stop_after_phase_1(&sess) { return; }
|
||||
let outputs = build_output_filenames(input,
|
||||
@ -77,25 +76,25 @@ pub fn compile_input(sess: Session,
|
||||
output,
|
||||
krate.attrs.as_slice(),
|
||||
&sess);
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
||||
outputs.out_filestem.as_slice());
|
||||
let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
|
||||
input);
|
||||
let (expanded_crate, ast_map)
|
||||
= match phase_2_configure_and_expand(&sess, krate, &id) {
|
||||
= match phase_2_configure_and_expand(&sess, krate, id.as_slice()) {
|
||||
None => return,
|
||||
Some(p) => p,
|
||||
};
|
||||
|
||||
(outputs, expanded_crate, ast_map)
|
||||
(outputs, expanded_crate, ast_map, id)
|
||||
};
|
||||
write_out_deps(&sess, input, &outputs, &expanded_crate);
|
||||
write_out_deps(&sess, input, &outputs, id.as_slice());
|
||||
|
||||
if stop_after_phase_2(&sess) { return; }
|
||||
|
||||
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
|
||||
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate,
|
||||
ast_map, id);
|
||||
phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
|
||||
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
|
||||
let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
|
||||
analysis, &outputs);
|
||||
let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
|
||||
|
||||
// Discard interned strings as they are no longer required.
|
||||
token::get_ident_interner().clear();
|
||||
@ -181,11 +180,14 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
|
||||
/// Returns `None` if we're aborting after handling -W help.
|
||||
pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
mut krate: ast::Crate,
|
||||
crate_id: &CrateId)
|
||||
crate_name: &str)
|
||||
-> Option<(ast::Crate, syntax::ast_map::Map)> {
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
*sess.crate_types.borrow_mut() = collect_crate_types(sess, krate.attrs.as_slice());
|
||||
*sess.crate_types.borrow_mut() =
|
||||
collect_crate_types(sess, krate.attrs.as_slice());
|
||||
*sess.crate_metadata.borrow_mut() =
|
||||
collect_crate_metadata(sess, krate.attrs.as_slice());
|
||||
|
||||
time(time_passes, "gated feature checking", (), |_|
|
||||
front::feature_gate::check_crate(sess, &krate));
|
||||
@ -247,7 +249,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
}
|
||||
let cfg = syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: sess.features.default_type_params.get(),
|
||||
crate_id: crate_id.clone(),
|
||||
crate_name: crate_name.to_string(),
|
||||
};
|
||||
syntax::ext::expand::expand_crate(&sess.parse_sess,
|
||||
cfg,
|
||||
@ -286,6 +288,7 @@ pub struct CrateAnalysis {
|
||||
pub public_items: middle::privacy::PublicItems,
|
||||
pub ty_cx: ty::ctxt,
|
||||
pub reachable: NodeSet,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
/// Run the resolution, typechecking, region checking and other
|
||||
@ -293,7 +296,8 @@ pub struct CrateAnalysis {
|
||||
/// structures carrying the results of the analysis.
|
||||
pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
krate: &ast::Crate,
|
||||
ast_map: syntax::ast_map::Map) -> CrateAnalysis {
|
||||
ast_map: syntax::ast_map::Map,
|
||||
name: String) -> CrateAnalysis {
|
||||
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
@ -398,6 +402,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
exported_items: exported_items,
|
||||
public_items: public_items,
|
||||
reachable: reachable_map,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,8 +431,7 @@ pub struct CrateTranslation {
|
||||
/// Run the translation phase to LLVM, after which the AST and analysis can
|
||||
/// be discarded.
|
||||
pub fn phase_4_translate_to_llvm(krate: ast::Crate,
|
||||
analysis: CrateAnalysis,
|
||||
outputs: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
|
||||
analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
|
||||
let time_passes = analysis.ty_cx.sess.time_passes();
|
||||
|
||||
time(time_passes, "resolving dependency formats", (), |_|
|
||||
@ -435,7 +439,7 @@ pub fn phase_4_translate_to_llvm(krate: ast::Crate,
|
||||
|
||||
// Option dance to work around the lack of stack once closures.
|
||||
time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
|
||||
trans::base::trans_crate(krate, analysis, outputs))
|
||||
trans::base::trans_crate(krate, analysis))
|
||||
}
|
||||
|
||||
/// Run LLVM itself, producing a bitcode file, assembly file or object file
|
||||
@ -473,7 +477,7 @@ pub fn phase_6_link_output(sess: &Session,
|
||||
link::link_binary(sess,
|
||||
trans,
|
||||
outputs,
|
||||
&trans.link.crateid));
|
||||
trans.link.crate_name.as_slice()));
|
||||
}
|
||||
|
||||
pub fn stop_after_phase_3(sess: &Session) -> bool {
|
||||
@ -514,9 +518,7 @@ pub fn stop_after_phase_5(sess: &Session) -> bool {
|
||||
fn write_out_deps(sess: &Session,
|
||||
input: &Input,
|
||||
outputs: &OutputFilenames,
|
||||
krate: &ast::Crate) {
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
||||
outputs.out_filestem.as_slice());
|
||||
id: &str) {
|
||||
|
||||
let mut out_filenames = Vec::new();
|
||||
for output_type in sess.opts.output_types.iter() {
|
||||
@ -524,7 +526,8 @@ fn write_out_deps(sess: &Session,
|
||||
match *output_type {
|
||||
link::OutputTypeExe => {
|
||||
for output in sess.crate_types.borrow().iter() {
|
||||
let p = link::filename_for_input(sess, *output, &id, &file);
|
||||
let p = link::filename_for_input(sess, *output,
|
||||
id, &file);
|
||||
out_filenames.push(p);
|
||||
}
|
||||
}
|
||||
@ -649,13 +652,13 @@ pub fn pretty_print_input(sess: Session,
|
||||
ppm: PpMode,
|
||||
ofile: Option<Path>) {
|
||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
||||
input.filestem().as_slice());
|
||||
let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(), input);
|
||||
|
||||
let (krate, ast_map, is_expanded) = match ppm {
|
||||
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
|
||||
let (krate, ast_map)
|
||||
= match phase_2_configure_and_expand(&sess, krate, &id) {
|
||||
= match phase_2_configure_and_expand(&sess, krate,
|
||||
id.as_slice()) {
|
||||
None => return,
|
||||
Some(p) => p,
|
||||
};
|
||||
@ -695,7 +698,7 @@ pub fn pretty_print_input(sess: Session,
|
||||
}
|
||||
PpmTyped => {
|
||||
let ast_map = ast_map.expect("--pretty=typed missing ast_map");
|
||||
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
||||
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map, id);
|
||||
let annotation = TypedAnnotation {
|
||||
analysis: analysis
|
||||
};
|
||||
@ -728,7 +731,8 @@ pub fn pretty_print_input(sess: Session,
|
||||
}
|
||||
}
|
||||
};
|
||||
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
||||
let analysis = phase_3_run_analysis_passes(sess, &krate,
|
||||
ast_map, id);
|
||||
print_flowgraph(analysis, block, out)
|
||||
}
|
||||
_ => {
|
||||
@ -845,6 +849,11 @@ pub fn collect_crate_types(session: &Session,
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn collect_crate_metadata(session: &Session,
|
||||
_attrs: &[ast::Attribute]) -> Vec<String> {
|
||||
session.opts.cg.metadata.clone()
|
||||
}
|
||||
|
||||
pub struct OutputFilenames {
|
||||
pub out_directory: Path,
|
||||
pub out_filestem: String,
|
||||
@ -893,14 +902,11 @@ pub fn build_output_filenames(input: &Input,
|
||||
None => Path::new(".")
|
||||
};
|
||||
|
||||
let mut stem = input.filestem();
|
||||
|
||||
// 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_string(),
|
||||
}
|
||||
// If a crate name is present, we use it as the link name
|
||||
let stem = match attr::find_crate_name(attrs) {
|
||||
None => input.filestem(),
|
||||
Some(name) => name.get().to_string(),
|
||||
};
|
||||
OutputFilenames {
|
||||
out_directory: dirpath,
|
||||
out_filestem: stem,
|
||||
|
@ -294,28 +294,26 @@ fn print_crate_info(sess: &Session,
|
||||
odir: &Option<Path>,
|
||||
ofile: &Option<Path>)
|
||||
-> bool {
|
||||
let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
|
||||
let (crate_name, crate_file_name) = sess.opts.print_metas;
|
||||
// these nasty nested conditions are to avoid doing extra work
|
||||
if crate_id || crate_name || crate_file_name {
|
||||
if crate_name || crate_file_name {
|
||||
let attrs = parse_crate_attrs(sess, input);
|
||||
let t_outputs = driver::build_output_filenames(input,
|
||||
odir,
|
||||
ofile,
|
||||
attrs.as_slice(),
|
||||
sess);
|
||||
let id = link::find_crate_id(attrs.as_slice(),
|
||||
t_outputs.out_filestem.as_slice());
|
||||
let id = link::find_crate_name(Some(sess), attrs.as_slice(), input);
|
||||
|
||||
if crate_id {
|
||||
println!("{}", id.to_str());
|
||||
}
|
||||
if crate_name {
|
||||
println!("{}", id.name);
|
||||
println!("{}", id);
|
||||
}
|
||||
if crate_file_name {
|
||||
let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
|
||||
let metadata = driver::collect_crate_metadata(sess, attrs.as_slice());
|
||||
*sess.crate_metadata.borrow_mut() = metadata;
|
||||
for &style in crate_types.iter() {
|
||||
let fname = link::filename_for_input(sess, style, &id,
|
||||
let fname = link::filename_for_input(sess, style, id.as_slice(),
|
||||
&t_outputs.with_extension(""));
|
||||
println!("{}", fname.filename_display());
|
||||
}
|
||||
@ -390,6 +388,11 @@ pub fn early_error(msg: &str) -> ! {
|
||||
fail!(diagnostic::FatalError);
|
||||
}
|
||||
|
||||
pub fn early_warn(msg: &str) {
|
||||
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto);
|
||||
emitter.emit(None, msg, diagnostic::Warning);
|
||||
}
|
||||
|
||||
pub fn list_metadata(sess: &Session, path: &Path,
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
|
||||
|
@ -47,6 +47,7 @@ pub struct Session {
|
||||
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
|
||||
pub node_id: Cell<ast::NodeId>,
|
||||
pub crate_types: RefCell<Vec<config::CrateType>>,
|
||||
pub crate_metadata: RefCell<Vec<String>>,
|
||||
pub features: front::feature_gate::Features,
|
||||
|
||||
/// The maximum recursion limit for potentially infinitely recursive
|
||||
@ -243,6 +244,7 @@ pub fn build_session_(sopts: config::Options,
|
||||
lints: RefCell::new(NodeMap::new()),
|
||||
node_id: Cell::new(1),
|
||||
crate_types: RefCell::new(Vec::new()),
|
||||
crate_metadata: RefCell::new(Vec::new()),
|
||||
features: front::feature_gate::Features::new(),
|
||||
recursion_limit: Cell::new(64),
|
||||
};
|
||||
|
@ -25,8 +25,6 @@
|
||||
use std::mem;
|
||||
use std::gc::{Gc, GC};
|
||||
|
||||
pub static VERSION: &'static str = "0.11.0";
|
||||
|
||||
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
|
||||
-> ast::Crate {
|
||||
if use_std(&krate) {
|
||||
@ -60,24 +58,12 @@ struct StandardLibraryInjector<'a> {
|
||||
sess: &'a Session,
|
||||
}
|
||||
|
||||
pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
|
||||
match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
|
||||
Some("1") => None,
|
||||
_ => {
|
||||
Some((token::intern_and_get_ident(format!("{}#{}",
|
||||
krate,
|
||||
VERSION).as_slice()),
|
||||
ast::CookedStr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||
let mut vis = vec!(ast::ViewItem {
|
||||
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
|
||||
with_version("std"),
|
||||
ast::DUMMY_NODE_ID),
|
||||
None,
|
||||
ast::DUMMY_NODE_ID),
|
||||
attrs: vec!(
|
||||
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
|
||||
InternedString::new("phase"),
|
||||
@ -95,8 +81,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||
if use_start(&krate) && any_exe {
|
||||
vis.push(ast::ViewItem {
|
||||
node: ast::ViewItemExternCrate(token::str_to_ident("native"),
|
||||
with_version("native"),
|
||||
ast::DUMMY_NODE_ID),
|
||||
None,
|
||||
ast::DUMMY_NODE_ID),
|
||||
attrs: Vec::new(),
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
use driver::session::Session;
|
||||
use front::config;
|
||||
use front::std_inject::with_version;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::gc::{Gc, GC};
|
||||
@ -154,7 +153,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate)
|
||||
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
|
||||
ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
crate_name: "test".to_string(),
|
||||
}),
|
||||
path: RefCell::new(Vec::new()),
|
||||
testfns: RefCell::new(Vec::new()),
|
||||
@ -298,9 +297,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
||||
ast::DUMMY_NODE_ID))),
|
||||
ast::Public)
|
||||
} else {
|
||||
(ast::ViewItemExternCrate(id_test,
|
||||
with_version("test"),
|
||||
ast::DUMMY_NODE_ID),
|
||||
(ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
|
||||
ast::Inherited)
|
||||
};
|
||||
ast::ViewItem {
|
||||
@ -395,8 +392,8 @@ fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
|
||||
}
|
||||
|
||||
fn is_test_crate(krate: &ast::Crate) -> bool {
|
||||
match attr::find_crateid(krate.attrs.as_slice()) {
|
||||
Some(ref s) if "test" == s.name.as_slice() => true,
|
||||
match attr::find_crate_name(krate.attrs.as_slice()) {
|
||||
Some(ref s) if "test" == s.get().as_slice() => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "rustc#0.11.0"]
|
||||
#![crate_id = "rustc#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "rustc"]
|
||||
#![experimental]
|
||||
#![comment = "The Rust compiler"]
|
||||
#![license = "MIT/ASL2"]
|
||||
@ -31,6 +32,7 @@
|
||||
#![allow(deprecated)]
|
||||
#![feature(macro_rules, globs, struct_variant, managed_boxes, quote)]
|
||||
#![feature(default_type_params, phase, unsafe_destructor)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
extern crate arena;
|
||||
extern crate debug;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use std::mem;
|
||||
use syntax::crateid::CrateId;
|
||||
use back::svh::Svh;
|
||||
|
||||
// EBML enum definitions and utils shared by the encoder and decoder
|
||||
@ -71,9 +70,9 @@
|
||||
pub static tag_crate_dep: uint = 0x19;
|
||||
|
||||
pub static tag_crate_hash: uint = 0x1a;
|
||||
pub static tag_crate_crateid: uint = 0x1b;
|
||||
pub static tag_crate_crate_name: uint = 0x1b;
|
||||
|
||||
pub static tag_crate_dep_crateid: uint = 0x1d;
|
||||
pub static tag_crate_dep_crate_name: uint = 0x1d;
|
||||
pub static tag_crate_dep_hash: uint = 0x1e;
|
||||
|
||||
pub static tag_mod_impl: uint = 0x1f;
|
||||
@ -215,7 +214,7 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
|
||||
|
||||
#[deriving(Clone, Show)]
|
||||
pub struct LinkMeta {
|
||||
pub crateid: CrateId,
|
||||
pub crate_name: String,
|
||||
pub crate_hash: Svh,
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
//! Validates all used crates and extern libraries and loads their metadata
|
||||
|
||||
use back::link;
|
||||
use back::svh::Svh;
|
||||
use driver::session::Session;
|
||||
use driver::{driver, config};
|
||||
@ -33,7 +32,6 @@
|
||||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::visit;
|
||||
|
||||
struct Env<'a> {
|
||||
@ -69,7 +67,7 @@ fn visit_item(&mut self, a: &ast::Item, _: ()) {
|
||||
fn dump_crates(cstore: &CStore) {
|
||||
debug!("resolved crates:");
|
||||
cstore.iter_crate_data_origins(|_, data, opt_source| {
|
||||
debug!("crate_id: {}", data.crate_id());
|
||||
debug!(" name: {}", data.name());
|
||||
debug!(" cnum: {}", data.cnum);
|
||||
debug!(" hash: {}", data.hash());
|
||||
opt_source.map(|cs| {
|
||||
@ -83,20 +81,17 @@ fn dump_crates(cstore: &CStore) {
|
||||
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
|
||||
let mut map = HashMap::new();
|
||||
cstore.iter_crate_data(|cnum, data| {
|
||||
let crateid = data.crate_id();
|
||||
let key = (crateid.name.clone(), crateid.path.clone());
|
||||
map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
|
||||
map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum);
|
||||
});
|
||||
|
||||
for ((name, _), dupes) in map.move_iter() {
|
||||
for (name, dupes) in map.move_iter() {
|
||||
if dupes.len() == 1 { continue }
|
||||
diag.handler().warn(
|
||||
format!("using multiple versions of crate `{}`",
|
||||
name).as_slice());
|
||||
format!("using multiple versions of crate `{}`", name).as_slice());
|
||||
for dupe in dupes.move_iter() {
|
||||
let data = cstore.get_crate_data(dupe);
|
||||
diag.span_note(data.span, "used here");
|
||||
loader::note_crateid_attr(diag, &data.crate_id());
|
||||
loader::note_crate_name(diag, data.name().as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,7 +124,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
||||
let (cnum, _, _) = resolve_crate(e,
|
||||
&None,
|
||||
info.ident.as_slice(),
|
||||
&info.crate_id,
|
||||
info.name.as_slice(),
|
||||
None,
|
||||
i.span);
|
||||
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||
@ -140,7 +135,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
||||
|
||||
struct CrateInfo {
|
||||
ident: String,
|
||||
crate_id: CrateId,
|
||||
name: String,
|
||||
id: ast::NodeId,
|
||||
should_link: bool,
|
||||
}
|
||||
@ -151,22 +146,18 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
let ident = token::get_ident(ident);
|
||||
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
|
||||
ident, path_opt);
|
||||
let crate_id = match *path_opt {
|
||||
let name = match *path_opt {
|
||||
Some((ref path_str, _)) => {
|
||||
let crateid: Option<CrateId> = from_str(path_str.get());
|
||||
match crateid {
|
||||
None => {
|
||||
e.sess.span_err(i.span, "malformed crate id");
|
||||
return None
|
||||
}
|
||||
Some(id) => id
|
||||
}
|
||||
let name = path_str.get().to_str();
|
||||
validate_crate_name(Some(e.sess), name.as_slice(),
|
||||
Some(i.span));
|
||||
name
|
||||
}
|
||||
None => from_str(ident.get().to_str().as_slice()).unwrap()
|
||||
None => ident.get().to_str(),
|
||||
};
|
||||
Some(CrateInfo {
|
||||
ident: ident.get().to_string(),
|
||||
crate_id: crate_id,
|
||||
name: name,
|
||||
id: id,
|
||||
should_link: should_link(i),
|
||||
})
|
||||
@ -175,6 +166,28 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
|
||||
let err = |s: &str| {
|
||||
match (sp, sess) {
|
||||
(_, None) => fail!("{}", s),
|
||||
(Some(sp), Some(sess)) => sess.span_err(sp, s),
|
||||
(None, Some(sess)) => sess.err(s),
|
||||
}
|
||||
};
|
||||
if s.len() == 0 {
|
||||
err("crate name must not be empty");
|
||||
}
|
||||
for c in s.chars() {
|
||||
if c.is_alphanumeric() { continue }
|
||||
if c == '_' || c == '-' { continue }
|
||||
err(format!("invalid character `{}` in crate name: `{}`", c, s).as_slice());
|
||||
}
|
||||
match sess {
|
||||
Some(sess) => sess.abort_if_errors(),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item(e: &Env, i: &ast::Item) {
|
||||
match i.node {
|
||||
ast::ItemForeignMod(ref fm) => {
|
||||
@ -263,17 +276,36 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
||||
}
|
||||
}
|
||||
|
||||
fn existing_match(e: &Env, crate_id: &CrateId,
|
||||
fn existing_match(e: &Env, name: &str,
|
||||
hash: Option<&Svh>) -> Option<ast::CrateNum> {
|
||||
let mut ret = None;
|
||||
e.sess.cstore.iter_crate_data(|cnum, data| {
|
||||
let other_id = data.crate_id();
|
||||
if crate_id.matches(&other_id) {
|
||||
let other_hash = data.hash();
|
||||
match hash {
|
||||
Some(hash) if *hash != other_hash => {}
|
||||
Some(..) | None => { ret = Some(cnum); }
|
||||
if data.name().as_slice() != name { return }
|
||||
|
||||
match hash {
|
||||
Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
|
||||
Some(..) => return,
|
||||
None => {}
|
||||
}
|
||||
|
||||
// When the hash is None we're dealing with a top-level dependency in
|
||||
// which case we may have a specification on the command line for this
|
||||
// library. Even though an upstream library may have loaded something of
|
||||
// the same name, we have to make sure it was loaded from the exact same
|
||||
// location as well.
|
||||
let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
|
||||
let dylib = source.dylib.as_ref().map(|p| p.as_vec());
|
||||
let rlib = source.rlib.as_ref().map(|p| p.as_vec());
|
||||
match e.sess.opts.externs.find_equiv(&name) {
|
||||
Some(locs) => {
|
||||
let found = locs.iter().any(|l| {
|
||||
Some(l.as_bytes()) == dylib || Some(l.as_bytes()) == rlib
|
||||
});
|
||||
if found {
|
||||
ret = Some(cnum);
|
||||
}
|
||||
}
|
||||
None => ret = Some(cnum),
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
@ -282,7 +314,7 @@ fn existing_match(e: &Env, crate_id: &CrateId,
|
||||
fn register_crate<'a>(e: &mut Env,
|
||||
root: &Option<CratePaths>,
|
||||
ident: &str,
|
||||
crate_id: &CrateId,
|
||||
name: &str,
|
||||
span: Span,
|
||||
lib: loader::Library)
|
||||
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
|
||||
@ -309,7 +341,7 @@ fn register_crate<'a>(e: &mut Env,
|
||||
let loader::Library{ dylib, rlib, metadata } = lib;
|
||||
|
||||
let cmeta = Rc::new( cstore::crate_metadata {
|
||||
name: crate_id.name.to_string(),
|
||||
name: name.to_string(),
|
||||
data: metadata,
|
||||
cnum_map: cnum_map,
|
||||
cnum: cnum,
|
||||
@ -330,20 +362,18 @@ fn register_crate<'a>(e: &mut Env,
|
||||
fn resolve_crate<'a>(e: &mut Env,
|
||||
root: &Option<CratePaths>,
|
||||
ident: &str,
|
||||
crate_id: &CrateId,
|
||||
name: &str,
|
||||
hash: Option<&Svh>,
|
||||
span: Span)
|
||||
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
|
||||
cstore::CrateSource) {
|
||||
match existing_match(e, crate_id, hash) {
|
||||
match existing_match(e, name, hash) {
|
||||
None => {
|
||||
let id_hash = link::crate_id_hash(crate_id);
|
||||
let mut load_ctxt = loader::Context {
|
||||
sess: e.sess,
|
||||
span: span,
|
||||
ident: ident,
|
||||
crate_id: crate_id,
|
||||
id_hash: id_hash.as_slice(),
|
||||
crate_name: name,
|
||||
hash: hash.map(|a| &*a),
|
||||
filesearch: e.sess.target_filesearch(),
|
||||
os: e.sess.targ_cfg.os,
|
||||
@ -351,9 +381,10 @@ fn resolve_crate<'a>(e: &mut Env,
|
||||
root: root,
|
||||
rejected_via_hash: vec!(),
|
||||
rejected_via_triple: vec!(),
|
||||
should_match_name: true,
|
||||
};
|
||||
let library = load_ctxt.load_library_crate();
|
||||
register_crate(e, root, ident, crate_id, span, library)
|
||||
register_crate(e, root, ident, name, span, library)
|
||||
}
|
||||
Some(cnum) => (cnum,
|
||||
e.sess.cstore.get_crate_data(cnum),
|
||||
@ -370,10 +401,10 @@ fn resolve_crate_deps(e: &mut Env,
|
||||
// The map from crate numbers in the crate we're resolving to local crate
|
||||
// numbers
|
||||
decoder::get_crate_deps(cdata).iter().map(|dep| {
|
||||
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
|
||||
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
|
||||
let (local_cnum, _, _) = resolve_crate(e, root,
|
||||
dep.crate_id.name.as_slice(),
|
||||
&dep.crate_id,
|
||||
dep.name.as_slice(),
|
||||
dep.name.as_slice(),
|
||||
Some(&dep.hash),
|
||||
span);
|
||||
(dep.cnum, local_cnum)
|
||||
@ -399,14 +430,12 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
|
||||
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
|
||||
let is_cross = target_triple != driver::host_triple();
|
||||
let mut should_link = info.should_link && !is_cross;
|
||||
let id_hash = link::crate_id_hash(&info.crate_id);
|
||||
let os = config::get_os(driver::host_triple()).unwrap();
|
||||
let mut load_ctxt = loader::Context {
|
||||
sess: self.env.sess,
|
||||
span: krate.span,
|
||||
ident: info.ident.as_slice(),
|
||||
crate_id: &info.crate_id,
|
||||
id_hash: id_hash.as_slice(),
|
||||
crate_name: info.name.as_slice(),
|
||||
hash: None,
|
||||
filesearch: self.env.sess.host_filesearch(),
|
||||
triple: driver::host_triple(),
|
||||
@ -414,6 +443,7 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
|
||||
root: &None,
|
||||
rejected_via_hash: vec!(),
|
||||
rejected_via_triple: vec!(),
|
||||
should_match_name: true,
|
||||
};
|
||||
let library = match load_ctxt.maybe_load_library_crate() {
|
||||
Some (l) => l,
|
||||
@ -448,10 +478,11 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
|
||||
macros: macros,
|
||||
registrar_symbol: registrar,
|
||||
};
|
||||
if should_link && existing_match(&self.env, &info.crate_id, None).is_none() {
|
||||
if should_link && existing_match(&self.env, info.name.as_slice(),
|
||||
None).is_none() {
|
||||
// register crate now to avoid double-reading metadata
|
||||
register_crate(&mut self.env, &None, info.ident.as_slice(),
|
||||
&info.crate_id, krate.span, library);
|
||||
info.name.as_slice(), krate.span, library);
|
||||
}
|
||||
pc
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
use std::rc::Rc;
|
||||
use std::collections::HashMap;
|
||||
use syntax::ast;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::IdentInterner;
|
||||
|
||||
@ -220,7 +219,7 @@ pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
|
||||
|
||||
impl crate_metadata {
|
||||
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
|
||||
pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
|
||||
pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
|
||||
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@
|
||||
use syntax::print::pprust;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::crateid::CrateId;
|
||||
|
||||
pub type Cmd<'a> = &'a crate_metadata;
|
||||
|
||||
@ -1101,7 +1100,7 @@ pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
|
||||
#[deriving(Clone)]
|
||||
pub struct CrateDep {
|
||||
pub cnum: ast::CrateNum,
|
||||
pub crate_id: CrateId,
|
||||
pub name: String,
|
||||
pub hash: Svh,
|
||||
}
|
||||
|
||||
@ -1115,13 +1114,11 @@ fn docstr(doc: ebml::Doc, tag_: uint) -> String {
|
||||
d.as_str_slice().to_string()
|
||||
}
|
||||
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
|
||||
let crate_id =
|
||||
from_str(docstr(depdoc,
|
||||
tag_crate_dep_crateid).as_slice()).unwrap();
|
||||
let name = docstr(depdoc, tag_crate_dep_crate_name);
|
||||
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
|
||||
deps.push(CrateDep {
|
||||
cnum: crate_num,
|
||||
crate_id: crate_id,
|
||||
name: name,
|
||||
hash: hash,
|
||||
});
|
||||
crate_num += 1;
|
||||
@ -1133,7 +1130,7 @@ fn docstr(doc: ebml::Doc, tag_: uint) -> String {
|
||||
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||
try!(write!(out, "=External Dependencies=\n"));
|
||||
for dep in get_crate_deps(data).iter() {
|
||||
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.crate_id, dep.hash));
|
||||
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
|
||||
}
|
||||
try!(write!(out, "\n"));
|
||||
Ok(())
|
||||
@ -1152,23 +1149,21 @@ pub fn get_crate_hash(data: &[u8]) -> Svh {
|
||||
Svh::new(hashdoc.as_str_slice())
|
||||
}
|
||||
|
||||
pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
|
||||
pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
|
||||
let cratedoc = ebml::Doc::new(data);
|
||||
reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
|
||||
from_str(doc.as_str_slice()).unwrap()
|
||||
reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
|
||||
doc.as_str_slice().to_string()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_crate_triple(data: &[u8]) -> String {
|
||||
pub fn get_crate_triple(data: &[u8]) -> Option<String> {
|
||||
let cratedoc = ebml::Doc::new(data);
|
||||
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
|
||||
triple_doc.expect("No triple in crate").as_str().to_string()
|
||||
triple_doc.map(|s| s.as_str().to_string())
|
||||
}
|
||||
|
||||
pub fn get_crate_id(data: &[u8]) -> CrateId {
|
||||
let cratedoc = ebml::Doc::new(data);
|
||||
let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
|
||||
from_str(hashdoc.as_str_slice()).unwrap()
|
||||
pub fn get_crate_name(data: &[u8]) -> String {
|
||||
maybe_get_crate_name(data).expect("no crate name in crate")
|
||||
}
|
||||
|
||||
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||
|
@ -44,11 +44,9 @@
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util::*;
|
||||
use syntax::ast_util;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::parse::token;
|
||||
use syntax::visit::Visitor;
|
||||
@ -1494,35 +1492,6 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
// So there's a special crate attribute called 'crate_id' which defines the
|
||||
// metadata that Rust cares about for linking crates. If the user didn't
|
||||
// provide it we will throw it in anyway with a default value.
|
||||
fn synthesize_crate_attrs(ecx: &EncodeContext,
|
||||
krate: &Crate) -> Vec<Attribute> {
|
||||
|
||||
fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
|
||||
assert!(!ecx.link_meta.crateid.name.is_empty());
|
||||
|
||||
attr::mk_attr_inner(attr::mk_attr_id(),
|
||||
attr::mk_name_value_item_str(
|
||||
InternedString::new("crate_id"),
|
||||
token::intern_and_get_ident(ecx.link_meta
|
||||
.crateid
|
||||
.to_str()
|
||||
.as_slice())))
|
||||
}
|
||||
|
||||
let mut attrs = Vec::new();
|
||||
for attr in krate.attrs.iter() {
|
||||
if !attr.check_name("crate_id") {
|
||||
attrs.push(*attr);
|
||||
}
|
||||
}
|
||||
attrs.push(synthesize_crateid_attr(ecx));
|
||||
|
||||
attrs
|
||||
}
|
||||
|
||||
fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
|
||||
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
|
||||
// Pull the cnums and name,vers,hash out of cstore
|
||||
@ -1530,8 +1499,8 @@ fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
|
||||
cstore.iter_crate_data(|key, val| {
|
||||
let dep = decoder::CrateDep {
|
||||
cnum: key,
|
||||
crate_id: decoder::get_crate_id(val.data()),
|
||||
hash: decoder::get_crate_hash(val.data())
|
||||
name: decoder::get_crate_name(val.data()),
|
||||
hash: decoder::get_crate_hash(val.data()),
|
||||
};
|
||||
deps.push(dep);
|
||||
});
|
||||
@ -1766,8 +1735,8 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
||||
fn encode_crate_dep(ebml_w: &mut Encoder,
|
||||
dep: decoder::CrateDep) {
|
||||
ebml_w.start_tag(tag_crate_dep);
|
||||
ebml_w.start_tag(tag_crate_dep_crateid);
|
||||
ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
|
||||
ebml_w.start_tag(tag_crate_dep_crate_name);
|
||||
ebml_w.writer.write(dep.name.as_bytes());
|
||||
ebml_w.end_tag();
|
||||
ebml_w.start_tag(tag_crate_dep_hash);
|
||||
ebml_w.writer.write(dep.hash.as_str().as_bytes());
|
||||
@ -1781,9 +1750,9 @@ fn encode_hash(ebml_w: &mut Encoder, hash: &Svh) {
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
|
||||
ebml_w.start_tag(tag_crate_crateid);
|
||||
ebml_w.writer.write(crate_id.to_str().as_bytes());
|
||||
fn encode_crate_name(ebml_w: &mut Encoder, crate_name: &str) {
|
||||
ebml_w.start_tag(tag_crate_crate_name);
|
||||
ebml_w.writer.write(crate_name.as_bytes());
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
@ -1880,7 +1849,7 @@ struct Stats {
|
||||
|
||||
let mut ebml_w = writer::Encoder::new(wr);
|
||||
|
||||
encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
|
||||
encode_crate_name(&mut ebml_w, ecx.link_meta.crate_name.as_slice());
|
||||
encode_crate_triple(&mut ebml_w,
|
||||
tcx.sess
|
||||
.targ_cfg
|
||||
@ -1891,8 +1860,7 @@ struct Stats {
|
||||
encode_dylib_dependency_formats(&mut ebml_w, &ecx);
|
||||
|
||||
let mut i = ebml_w.writer.tell().unwrap();
|
||||
let crate_attrs = synthesize_crate_attrs(&ecx, krate);
|
||||
encode_attributes(&mut ebml_w, crate_attrs.as_slice());
|
||||
encode_attributes(&mut ebml_w, krate.attrs.as_slice());
|
||||
stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
|
||||
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
|
@ -9,6 +9,208 @@
|
||||
// except according to those terms.
|
||||
|
||||
//! Finds crate binaries and loads their metadata
|
||||
//!
|
||||
//! Might I be the first to welcome you to a world of platform differences,
|
||||
//! version requirements, dependency graphs, conficting desires, and fun! This
|
||||
//! is the major guts (along with metadata::creader) of the compiler for loading
|
||||
//! crates and resolving dependencies. Let's take a tour!
|
||||
//!
|
||||
//! # The problem
|
||||
//!
|
||||
//! Each invocation of the compiler is immediately concerned with one primary
|
||||
//! problem, to connect a set of crates to resolved crates on the filesystem.
|
||||
//! Concretely speaking, the compiler follows roughly these steps to get here:
|
||||
//!
|
||||
//! 1. Discover a set of `extern crate` statements.
|
||||
//! 2. Transform these directives into crate names. If the directive does not
|
||||
//! have an explicit name, then the identifier is the name.
|
||||
//! 3. For each of these crate names, find a corresponding crate on the
|
||||
//! filesystem.
|
||||
//!
|
||||
//! Sounds easy, right? Let's walk into some of the nuances.
|
||||
//!
|
||||
//! ## Transitive Dependencies
|
||||
//!
|
||||
//! Let's say we've got three crates: A, B, and C. A depends on B, and B depends
|
||||
//! on C. When we're compiling A, we primarily need to find and locate B, but we
|
||||
//! also end up needing to find and locate C as well.
|
||||
//!
|
||||
//! The reason for this is that any of B's types could be composed of C's types,
|
||||
//! any function in B could return a type from C, etc. To be able to guarantee
|
||||
//! that we can always typecheck/translate any function, we have to have
|
||||
//! complete knowledge of the whole ecosystem, not just our immediate
|
||||
//! dependencies.
|
||||
//!
|
||||
//! So now as part of the "find a corresponding crate on the filesystem" step
|
||||
//! above, this involves also finding all crates for *all upstream
|
||||
//! dependencies*. This includes all dependencies transitively.
|
||||
//!
|
||||
//! ## Rlibs and Dylibs
|
||||
//!
|
||||
//! The compiler has two forms of intermediate dependencies. These are dubbed
|
||||
//! rlibs and dylibs for the static and dynamic variants, respectively. An rlib
|
||||
//! is a rustc-defined file format (currently just an ar archive) while a dylib
|
||||
//! is a platform-defined dynamic library. Each library has a metadata somewhere
|
||||
//! inside of it.
|
||||
//!
|
||||
//! When translating a crate name to a crate on the filesystem, we all of a
|
||||
//! sudden need to take into account both rlibs and dylibs! Linkage later on may
|
||||
//! use either one of these files, as each has their pros/cons. The job of crate
|
||||
//! loading is to discover what's possible by finding all candidates.
|
||||
//!
|
||||
//! Most parts of this loading systems keep the dylib/rlib as just separate
|
||||
//! variables.
|
||||
//!
|
||||
//! ## Where to look?
|
||||
//!
|
||||
//! We can't exactly scan your whole hard drive when looking for dependencies,
|
||||
//! so we need to places to look. Currently the compiler will implicitly add the
|
||||
//! target lib search path ($prefix/lib/rustlib/$target/lib) to any compilation,
|
||||
//! and otherwise all -L flags are added to the search paths.
|
||||
//!
|
||||
//! ## What criterion to select on?
|
||||
//!
|
||||
//! This a pretty tricky area of loading crates. Given a file, how do we know
|
||||
//! whether it's the right crate? Currently, the rules look along these lines:
|
||||
//!
|
||||
//! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
|
||||
//! filename have the right prefix/suffix?
|
||||
//! 2. Does the filename have the right prefix for the crate name being queried?
|
||||
//! This is filtering for files like `libfoo*.rlib` and such.
|
||||
//! 3. Is the file an actual rust library? This is done by loading the metadata
|
||||
//! from the library and making sure it's actually there.
|
||||
//! 4. Does the name in the metadata agree with the name of the library?
|
||||
//! 5. Does the target in the metadata agree with the current target?
|
||||
//! 6. Does the SVH match? (more on this later)
|
||||
//!
|
||||
//! If the file answeres `yes` to all these questions, then the file is
|
||||
//! considered as being *candidate* for being accepted. It is illegal to have
|
||||
//! more than two candidates as the compiler has no method by which to resolve
|
||||
//! this conflict. Additionally, rlib/dylib candidates are considered
|
||||
//! separately.
|
||||
//!
|
||||
//! After all this has happened, we have 1 or two files as candidates. These
|
||||
//! represent the rlib/dylib file found for a library, and they're returned as
|
||||
//! being found.
|
||||
//!
|
||||
//! ### What about versions?
|
||||
//!
|
||||
//! A lot of effort has been put forth to remove versioning from the compiler.
|
||||
//! There have been forays in the past to have versioning baked in, but it was
|
||||
//! largely always deemed insufficient to the point that it was recognized that
|
||||
//! it's probably something the compiler shouldn't do anyway due to its
|
||||
//! complicated nature and the state of the half-baked solutions.
|
||||
//!
|
||||
//! With a departure from versioning, the primary criterion for loading crates
|
||||
//! is just the name of a crate. If we stopped here, it would imply that you
|
||||
//! could never link two crates of the same name from different sources
|
||||
//! together, which is clearly a bad state to be in.
|
||||
//!
|
||||
//! To resolve this problem, we come to the next section!
|
||||
//!
|
||||
//! # Expert Mode
|
||||
//!
|
||||
//! A number of flags have been added to the compiler to solve the "version
|
||||
//! problem" in the previous section, as well as generally enabling more
|
||||
//! powerful usage of the crate loading system of the compiler. The goal of
|
||||
//! these flags and options are to enable third-party tools to drive the
|
||||
//! compiler with prior knowledge about how the world should look.
|
||||
//!
|
||||
//! ## The `--extern` flag
|
||||
//!
|
||||
//! The compiler accepts a flag of this form a number of times:
|
||||
//!
|
||||
//! ```notrust
|
||||
//! --extern crate-name=path/to/the/crate.rlib
|
||||
//! ```
|
||||
//!
|
||||
//! This flag is basically the following letter to the compiler:
|
||||
//!
|
||||
//! > Dear rustc,
|
||||
//! >
|
||||
//! > When you are attempting to load the immediate dependency `crate-name`, I
|
||||
//! > would like you too assume that the library is located at
|
||||
//! > `path/to/the/crate.rlib`, and look nowhere else. Also, please do not
|
||||
//! > assume that the path I specified has the name `crate-name`.
|
||||
//!
|
||||
//! This flag basically overrides most matching logic except for validating that
|
||||
//! the file is indeed a rust library. The same `crate-name` can be specified
|
||||
//! twice to specify the rlib/dylib pair.
|
||||
//!
|
||||
//! ## Enabling "multiple versions"
|
||||
//!
|
||||
//! This basically boils down to the ability to specify arbitrary packages to
|
||||
//! the compiler. For example, if crate A wanted to use Bv1 and Bv2, then it
|
||||
//! would look something like:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! extern crate b1;
|
||||
//! extern crate b2;
|
||||
//!
|
||||
//! fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! and the compiler would be invoked as:
|
||||
//!
|
||||
//! ```notrust
|
||||
//! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
|
||||
//! ```
|
||||
//!
|
||||
//! In this scenario there are two crates named `b` and the compiler must be
|
||||
//! manually driven to be informed where each crate is.
|
||||
//!
|
||||
//! ## Frobbing symbols
|
||||
//!
|
||||
//! One of the immediate problems with linking the same library together twice
|
||||
//! in the same problem is dealing with duplicate symbols. The primary way to
|
||||
//! deal with this in rustc is to add hashes to the end of each symbol.
|
||||
//!
|
||||
//! In order to force hashes to change between versions of a library, if
|
||||
//! desired, the compiler exposes an option `-C metadata=foo`, which is used to
|
||||
//! initially seed each symbol hash. The string `foo` is prepended to each
|
||||
//! string-to-hash to ensure that symbols change over time.
|
||||
//!
|
||||
//! ## Loading transitive dependencies
|
||||
//!
|
||||
//! Dealing with same-named-but-distinct crates is not just a local problem, but
|
||||
//! one that also needs to be dealt with for transitive dependences. Note that
|
||||
//! in the letter above `--extern` flags only apply to the *local* set of
|
||||
//! dependencies, not the upstream transitive dependencies. Consider this
|
||||
//! dependency graph:
|
||||
//!
|
||||
//! ```notrust
|
||||
//! A.1 A.2
|
||||
//! | |
|
||||
//! | |
|
||||
//! B C
|
||||
//! \ /
|
||||
//! \ /
|
||||
//! D
|
||||
//! ```
|
||||
//!
|
||||
//! In this scenario, when we compile `D`, we need to be able to distinctly
|
||||
//! resolve `A.1` and `A.2`, but an `--extern` flag cannot apply to these
|
||||
//! transitive dependencies.
|
||||
//!
|
||||
//! Note that the key idea here is that `B` and `C` are both *already compiled*.
|
||||
//! That is, they have already resolved their dependencies. Due to unrelated
|
||||
//! technical reasons, when a library is compiled, it is only compatible with
|
||||
//! the *exact same* version of the upstream libraries it was compiled against.
|
||||
//! We use the "Strict Version Hash" to identify the exact copy of an upstream
|
||||
//! library.
|
||||
//!
|
||||
//! With this knowledge, we know that `B` and `C` will depend on `A` with
|
||||
//! different SVH values, so we crawl the normal `-L` paths looking for
|
||||
//! `liba*.rlib` and filter based on the contained SVH.
|
||||
//!
|
||||
//! In the end, this ends up not needing `--extern` to specify upstream
|
||||
//! transitive dependencies.
|
||||
//!
|
||||
//! # Wrapping up
|
||||
//!
|
||||
//! That's the general overview of loading crates in the compiler, but it's by
|
||||
//! no means all of the necessary details. Take a look at the rest of
|
||||
//! metadata::loader or metadata::creader for all the juicy details!
|
||||
|
||||
use back::archive::{ArchiveRO, METADATA_FILENAME};
|
||||
use back::svh::Svh;
|
||||
@ -21,8 +223,6 @@
|
||||
use syntax::abi;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use util::fs;
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
@ -61,8 +261,7 @@ pub struct Context<'a> {
|
||||
pub sess: &'a Session,
|
||||
pub span: Span,
|
||||
pub ident: &'a str,
|
||||
pub crate_id: &'a CrateId,
|
||||
pub id_hash: &'a str,
|
||||
pub crate_name: &'a str,
|
||||
pub hash: Option<&'a Svh>,
|
||||
pub triple: &'a str,
|
||||
pub os: abi::Os,
|
||||
@ -70,6 +269,7 @@ pub struct Context<'a> {
|
||||
pub root: &'a Option<CratePaths>,
|
||||
pub rejected_via_hash: Vec<CrateMismatch>,
|
||||
pub rejected_via_triple: Vec<CrateMismatch>,
|
||||
pub should_match_name: bool,
|
||||
}
|
||||
|
||||
pub struct Library {
|
||||
@ -167,19 +367,30 @@ pub fn report_load_errs(&mut self) {
|
||||
}
|
||||
|
||||
fn find_library_crate(&mut self) -> Option<Library> {
|
||||
// If an SVH is specified, then this is a transitive dependency that
|
||||
// must be loaded via -L plus some filtering.
|
||||
if self.hash.is_none() {
|
||||
self.should_match_name = false;
|
||||
match self.find_commandline_library() {
|
||||
Some(l) => return Some(l),
|
||||
None => {}
|
||||
}
|
||||
self.should_match_name = true;
|
||||
}
|
||||
|
||||
let dypair = self.dylibname();
|
||||
|
||||
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
||||
let dylib_prefix = dypair.map(|(prefix, _)| {
|
||||
format!("{}{}-", prefix, self.crate_id.name)
|
||||
format!("{}{}", prefix, self.crate_name)
|
||||
});
|
||||
let rlib_prefix = format!("lib{}-", self.crate_id.name);
|
||||
let rlib_prefix = format!("lib{}", self.crate_name);
|
||||
|
||||
let mut candidates = HashMap::new();
|
||||
|
||||
// First, find all possible candidate rlibs and dylibs purely based on
|
||||
// the name of the files themselves. We're trying to match against an
|
||||
// exact crate_id and a possibly an exact hash.
|
||||
// exact crate name and a possibly an exact hash.
|
||||
//
|
||||
// During this step, we can filter all found libraries based on the
|
||||
// name and id found in the crate id (we ignore the path portion for
|
||||
@ -195,49 +406,32 @@ fn find_library_crate(&mut self) -> Option<Library> {
|
||||
None => return FileDoesntMatch,
|
||||
Some(file) => file,
|
||||
};
|
||||
if file.starts_with(rlib_prefix.as_slice()) &&
|
||||
let (hash, rlib) = if file.starts_with(rlib_prefix.as_slice()) &&
|
||||
file.ends_with(".rlib") {
|
||||
info!("rlib candidate: {}", path.display());
|
||||
match self.try_match(file, rlib_prefix.as_slice(), ".rlib") {
|
||||
Some(hash) => {
|
||||
info!("rlib accepted, hash: {}", hash);
|
||||
let slot = candidates.find_or_insert_with(hash, |_| {
|
||||
(HashSet::new(), HashSet::new())
|
||||
});
|
||||
let (ref mut rlibs, _) = *slot;
|
||||
rlibs.insert(fs::realpath(path).unwrap());
|
||||
FileMatches
|
||||
}
|
||||
None => {
|
||||
info!("rlib rejected");
|
||||
FileDoesntMatch
|
||||
}
|
||||
}
|
||||
(file.slice(rlib_prefix.len(), file.len() - ".rlib".len()),
|
||||
true)
|
||||
} else if dypair.map_or(false, |(_, suffix)| {
|
||||
file.starts_with(dylib_prefix.get_ref().as_slice()) &&
|
||||
file.ends_with(suffix)
|
||||
}) {
|
||||
let (_, suffix) = dypair.unwrap();
|
||||
let dylib_prefix = dylib_prefix.get_ref().as_slice();
|
||||
info!("dylib candidate: {}", path.display());
|
||||
match self.try_match(file, dylib_prefix, suffix) {
|
||||
Some(hash) => {
|
||||
info!("dylib accepted, hash: {}", hash);
|
||||
let slot = candidates.find_or_insert_with(hash, |_| {
|
||||
(HashSet::new(), HashSet::new())
|
||||
});
|
||||
let (_, ref mut dylibs) = *slot;
|
||||
dylibs.insert(fs::realpath(path).unwrap());
|
||||
FileMatches
|
||||
}
|
||||
None => {
|
||||
info!("dylib rejected");
|
||||
FileDoesntMatch
|
||||
}
|
||||
}
|
||||
(file.slice(dylib_prefix.len(), file.len() - suffix.len()),
|
||||
false)
|
||||
} else {
|
||||
FileDoesntMatch
|
||||
return FileDoesntMatch
|
||||
};
|
||||
info!("lib candidate: {}", path.display());
|
||||
let slot = candidates.find_or_insert_with(hash.to_string(), |_| {
|
||||
(HashSet::new(), HashSet::new())
|
||||
});
|
||||
let (ref mut rlibs, ref mut dylibs) = *slot;
|
||||
if rlib {
|
||||
rlibs.insert(fs::realpath(path).unwrap());
|
||||
} else {
|
||||
dylibs.insert(fs::realpath(path).unwrap());
|
||||
}
|
||||
FileMatches
|
||||
});
|
||||
|
||||
// We have now collected all known libraries into a set of candidates
|
||||
@ -274,7 +468,7 @@ fn find_library_crate(&mut self) -> Option<Library> {
|
||||
_ => {
|
||||
self.sess.span_err(self.span,
|
||||
format!("multiple matching crates for `{}`",
|
||||
self.crate_id.name).as_slice());
|
||||
self.crate_name).as_slice());
|
||||
self.sess.note("candidates:");
|
||||
for lib in libraries.iter() {
|
||||
match lib.dylib {
|
||||
@ -292,50 +486,14 @@ fn find_library_crate(&mut self) -> Option<Library> {
|
||||
None => {}
|
||||
}
|
||||
let data = lib.metadata.as_slice();
|
||||
let crate_id = decoder::get_crate_id(data);
|
||||
note_crateid_attr(self.sess.diagnostic(), &crate_id);
|
||||
let name = decoder::get_crate_name(data);
|
||||
note_crate_name(self.sess.diagnostic(), name.as_slice());
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to match the requested version of a library against the file
|
||||
// specified. The prefix/suffix are specified (disambiguates between
|
||||
// rlib/dylib).
|
||||
//
|
||||
// The return value is `None` if `file` doesn't look like a rust-generated
|
||||
// library, or if a specific version was requested and it doesn't match the
|
||||
// apparent file's version.
|
||||
//
|
||||
// If everything checks out, then `Some(hash)` is returned where `hash` is
|
||||
// the listed hash in the filename itself.
|
||||
fn try_match(&self, file: &str, prefix: &str, suffix: &str) -> Option<String>{
|
||||
let middle = file.slice(prefix.len(), file.len() - suffix.len());
|
||||
debug!("matching -- {}, middle: {}", file, middle);
|
||||
let mut parts = middle.splitn('-', 1);
|
||||
let hash = match parts.next() { Some(h) => h, None => return None };
|
||||
debug!("matching -- {}, hash: {} (want {})", file, hash, self.id_hash);
|
||||
let vers = match parts.next() { Some(v) => v, None => return None };
|
||||
debug!("matching -- {}, vers: {} (want {})", file, vers,
|
||||
self.crate_id.version);
|
||||
match self.crate_id.version {
|
||||
Some(ref version) if version.as_slice() != vers => return None,
|
||||
Some(..) => {} // check the hash
|
||||
|
||||
// hash is irrelevant, no version specified
|
||||
None => return Some(hash.to_string())
|
||||
}
|
||||
debug!("matching -- {}, vers ok", file);
|
||||
// hashes in filenames are prefixes of the "true hash"
|
||||
if self.id_hash == hash.as_slice() {
|
||||
debug!("matching -- {}, hash ok", file);
|
||||
Some(hash.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to extract *one* library from the set `m`. If the set has no
|
||||
// elements, `None` is returned. If the set has more than one element, then
|
||||
// the errors and notes are emitted about the set of libraries.
|
||||
@ -382,7 +540,7 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
|
||||
format!("multiple {} candidates for `{}` \
|
||||
found",
|
||||
flavor,
|
||||
self.crate_id.name).as_slice());
|
||||
self.crate_name).as_slice());
|
||||
self.sess.span_note(self.span,
|
||||
format!(r"candidate #1: {}",
|
||||
ret.get_ref()
|
||||
@ -404,9 +562,11 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
|
||||
}
|
||||
|
||||
fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
|
||||
match decoder::maybe_get_crate_id(crate_data) {
|
||||
Some(ref id) if self.crate_id.matches(id) => {}
|
||||
_ => { info!("Rejecting via crate_id"); return false }
|
||||
if self.should_match_name {
|
||||
match decoder::maybe_get_crate_name(crate_data) {
|
||||
Some(ref name) if self.crate_name == name.as_slice() => {}
|
||||
_ => { info!("Rejecting via crate name"); return false }
|
||||
}
|
||||
}
|
||||
let hash = match decoder::maybe_get_crate_hash(crate_data) {
|
||||
Some(hash) => hash, None => {
|
||||
@ -415,7 +575,10 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
|
||||
}
|
||||
};
|
||||
|
||||
let triple = decoder::get_crate_triple(crate_data);
|
||||
let triple = match decoder::get_crate_triple(crate_data) {
|
||||
None => { debug!("triple not present"); return false }
|
||||
Some(t) => t,
|
||||
};
|
||||
if triple.as_slice() != self.triple {
|
||||
info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
|
||||
self.rejected_via_triple.push(CrateMismatch {
|
||||
@ -456,10 +619,72 @@ fn dylibname(&self) -> Option<(&'static str, &'static str)> {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_commandline_library(&mut self) -> Option<Library> {
|
||||
let locs = match self.sess.opts.externs.find_equiv(&self.crate_name) {
|
||||
Some(s) => s,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// First, filter out all libraries that look suspicious. We only accept
|
||||
// files which actually exist that have the correct naming scheme for
|
||||
// rlibs/dylibs.
|
||||
let sess = self.sess;
|
||||
let dylibname = self.dylibname();
|
||||
let mut locs = locs.iter().map(|l| Path::new(l.as_slice())).filter(|loc| {
|
||||
if !loc.exists() {
|
||||
sess.err(format!("extern location does not exist: {}",
|
||||
loc.display()).as_slice());
|
||||
return false;
|
||||
}
|
||||
let file = loc.filename_str().unwrap();
|
||||
if file.starts_with("lib") && file.ends_with(".rlib") {
|
||||
return true
|
||||
} else {
|
||||
match dylibname {
|
||||
Some((prefix, suffix)) => {
|
||||
if file.starts_with(prefix) && file.ends_with(suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
sess.err(format!("extern location is of an unknown type: {}",
|
||||
loc.display()).as_slice());
|
||||
false
|
||||
});
|
||||
|
||||
// Now that we have an itertor of good candidates, make sure there's at
|
||||
// most one rlib and at most one dylib.
|
||||
let mut rlibs = HashSet::new();
|
||||
let mut dylibs = HashSet::new();
|
||||
for loc in locs {
|
||||
if loc.filename_str().unwrap().ends_with(".rlib") {
|
||||
rlibs.insert(loc.clone());
|
||||
} else {
|
||||
dylibs.insert(loc.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the rlib/dylib pair.
|
||||
let mut metadata = None;
|
||||
let rlib = self.extract_one(rlibs, "rlib", &mut metadata);
|
||||
let dylib = self.extract_one(dylibs, "dylib", &mut metadata);
|
||||
|
||||
if rlib.is_none() && dylib.is_none() { return None }
|
||||
match metadata {
|
||||
Some(metadata) => Some(Library {
|
||||
dylib: dylib,
|
||||
rlib: rlib,
|
||||
metadata: metadata,
|
||||
}),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn note_crateid_attr(diag: &SpanHandler, crateid: &CrateId) {
|
||||
diag.handler().note(format!("crate_id: {}", crateid.to_str()).as_slice());
|
||||
pub fn note_crate_name(diag: &SpanHandler, name: &str) {
|
||||
diag.handler().note(format!("crate name: {}", name).as_slice());
|
||||
}
|
||||
|
||||
impl ArchiveMetadata {
|
||||
|
@ -1373,15 +1373,15 @@ pub fn process_crate(sess: &Session,
|
||||
return;
|
||||
}
|
||||
|
||||
let (cratename, crateid) = match attr::find_crateid(krate.attrs.as_slice()) {
|
||||
Some(crateid) => (crateid.name.clone(), crateid.to_str()),
|
||||
let cratename = match attr::find_crate_name(krate.attrs.as_slice()) {
|
||||
Some(name) => name.get().to_string(),
|
||||
None => {
|
||||
info!("Could not find crate name, using 'unknown_crate'");
|
||||
(String::from_str("unknown_crate"),"unknown_crate".to_owned())
|
||||
String::from_str("unknown_crate")
|
||||
},
|
||||
};
|
||||
|
||||
info!("Dumping crate {} ({})", cratename, crateid);
|
||||
info!("Dumping crate {}", cratename);
|
||||
|
||||
// find a path to dump our data to
|
||||
let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
|
||||
|
@ -30,7 +30,6 @@
|
||||
use driver::config;
|
||||
use driver::config::{NoDebugInfo, FullDebugInfo};
|
||||
use driver::session::Session;
|
||||
use driver::driver::OutputFilenames;
|
||||
use driver::driver::{CrateAnalysis, CrateTranslation};
|
||||
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
|
||||
use lib::llvm::{llvm, Vector};
|
||||
@ -2270,8 +2269,9 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||
}.as_slice());
|
||||
let llmeta = C_bytes(cx, compressed.as_slice());
|
||||
let llconst = C_struct(cx, [llmeta], false);
|
||||
let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
|
||||
cx.link_meta.crateid.version_or_default(), cx.link_meta.crate_hash);
|
||||
let name = format!("rust_metadata_{}_{}",
|
||||
cx.link_meta.crate_name,
|
||||
cx.link_meta.crate_hash);
|
||||
let llglobal = name.with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
|
||||
@ -2288,9 +2288,8 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||
}
|
||||
|
||||
pub fn trans_crate(krate: ast::Crate,
|
||||
analysis: CrateAnalysis,
|
||||
output: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
|
||||
let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, .. } = analysis;
|
||||
analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
|
||||
let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
|
||||
|
||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||
unsafe {
|
||||
@ -2310,8 +2309,7 @@ pub fn trans_crate(krate: ast::Crate,
|
||||
}
|
||||
}
|
||||
|
||||
let link_meta = link::build_link_meta(&krate,
|
||||
output.out_filestem.as_slice());
|
||||
let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
|
||||
|
||||
// Append ".rs" to crate name as LLVM module identifier.
|
||||
//
|
||||
@ -2321,7 +2319,7 @@ pub fn trans_crate(krate: ast::Crate,
|
||||
// crashes if the module identifier is same as other symbols
|
||||
// such as a function name in the module.
|
||||
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
|
||||
let mut llmod_id = link_meta.crateid.name.clone();
|
||||
let mut llmod_id = link_meta.crate_name.clone();
|
||||
llmod_id.push_str(".rs");
|
||||
|
||||
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
|
||||
|
@ -1496,7 +1496,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
|
||||
});
|
||||
|
||||
fn fallback_path(cx: &CrateContext) -> CString {
|
||||
cx.link_meta.crateid.name.as_slice().to_c_str()
|
||||
cx.link_meta.crate_name.as_slice().to_c_str()
|
||||
}
|
||||
}
|
||||
|
||||
@ -3972,7 +3972,7 @@ fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
|
||||
}
|
||||
|
||||
fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
|
||||
cx.link_meta.crateid.name.as_slice()
|
||||
cx.link_meta.crate_name.as_slice()
|
||||
}
|
||||
|
||||
fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
|
||||
|
@ -566,7 +566,7 @@ fn build_rust_fn(ccx: &CrateContext,
|
||||
|
||||
let ps = ccx.tcx.map.with_path(id, |path| {
|
||||
let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
|
||||
link::mangle(path.chain(abi.move_iter()), None, None)
|
||||
link::mangle(path.chain(abi.move_iter()), None)
|
||||
});
|
||||
|
||||
// Compute the type that the function would have if it were just a
|
||||
|
@ -129,9 +129,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
hash_id.hash(&mut state);
|
||||
mono_ty.hash(&mut state);
|
||||
|
||||
exported_name(path,
|
||||
format!("h{}", state.result()).as_slice(),
|
||||
ccx.link_meta.crateid.version_or_default())
|
||||
exported_name(path, format!("h{}", state.result()).as_slice())
|
||||
});
|
||||
debug!("monomorphize_fn mangled to {}", s);
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
||||
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
|
||||
use syntax::ast;
|
||||
use syntax::crateid::CrateId;
|
||||
use util::ppaux::{ty_to_str, UserString};
|
||||
|
||||
struct Env<'a> {
|
||||
@ -116,11 +115,8 @@ fn test_env(_test_name: &str,
|
||||
let krate_config = Vec::new();
|
||||
let input = driver::StrInput(source_string.to_owned());
|
||||
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
|
||||
let krate_id = CrateId { path: "test".to_owned(),
|
||||
name: "test".to_owned(),
|
||||
version: None };
|
||||
let (krate, ast_map) =
|
||||
driver::phase_2_configure_and_expand(&sess, krate, &krate_id)
|
||||
driver::phase_2_configure_and_expand(&sess, krate, "test")
|
||||
.expect("phase 2 aborted");
|
||||
|
||||
// run just enough stuff to build a tcx:
|
||||
|
@ -119,13 +119,7 @@ fn clean(&self) -> Crate {
|
||||
|
||||
// Figure out the name of this crate
|
||||
let input = driver::FileInput(cx.src.clone());
|
||||
let t_outputs = driver::build_output_filenames(&input,
|
||||
&None,
|
||||
&None,
|
||||
self.attrs.as_slice(),
|
||||
cx.sess());
|
||||
let id = link::find_crate_id(self.attrs.as_slice(),
|
||||
t_outputs.out_filestem.as_slice());
|
||||
let name = link::find_crate_name(None, self.attrs.as_slice(), &input);
|
||||
|
||||
// Clean the crate, translating the entire libsyntax AST to one that is
|
||||
// understood by rustdoc.
|
||||
@ -188,7 +182,7 @@ fn clean(&self) -> Crate {
|
||||
}
|
||||
|
||||
Crate {
|
||||
name: id.name.to_string(),
|
||||
name: name.to_string(),
|
||||
module: Some(module),
|
||||
externs: externs,
|
||||
primitives: primitives,
|
||||
|
@ -12,6 +12,7 @@
|
||||
use rustc::{driver, middle};
|
||||
use rustc::middle::{privacy, ty};
|
||||
use rustc::lint;
|
||||
use rustc::back::link;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::parse::token;
|
||||
@ -115,13 +116,17 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
|
||||
}
|
||||
|
||||
let krate = phase_1_parse_input(&sess, cfg, &input);
|
||||
|
||||
let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
|
||||
&input);
|
||||
|
||||
let (krate, ast_map)
|
||||
= phase_2_configure_and_expand(&sess, krate, &from_str("rustdoc").unwrap())
|
||||
= phase_2_configure_and_expand(&sess, krate, name.as_slice())
|
||||
.expect("phase_2_configure_and_expand aborted in rustdoc!");
|
||||
|
||||
let driver::driver::CrateAnalysis {
|
||||
exported_items, public_items, ty_cx, ..
|
||||
} = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
||||
} = phase_3_run_analysis_passes(sess, &krate, ast_map, name);
|
||||
|
||||
debug!("crate: {:?}", krate);
|
||||
(DocContext {
|
||||
|
@ -8,12 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id = "rustdoc#0.11.0"]
|
||||
#![crate_id = "rustdoc#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "rustdoc"]
|
||||
#![experimental]
|
||||
#![desc = "rustdoc, the Rust documentation extractor"]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "dylib"]
|
||||
#![crate_type = "rlib"]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![feature(globs, struct_variant, managed_boxes, macro_rules, phase)]
|
||||
|
||||
|
@ -69,7 +69,7 @@ pub fn run(input: &str,
|
||||
}));
|
||||
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
|
||||
let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
|
||||
&from_str("rustdoc-test").unwrap())
|
||||
"rustdoc-test")
|
||||
.expect("phase_2_configure_and_expand aborted in rustdoc!");
|
||||
|
||||
let ctx = box(GC) core::DocContext {
|
||||
|
@ -8,7 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id = "rustrt#0.11.0"]
|
||||
#![crate_id = "rustrt#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "rustrt"]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -20,6 +21,7 @@
|
||||
#![feature(linkage, lang_items, unsafe_destructor)]
|
||||
#![no_std]
|
||||
#![experimental]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[phase(plugin, link)] extern crate core;
|
||||
extern crate alloc;
|
||||
|
@ -34,7 +34,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "rustuv#0.11.0"]
|
||||
#![crate_id = "rustuv#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "rustuv"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
@ -47,6 +48,7 @@
|
||||
#![feature(macro_rules, unsafe_destructor)]
|
||||
#![deny(unused_result, unused_must_use)]
|
||||
#![allow(visible_private_types)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] extern crate green;
|
||||
#[cfg(test)] extern crate debug;
|
||||
|
@ -28,7 +28,8 @@
|
||||
//! An example version number with all five components is
|
||||
//! `0.8.1-rc.3.0+20130922.linux`.
|
||||
|
||||
#![crate_id = "semver#0.11.0"]
|
||||
#![crate_id = "semver#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "semver"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -36,6 +37,7 @@
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
use std::char;
|
||||
use std::cmp;
|
||||
|
@ -14,7 +14,8 @@
|
||||
Core encoding and decoding interfaces.
|
||||
*/
|
||||
|
||||
#![crate_id = "serialize#0.11.0"]
|
||||
#![crate_id = "serialize#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "serialize"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -24,6 +25,7 @@
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(macro_rules, managed_boxes, default_type_params, phase)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
// test harness access
|
||||
#[cfg(test)]
|
||||
|
@ -94,7 +94,8 @@
|
||||
//! all the standard macros, such as `assert!`, `fail!`, `println!`,
|
||||
//! and `format!`, also available to all Rust code.
|
||||
|
||||
#![crate_id = "std#0.11.0"]
|
||||
#![crate_id = "std#0.11.0"] // NOTE: remove after stage0 snap
|
||||
#![crate_name = "std"]
|
||||
#![unstable]
|
||||
#![comment = "The Rust standard library"]
|
||||
#![license = "MIT/ASL2"]
|
||||
@ -107,6 +108,7 @@
|
||||
|
||||
#![feature(macro_rules, globs, managed_boxes, linkage)]
|
||||
#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
// Don't link to std. We are std.
|
||||
#![no_std]
|
||||
|
@ -17,7 +17,8 @@
|
||||
//! use this crate specifically. Instead, its functionality is reexported
|
||||
//! through `std::sync`.
|
||||
|
||||
#![crate_id = "sync#0.11.0"]
|
||||
#![crate_id = "sync#0.11.0"] // NOTE: remove after stage0 snap
|
||||
#![crate_name = "sync"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -30,6 +31,7 @@
|
||||
#![feature(phase, globs, macro_rules, unsafe_destructor)]
|
||||
#![deny(missing_doc)]
|
||||
#![no_std]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[phase(plugin, link)] extern crate core;
|
||||
extern crate alloc;
|
||||
|
@ -18,7 +18,6 @@
|
||||
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
use crateid::CrateId;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::BitvSet;
|
||||
@ -271,11 +270,8 @@ pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
|
||||
match first_attr_value_str_by_name(attrs, "crate_id") {
|
||||
None => None,
|
||||
Some(id) => from_str::<CrateId>(id.get()),
|
||||
}
|
||||
pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
|
||||
first_attr_value_str_by_name(attrs, "crate_name")
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
|
@ -452,7 +452,7 @@ pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace }
|
||||
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
|
||||
pub fn mod_path(&self) -> Vec<ast::Ident> {
|
||||
let mut v = Vec::new();
|
||||
v.push(token::str_to_ident(self.ecfg.crate_id.name.as_slice()));
|
||||
v.push(token::str_to_ident(self.ecfg.crate_name.as_slice()));
|
||||
v.extend(self.mod_path.iter().map(|a| *a));
|
||||
return v;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
use attr::AttrMetaMethods;
|
||||
use codemap;
|
||||
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
|
||||
use crateid::CrateId;
|
||||
use ext::base::*;
|
||||
use fold;
|
||||
use fold::*;
|
||||
@ -985,7 +984,7 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
|
||||
|
||||
pub struct ExpansionConfig {
|
||||
pub deriving_hash_type_parameter: bool,
|
||||
pub crate_id: CrateId,
|
||||
pub crate_name: String,
|
||||
}
|
||||
|
||||
pub struct ExportedMacros {
|
||||
@ -1184,7 +1183,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
|
||||
// should fail:
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
crate_name: "test".to_str(),
|
||||
};
|
||||
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||
}
|
||||
@ -1201,7 +1200,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
|
||||
Vec::new(), &sess);
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
crate_name: "test".to_str(),
|
||||
};
|
||||
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||
}
|
||||
@ -1217,7 +1216,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
|
||||
Vec::new(), &sess);
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
crate_name: "test".to_str(),
|
||||
};
|
||||
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
|
||||
}
|
||||
@ -1254,7 +1253,7 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
|
||||
// the cfg argument actually does matter, here...
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
crate_name: "test".to_str(),
|
||||
};
|
||||
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
|
||||
}
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "syntax#0.11.0"]
|
||||
#![crate_id = "syntax#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "syntax"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -30,6 +31,7 @@
|
||||
#![feature(macro_rules, globs, managed_boxes, default_type_params, phase)]
|
||||
#![feature(quote, unsafe_destructor)]
|
||||
#![allow(deprecated)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
extern crate serialize;
|
||||
extern crate term;
|
||||
|
@ -38,7 +38,8 @@
|
||||
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
|
||||
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
|
||||
|
||||
#![crate_id = "term#0.11.0"]
|
||||
#![crate_id = "term#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "term"]
|
||||
#![experimental]
|
||||
#![comment = "Simple ANSI color library"]
|
||||
#![license = "MIT/ASL2"]
|
||||
@ -48,6 +49,7 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![feature(macro_rules, phase)]
|
||||
|
||||
|
@ -23,7 +23,8 @@
|
||||
// running tests while providing a base that other test frameworks may
|
||||
// build off of.
|
||||
|
||||
#![crate_id = "test#0.11.0"]
|
||||
#![crate_id = "test#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "test"] // NOTE: remove after stage0
|
||||
#![experimental]
|
||||
#![comment = "Rust internal test library only used by rustc"]
|
||||
#![license = "MIT/ASL2"]
|
||||
@ -32,6 +33,7 @@
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![feature(asm, macro_rules, phase)]
|
||||
|
||||
|
@ -10,7 +10,8 @@
|
||||
|
||||
//! Simple time handling.
|
||||
|
||||
#![crate_id = "time#0.11.0"]
|
||||
#![crate_id = "time#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "time"]
|
||||
#![experimental]
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
@ -21,6 +22,7 @@
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(phase)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] extern crate debug;
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
@ -10,7 +10,8 @@
|
||||
|
||||
//! Types/fns concerning URLs (see RFC 3986)
|
||||
|
||||
#![crate_id = "url#0.11.0"]
|
||||
#![crate_id = "url#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "url"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -20,6 +21,7 @@
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(default_type_params)]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
@ -54,7 +54,8 @@ fn main() {
|
||||
|
||||
*/
|
||||
|
||||
#![crate_id = "uuid#0.11.0"]
|
||||
#![crate_id = "uuid#0.11.0"] // NOTE: remove after stage0
|
||||
#![crate_name = "uuid"]
|
||||
#![experimental]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
@ -63,6 +64,7 @@ fn main() {
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/0.11.0/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||
|
||||
#![feature(default_type_params)]
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="crateresolve1#0.1"]
|
||||
|
||||
// compile-flags:-C extra-filename=-1
|
||||
#![crate_name = "crateresolve1"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn f() -> int { 10 }
|
||||
|
@ -8,8 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="crateresolve1#0.2"]
|
||||
|
||||
// compile-flags:-C extra-filename=-2
|
||||
#![crate_name = "crateresolve1"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn f() -> int { 20 }
|
||||
|
@ -8,8 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="crateresolve1#0.3"]
|
||||
|
||||
// compile-flags:-C extra-filename=-3
|
||||
#![crate_name = "crateresolve1"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn f() -> int { 30 }
|
||||
|
@ -1,15 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="crateresolve2#0.1"]
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn f() -> int { 10 }
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="externcallback#0.1"]
|
||||
#![crate_name="externcallback"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
extern crate libc;
|
||||
|
@ -8,7 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate foo = ""; //~ ERROR: malformed crate id
|
||||
extern crate bar = "#a"; //~ ERROR: malformed crate id
|
||||
extern crate foo = ""; //~ ERROR: crate name must not be empty
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -8,8 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="crateresolve2#0.2"]
|
||||
extern crate bar = "#a"; //~ ERROR: invalid character `#` in crate name: `#a`
|
||||
|
||||
#![crate_type = "lib"]
|
||||
fn main() {}
|
||||
|
||||
pub fn f() -> int { 20 }
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:crateresolve2-1.rs
|
||||
// aux-build:crateresolve2-2.rs
|
||||
// aux-build:crateresolve2-3.rs
|
||||
// error-pattern:using multiple versions of crate `crateresolve2`
|
||||
|
||||
extern crate crateresolve2 = "crateresolve2#0.1";
|
||||
|
||||
mod m {
|
||||
pub extern crate crateresolve2 = "crateresolve2#0.2";
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: int = false;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:crateresolve5-1.rs
|
||||
// aux-build:crateresolve5-2.rs
|
||||
|
||||
extern crate cr5_1 = "crateresolve5#0.1";
|
||||
extern crate cr5_2 = "crateresolve5#0.2";
|
||||
|
||||
|
||||
fn main() {
|
||||
// Nominal types from two multiple versions of a crate are different types
|
||||
assert!(cr5_1::nominal() == cr5_2::nominal()); //~ ERROR mismatched types: expected
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:issue-11908-1.rs
|
||||
// ignore-android this test is incompatible with the android test runner
|
||||
// error-pattern: multiple dylib candidates for `url` found
|
||||
|
||||
// This test ensures that if you have the same rlib or dylib at two locations
|
||||
// in the same path that you don't hit an assertion in the compiler.
|
||||
//
|
||||
// Note that this relies on `liburl` to be in the path somewhere else,
|
||||
// and then our aux-built libraries will collide with liburl (they have
|
||||
// the same version listed)
|
||||
|
||||
extern crate url;
|
||||
|
||||
fn main() {}
|
@ -6,7 +6,6 @@ TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs
|
||||
ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
|
||||
$(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
|
||||
$(call RUN,main)
|
||||
$(call REMOVE_DYLIBS,boot)
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="boot#0.1"]
|
||||
#![crate_name="boot"]
|
||||
#![crate_type="dylib"]
|
||||
|
||||
extern crate rustuv;
|
||||
|
@ -6,7 +6,6 @@ TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs
|
||||
ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
|
||||
$(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
|
||||
$(call RUN,main)
|
||||
$(call REMOVE_DYLIBS,boot)
|
||||
|
@ -4,7 +4,6 @@ HOST_LIB_DIR=$(TMPDIR)/../../../stage$(RUST_BUILD_STAGE)/lib
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs
|
||||
ln -s $(call DYLIB,foo-*) $(call DYLIB,foo)
|
||||
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -Wl,-rpath,$(TMPDIR)
|
||||
$(call RUN,bar)
|
||||
$(call REMOVE_DYLIBS,foo)
|
||||
|
@ -10,7 +10,6 @@ endif
|
||||
ifneq ($(shell uname),FreeBSD)
|
||||
all:
|
||||
$(RUSTC) foo.rs
|
||||
ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
|
||||
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRAFLAGS) -lstdc++
|
||||
$(call RUN,bar)
|
||||
rm $(call STATICLIB,foo*)
|
||||
|
@ -1,10 +1,9 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
[ `$(RUSTC) --crate-id crate.rs` = "foo#0.11.0" ]
|
||||
[ `$(RUSTC) --crate-name crate.rs` = "foo" ]
|
||||
[ `$(RUSTC) --crate-file-name 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
|
||||
[ `$(RUSTC) --print-crate-name crate.rs` = "foo" ]
|
||||
[ `$(RUSTC) --print-file-name crate.rs` = "foo" ]
|
||||
[ `$(RUSTC) --print-file-name --crate-type=lib --test crate.rs` = "foo" ]
|
||||
[ `$(RUSTC) --print-file-name --test lib.rs` = "mylib" ]
|
||||
$(RUSTC) --print-file-name lib.rs
|
||||
$(RUSTC) --print-file-name rlib.rs
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id = "foo#0.11.0"]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// Querying about the crate metadata should *not* parse the entire crate, it
|
||||
// only needs the crate attributes (which are guaranteed to be at the top) be
|
||||
|
@ -8,5 +8,5 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id = "mylib"]
|
||||
#![crate_name = "mylib"]
|
||||
#![crate_type = "lib"]
|
||||
|
@ -8,5 +8,5 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id = "mylib"]
|
||||
#![crate_name = "mylib"]
|
||||
#![crate_type = "rlib"]
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_id="foo#0.1"]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
pub mod foo;
|
||||
pub mod bar;
|
||||
|
24
src/test/run-make/extern-flag-disambiguates/Makefile
Normal file
24
src/test/run-make/extern-flag-disambiguates/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
-include ../tools.mk
|
||||
|
||||
# Attempt to build this dependency tree:
|
||||
#
|
||||
# A.1 A.2
|
||||
# |\ |
|
||||
# | \ |
|
||||
# B \ C
|
||||
# \ | /
|
||||
# \|/
|
||||
# D
|
||||
#
|
||||
# Note that A.1 and A.2 are crates with the same name.
|
||||
|
||||
all:
|
||||
$(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
|
||||
$(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
|
||||
$(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
|
||||
$(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
|
||||
$(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
|
||||
$(call RUN,d)
|
||||
$(RUSTC) --cfg after d.rs --extern a=$(TMPDIR)/liba-1.rlib
|
||||
$(call RUN,d)
|
||||
|
16
src/test/run-make/extern-flag-disambiguates/a.rs
Normal file
16
src/test/run-make/extern-flag-disambiguates/a.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_name = "a"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
static FOO: uint = 3;
|
||||
|
||||
pub fn token() -> &'static uint { &FOO }
|
@ -8,14 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:issue-11908-2.rs
|
||||
// no-prefer-dynamic
|
||||
// ignore-android this test is incompatible with the android test runner
|
||||
// error-pattern: multiple rlib candidates for `url` found
|
||||
#![crate_name = "b"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// see comments in issue-11908-1 for what's going on here
|
||||
extern crate a;
|
||||
|
||||
extern crate url;
|
||||
|
||||
fn main() {}
|
||||
static FOO: uint = 3;
|
||||
|
||||
pub fn token() -> &'static uint { &FOO }
|
||||
pub fn a_token() -> &'static uint { a::token() }
|
19
src/test/run-make/extern-flag-disambiguates/c.rs
Normal file
19
src/test/run-make/extern-flag-disambiguates/c.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_name = "c"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
extern crate a;
|
||||
|
||||
static FOO: uint = 3;
|
||||
|
||||
pub fn token() -> &'static uint { &FOO }
|
||||
pub fn a_token() -> &'static uint { a::token() }
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -8,13 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:crateresolve8-1.rs
|
||||
#[cfg(before)] extern crate a;
|
||||
extern crate b;
|
||||
extern crate c;
|
||||
#[cfg(after)] extern crate a;
|
||||
|
||||
#![crate_id="crateresolve8#0.1"]
|
||||
fn t(a: &'static uint) -> uint { a as *const _ as uint }
|
||||
|
||||
extern crate crateresolve8 = "crateresolve8#0.1";
|
||||
//extern crate crateresolve8(vers = "0.1");
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(crateresolve8::f(), 20);
|
||||
fn main() {
|
||||
assert!(t(a::token()) == t(b::a_token()));
|
||||
assert!(t(a::token()) != t(c::a_token()));
|
||||
}
|
16
src/test/run-make/extern-flag-fun/Makefile
Normal file
16
src/test/run-make/extern-flag-fun/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) bar.rs --crate-type=rlib
|
||||
$(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
|
||||
$(RUSTC) foo.rs --extern hello && exit 1 || exit 0
|
||||
$(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
|
||||
$(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
|
||||
$(RUSTC) foo.rs \
|
||||
--extern bar=$(TMPDIR)/libbar.rlib \
|
||||
--extern bar=$(TMPDIR)/libbar-a.rlib \
|
||||
&& exit 1 || exit 0
|
||||
$(RUSTC) foo.rs \
|
||||
--extern bar=$(TMPDIR)/libbar.rlib \
|
||||
--extern bar=$(TMPDIR)/libbar.rlib
|
||||
$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
|
10
src/test/run-make/extern-flag-fun/bar.rs
Normal file
10
src/test/run-make/extern-flag-fun/bar.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
@ -8,7 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
extern crate bar;
|
||||
|
||||
#![crate_id = "url#0.11.0"]
|
||||
#![crate_type = "dylib"]
|
||||
fn main() {}
|
23
src/test/run-make/issue-11908/Makefile
Normal file
23
src/test/run-make/issue-11908/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
# This test ensures that if you have the same rlib or dylib at two locations
|
||||
# in the same path that you don't hit an assertion in the compiler.
|
||||
#
|
||||
# Note that this relies on `liburl` to be in the path somewhere else,
|
||||
# and then our aux-built libraries will collide with liburl (they have
|
||||
# the same version listed)
|
||||
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
mkdir $(TMPDIR)/other
|
||||
$(RUSTC) foo.rs --crate-type=dylib
|
||||
mv $(call DYLIB,foo) $(TMPDIR)/other
|
||||
$(RUSTC) foo.rs --crate-type=dylib
|
||||
$(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
|
||||
grep "multiple dylib candidates"
|
||||
rm -rf $(TMPDIR)
|
||||
mkdir -p $(TMPDIR)/other
|
||||
$(RUSTC) foo.rs --crate-type=rlib
|
||||
mv $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
|
||||
$(RUSTC) foo.rs --crate-type=rlib
|
||||
$(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
|
||||
grep "multiple rlib candidates"
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -8,6 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:can't find crate for `std`
|
||||
extern crate foo;
|
||||
|
||||
extern crate std = "std#bogus";
|
||||
fn main() {}
|
11
src/test/run-make/issue-11908/foo.rs
Normal file
11
src/test/run-make/issue-11908/foo.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_name = "foo"]
|
@ -5,6 +5,5 @@ CC := $(CC:-g=)
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -Z lto
|
||||
ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
|
||||
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRACFLAGS) -lstdc++
|
||||
$(call RUN,bar)
|
||||
|
@ -8,4 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[crate_type = "rlib"];
|
||||
#![crate_type = "rlib"]
|
||||
|
5
src/test/run-make/manual-crate-name/Makefile
Normal file
5
src/test/run-make/manual-crate-name/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) --crate-name foo bar.rs
|
||||
rm $(TMPDIR)/libfoo.rlib
|
@ -8,7 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_id = "url#0.11.0"]
|
||||
#![crate_type = "rlib"]
|
10
src/test/run-make/metadata-flag-frobs-symbols/Makefile
Normal file
10
src/test/run-make/metadata-flag-frobs-symbols/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -C metadata=a -C extra-filename=-a
|
||||
$(RUSTC) foo.rs -C metadata=b -C extra-filename=-b
|
||||
$(RUSTC) bar.rs \
|
||||
--extern foo1=$(TMPDIR)/libfoo-a.rlib \
|
||||
--extern foo2=$(TMPDIR)/libfoo-b.rlib \
|
||||
-Z print-link-args
|
||||
$(call RUN,bar)
|
18
src/test/run-make/metadata-flag-frobs-symbols/bar.rs
Normal file
18
src/test/run-make/metadata-flag-frobs-symbols/bar.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate foo1;
|
||||
extern crate foo2;
|
||||
|
||||
fn main() {
|
||||
let a = foo1::foo();
|
||||
let b = foo2::foo();
|
||||
assert!(a as *const _ != b as *const _);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user