Add -Z no-link
flag
Adds a compiler option to allow rustc compile a crate without linking. With this flag, rustc serializes codegen_results into a .rlink file.
This commit is contained in:
parent
d1e594f402
commit
6a6ebb4403
11 changed files with 65 additions and 13 deletions
|
@ -3428,6 +3428,7 @@ dependencies = [
|
||||||
"rustc_session",
|
"rustc_session",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
|
"serialize",
|
||||||
"smallvec 1.0.0",
|
"smallvec 1.0.0",
|
||||||
"syntax",
|
"syntax",
|
||||||
]
|
]
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub use rustc_session::utils::NativeLibraryKind;
|
||||||
|
|
||||||
/// Where a crate came from on the local filesystem. One of these three options
|
/// Where a crate came from on the local filesystem. One of these three options
|
||||||
/// must be non-None.
|
/// must be non-None.
|
||||||
#[derive(PartialEq, Clone, Debug, HashStable)]
|
#[derive(PartialEq, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
|
||||||
pub struct CrateSource {
|
pub struct CrateSource {
|
||||||
pub dylib: Option<(PathBuf, PathKind)>,
|
pub dylib: Option<(PathBuf, PathKind)>,
|
||||||
pub rlib: Option<(PathBuf, PathKind)>,
|
pub rlib: Option<(PathBuf, PathKind)>,
|
||||||
|
@ -75,7 +75,7 @@ impl DepKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub enum LibSource {
|
pub enum LibSource {
|
||||||
Some(PathBuf),
|
Some(PathBuf),
|
||||||
MetadataOnly,
|
MetadataOnly,
|
||||||
|
@ -160,6 +160,7 @@ pub enum ExternCrateSource {
|
||||||
Path,
|
Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct EncodedMetadata {
|
pub struct EncodedMetadata {
|
||||||
pub raw_data: Vec<u8>,
|
pub raw_data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub type DependencyList = Vec<Linkage>;
|
||||||
/// This is local to the tcx, and is generally relevant to one session.
|
/// This is local to the tcx, and is generally relevant to one session.
|
||||||
pub type Dependencies = Vec<(config::CrateType, DependencyList)>;
|
pub type Dependencies = Vec<(config::CrateType, DependencyList)>;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
|
#[derive(Copy, Clone, PartialEq, Debug, HashStable, RustcEncodable, RustcDecodable)]
|
||||||
pub enum Linkage {
|
pub enum Linkage {
|
||||||
NotLinked,
|
NotLinked,
|
||||||
IncludedFromDylib,
|
IncludedFromDylib,
|
||||||
|
|
|
@ -28,6 +28,7 @@ rustc_incremental = { path = "../librustc_incremental" }
|
||||||
rustc_index = { path = "../librustc_index" }
|
rustc_index = { path = "../librustc_index" }
|
||||||
rustc_llvm = { path = "../librustc_llvm" }
|
rustc_llvm = { path = "../librustc_llvm" }
|
||||||
rustc_session = { path = "../librustc_session" }
|
rustc_session = { path = "../librustc_session" }
|
||||||
|
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
|
|
|
@ -33,6 +33,7 @@ use rustc_codegen_ssa::CompiledModule;
|
||||||
use rustc_errors::{FatalError, Handler};
|
use rustc_errors::{FatalError, Handler};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::fs;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use syntax::expand::allocator::AllocatorKind;
|
use syntax::expand::allocator::AllocatorKind;
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::util::common::ErrorReported;
|
use rustc::util::common::ErrorReported;
|
||||||
use rustc_codegen_ssa::ModuleCodegen;
|
use rustc_codegen_ssa::ModuleCodegen;
|
||||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||||
|
use rustc_serialize::json;
|
||||||
|
|
||||||
mod back {
|
mod back {
|
||||||
pub mod archive;
|
pub mod archive;
|
||||||
|
@ -298,6 +300,18 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sess.opts.debugging_opts.no_link {
|
||||||
|
// FIXME: use a binary format to encode the `.rlink` file
|
||||||
|
let rlink_data = json::encode(&codegen_results).map_err(|err| {
|
||||||
|
sess.fatal(&format!("failed to encode rlink: {}", err));
|
||||||
|
})?;
|
||||||
|
let rlink_file = outputs.with_extension("rlink");
|
||||||
|
fs::write(&rlink_file, rlink_data).map_err(|err| {
|
||||||
|
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
|
||||||
|
})?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// Run the linker on any artifacts that resulted from the LLVM run.
|
// Run the linker on any artifacts that resulted from the LLVM run.
|
||||||
// This should produce either a finished executable or library.
|
// This should produce either a finished executable or library.
|
||||||
sess.time("link_crate", || {
|
sess.time("link_crate", || {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use rustc_target::spec::{LinkerFlavor, LldFlavor};
|
||||||
|
|
||||||
/// For all the linkers we support, and information they might
|
/// For all the linkers we support, and information they might
|
||||||
/// need out of the shared crate context before we get rid of it.
|
/// need out of the shared crate context before we get rid of it.
|
||||||
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct LinkerInfo {
|
pub struct LinkerInfo {
|
||||||
exports: FxHashMap<CrateType, Vec<String>>,
|
exports: FxHashMap<CrateType, Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl<M> ModuleCodegen<M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct CompiledModule {
|
pub struct CompiledModule {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub kind: ModuleKind,
|
pub kind: ModuleKind,
|
||||||
|
@ -101,7 +101,7 @@ pub struct CachedModuleCodegen {
|
||||||
pub source: WorkProduct,
|
pub source: WorkProduct,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
|
||||||
pub enum ModuleKind {
|
pub enum ModuleKind {
|
||||||
Regular,
|
Regular,
|
||||||
Metadata,
|
Metadata,
|
||||||
|
@ -117,7 +117,14 @@ bitflags::bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Misc info we load from metadata to persist beyond the tcx.
|
/// Misc info we load from metadata to persist beyond the tcx.
|
||||||
#[derive(Debug)]
|
///
|
||||||
|
/// Note: though `CrateNum` is only meaningful within the same tcx, information within `CrateInfo`
|
||||||
|
/// is self-contained. `CrateNum` can be viewed as a unique identifier within a `CrateInfo`, where
|
||||||
|
/// `used_crate_source` contains all `CrateSource` of the dependents, and maintains a mapping from
|
||||||
|
/// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own
|
||||||
|
/// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource`
|
||||||
|
/// and the corresponding properties without referencing information outside of a `CrateInfo`.
|
||||||
|
#[derive(Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct CrateInfo {
|
pub struct CrateInfo {
|
||||||
pub panic_runtime: Option<CrateNum>,
|
pub panic_runtime: Option<CrateNum>,
|
||||||
pub compiler_builtins: Option<CrateNum>,
|
pub compiler_builtins: Option<CrateNum>,
|
||||||
|
@ -135,6 +142,7 @@ pub struct CrateInfo {
|
||||||
pub dependency_formats: Lrc<Dependencies>,
|
pub dependency_formats: Lrc<Dependencies>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct CodegenResults {
|
pub struct CodegenResults {
|
||||||
pub crate_name: Symbol,
|
pub crate_name: Symbol,
|
||||||
pub modules: Vec<CompiledModule>,
|
pub modules: Vec<CompiledModule>,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use rustc_data_structures::AtomicRef;
|
use rustc_data_structures::AtomicRef;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
use rustc_serialize::{Decoder, Encoder};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::u32;
|
use std::{u32, u64};
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
pub struct CrateId {
|
pub struct CrateId {
|
||||||
|
@ -86,8 +87,18 @@ impl fmt::Display for CrateNum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rustc_serialize::UseSpecializedEncodable for CrateNum {}
|
/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
|
||||||
impl rustc_serialize::UseSpecializedDecodable for CrateNum {}
|
/// Therefore, make sure to include the context when encode a `CrateNum`.
|
||||||
|
impl rustc_serialize::UseSpecializedEncodable for CrateNum {
|
||||||
|
fn default_encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
|
||||||
|
e.emit_u32(self.as_u32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl rustc_serialize::UseSpecializedDecodable for CrateNum {
|
||||||
|
fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
|
||||||
|
Ok(CrateNum::from_u32(d.read_u32()?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// A DefIndex is an index into the hir-map for a crate, identifying a
|
/// A DefIndex is an index into the hir-map for a crate, identifying a
|
||||||
|
@ -135,8 +146,21 @@ impl DefId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rustc_serialize::UseSpecializedEncodable for DefId {}
|
impl rustc_serialize::UseSpecializedEncodable for DefId {
|
||||||
impl rustc_serialize::UseSpecializedDecodable for DefId {}
|
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
|
let krate = u64::from(self.krate.as_u32());
|
||||||
|
let index = u64::from(self.index.as_u32());
|
||||||
|
s.emit_u64((krate << 32) | index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl rustc_serialize::UseSpecializedDecodable for DefId {
|
||||||
|
fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
|
||||||
|
let def_id = d.read_u64()?;
|
||||||
|
let krate = CrateNum::from_u32((def_id >> 32) as u32);
|
||||||
|
let index = DefIndex::from_u32((def_id & 0xffffffff) as u32);
|
||||||
|
Ok(DefId { krate, index })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
|
f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
|
||||||
|
|
|
@ -619,7 +619,7 @@ pub enum EntryFnType {
|
||||||
|
|
||||||
impl_stable_hash_via_hash!(EntryFnType);
|
impl_stable_hash_via_hash!(EntryFnType);
|
||||||
|
|
||||||
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
|
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub enum CrateType {
|
pub enum CrateType {
|
||||||
Executable,
|
Executable,
|
||||||
Dylib,
|
Dylib,
|
||||||
|
|
|
@ -950,4 +950,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||||
(such as entering an empty infinite loop) by inserting llvm.sideeffect"),
|
(such as entering an empty infinite loop) by inserting llvm.sideeffect"),
|
||||||
deduplicate_diagnostics: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
|
deduplicate_diagnostics: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
|
||||||
"deduplicate identical diagnostics"),
|
"deduplicate identical diagnostics"),
|
||||||
|
no_link: bool = (false, parse_bool, [TRACKED],
|
||||||
|
"compile without linking"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct SearchPath {
|
||||||
pub files: Vec<PathBuf>,
|
pub files: Vec<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq)]
|
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, RustcEncodable, RustcDecodable)]
|
||||||
pub enum PathKind {
|
pub enum PathKind {
|
||||||
Native,
|
Native,
|
||||||
Crate,
|
Crate,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue