Skip to content

Commit d03e434

Browse files
committed
[WIP]
1 parent be5e1a1 commit d03e434

File tree

9 files changed

+170
-1123
lines changed

9 files changed

+170
-1123
lines changed

0001-WIP.patch

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
From c15c3efc3d05ca93abef7e3838feb58a004ad001 Mon Sep 17 00:00:00 2001
2+
From: bjorn3 <[email protected]>
3+
Date: Sun, 31 Mar 2019 11:30:09 +0200
4+
Subject: [PATCH] [WIP]
5+
6+
---
7+
src/librustc_codegen_ssa/lib.rs | 23 +++++++++++++++++++++--
8+
1 file changed, 21 insertions(+), 2 deletions(-)
9+
10+
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
11+
index 69572733cc..9d08cf7d96 100644
12+
--- a/src/librustc_codegen_ssa/lib.rs
13+
+++ b/src/librustc_codegen_ssa/lib.rs
14+
@@ -18,6 +18,8 @@
15+
16+
#![recursion_limit="256"]
17+
18+
+#![feature(rustc_private)]
19+
+
20+
//! This crate contains codegen code that is used by all codegen backends (LLVM and others).
21+
//! The backend-agnostic functions of this crate use functions defined in various traits that
22+
//! have to be implemented by each backends.
23+
@@ -27,6 +29,25 @@
24+
#[macro_use] extern crate rustc_data_structures;
25+
#[macro_use] extern crate syntax;
26+
27+
+extern crate syntax_pos;
28+
+extern crate rustc_mir;
29+
+extern crate libc;
30+
+extern crate rustc_target;
31+
+extern crate rustc_codegen_utils;
32+
+extern crate serialize;
33+
+extern crate rustc_errors;
34+
+extern crate rustc_incremental;
35+
+extern crate memmap;
36+
+extern crate rustc_allocator;
37+
+extern crate cc;
38+
+extern crate rustc_apfloat;
39+
+extern crate tempfile;
40+
+extern crate parking_lot;
41+
+extern crate jobserver;
42+
+extern crate bitflags;
43+
+extern crate num_cpus;
44+
+extern crate rustc_fs_util;
45+
+
46+
use std::path::PathBuf;
47+
use rustc::dep_graph::WorkProduct;
48+
use rustc::session::config::{OutputFilenames, OutputType};
49+
@@ -160,5 +181,3 @@ pub struct CodegenResults {
50+
pub linker_info: back::linker::LinkerInfo,
51+
pub crate_info: CrateInfo,
52+
}
53+
-
54+
-__build_diagnostic_array! { librustc_codegen_ssa, DIAGNOSTICS }
55+
--
56+
2.11.0
57+

Cargo.lock

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ gimli = { git = "https://github.com/gimli-rs/gimli.git" }
2929
indexmap = "1.0.2"
3030
object = "0.11.0"
3131

32+
rustc_codegen_ssa = { path = "./rustc_codegen_ssa" }
33+
3234
# Uncomment to use local checkout of cranelift
3335
#[patch."https://github.com/CraneStation/cranelift.git"]
3436
#cranelift = { path = "../cranelift/cranelift-umbrella" }

rustc_codegen_ssa/Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "rustc_codegen_ssa"
3+
version = "0.1.0"
4+
authors = ["bjorn3 <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
9+
[lib]
10+
path = "../../rust/src/librustc_codegen_ssa/lib.rs"

src/archive.rs

+84-12
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
use std::collections::HashMap;
22
use std::fs::File;
3-
use std::path::PathBuf;
3+
use std::path::{Path, PathBuf};
44

55
use crate::prelude::*;
66

7+
use rustc_codegen_ssa::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
8+
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library};
9+
710
pub struct ArchiveConfig<'a> {
811
pub sess: &'a Session,
912
pub dst: PathBuf,
1013
pub src: Option<PathBuf>,
1114
pub lib_search_paths: Vec<PathBuf>,
1215
}
1316

14-
pub struct ArchiveBuilder<'a> {
15-
cfg: ArchiveConfig<'a>,
17+
pub struct ArArchiveBuilder<'a> {
18+
config: ArchiveConfig<'a>,
1619
src_archive: Option<ar::Archive<File>>,
1720
src_entries: HashMap<String, usize>,
1821
builder: ar::Builder<File>,
1922
update_symbols: bool,
2023
}
2124

22-
impl<'a> ArchiveBuilder<'a> {
23-
pub fn new(cfg: ArchiveConfig<'a>) -> Self {
25+
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
26+
fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
27+
use rustc_codegen_ssa::back::link::archive_search_paths;
28+
let cfg = ArchiveConfig {
29+
sess,
30+
dst: output.to_path_buf(),
31+
src: input.map(|p| p.to_path_buf()),
32+
lib_search_paths: archive_search_paths(sess),
33+
};
34+
2435
let (src_archive, src_entries) = if let Some(src) = &cfg.src {
2536
let mut archive = ar::Archive::new(File::open(src).unwrap());
2637
let mut entries = HashMap::new();
@@ -42,32 +53,68 @@ impl<'a> ArchiveBuilder<'a> {
4253

4354
let builder = ar::Builder::new(File::create(&cfg.dst).unwrap());
4455

45-
ArchiveBuilder {
46-
cfg,
56+
ArArchiveBuilder {
57+
config: cfg,
4758
src_archive,
4859
src_entries,
4960
builder,
5061
update_symbols: false,
5162
}
5263
}
5364

54-
pub fn src_files(&self) -> Vec<String> {
65+
fn src_files(&mut self) -> Vec<String> {
5566
self.src_entries.keys().cloned().collect()
5667
}
5768

58-
pub fn remove_file(&mut self, name: &str) {
69+
fn remove_file(&mut self, name: &str) {
5970
let file = self.src_entries.remove(name);
6071
assert!(
6172
file.is_some(),
6273
"Tried to remove file not existing in src archive",
6374
);
6475
}
6576

66-
pub fn update_symbols(&mut self) {
77+
fn add_file(&mut self, file: &Path) {
78+
self.builder.append_path(file).unwrap();
79+
}
80+
81+
fn add_native_library(&mut self, name: &str) {
82+
let location = find_library(name, &self.config.lib_search_paths, self.config.sess);
83+
self.add_archive(&location, |_| false).unwrap_or_else(|e| {
84+
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
85+
});
86+
}
87+
88+
fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool, skip_objects: bool) -> std::io::Result<()> {
89+
let obj_start = name.to_owned();
90+
91+
self.add_archive(rlib, move |fname: &str| {
92+
// Ignore bytecode/metadata files, no matter the name.
93+
if fname.ends_with(RLIB_BYTECODE_EXTENSION) || fname == METADATA_FILENAME {
94+
return true;
95+
}
96+
97+
// Don't include Rust objects if LTO is enabled
98+
if lto && fname.starts_with(&obj_start) && fname.ends_with(".o") {
99+
return true;
100+
}
101+
102+
// Otherwise if this is *not* a rust object and we're skipping
103+
// objects then skip this file
104+
if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
105+
return true;
106+
}
107+
108+
// ok, don't skip this
109+
return false;
110+
})
111+
}
112+
113+
fn update_symbols(&mut self) {
67114
self.update_symbols = true;
68115
}
69116

70-
pub fn build(mut self) {
117+
fn build(mut self) {
71118
// Add files from original archive
72119
if let Some(mut src_archive) = self.src_archive {
73120
for (_entry_name, entry_idx) in self.src_entries.into_iter() {
@@ -88,7 +135,7 @@ impl<'a> ArchiveBuilder<'a> {
88135

89136
// Run ranlib to be able to link the archive
90137
let status = std::process::Command::new("ranlib")
91-
.arg(self.cfg.dst)
138+
.arg(self.config.dst)
92139
.status()
93140
.expect("Couldn't run ranlib");
94141
assert!(
@@ -98,3 +145,28 @@ impl<'a> ArchiveBuilder<'a> {
98145
);
99146
}
100147
}
148+
149+
impl<'a> ArArchiveBuilder<'a> {
150+
fn add_archive<F>(&mut self, archive: &Path, mut skip: F) -> std::io::Result<()>
151+
where F: FnMut(&str) -> bool + 'static
152+
{
153+
let mut archive = ar::Archive::new(std::fs::File::open(archive)?);
154+
while let Some(entry) = archive.next_entry() {
155+
let entry = entry?;
156+
let orig_header = entry.header();
157+
158+
if skip(std::str::from_utf8(orig_header.identifier()).unwrap()) {
159+
continue;
160+
}
161+
162+
let mut header =
163+
ar::Header::new(orig_header.identifier().to_vec(), orig_header.size());
164+
header.set_mtime(orig_header.mtime());
165+
header.set_uid(orig_header.uid());
166+
header.set_gid(orig_header.gid());
167+
header.set_mode(orig_header.mode());
168+
self.builder.append(&header, entry).unwrap();
169+
}
170+
Ok(())
171+
}
172+
}

src/lib.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ mod common;
4747
mod constant;
4848
mod debuginfo;
4949
mod intrinsics;
50-
mod link;
51-
mod link_copied;
5250
mod linkage;
5351
mod main_shim;
5452
mod metadata;
@@ -389,20 +387,21 @@ impl CodegenBackend for CraneliftCodegenBackend {
389387
_dep_graph: &DepGraph,
390388
outputs: &OutputFilenames,
391389
) -> Result<(), ErrorReported> {
392-
let res = *res
390+
use rustc_codegen_ssa::back::link::link_binary;
391+
392+
let codegen_results = *res
393393
.downcast::<CodegenResults>()
394394
.expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");
395395

396-
for &crate_type in sess.crate_types.borrow().iter() {
397-
let output_name = out_filename(sess, crate_type, &outputs, &res.crate_name.as_str());
398-
match crate_type {
399-
CrateType::Rlib => link::link_rlib(sess, &res, output_name),
400-
CrateType::Dylib | CrateType::Executable => {
401-
link::link_natively(sess, crate_type, &res, &output_name);
402-
}
403-
_ => sess.fatal(&format!("Unsupported crate type: {:?}", crate_type)),
404-
}
405-
}
396+
let target_cpu = ::target_lexicon::HOST.to_string();
397+
link_binary::<crate::archive::ArArchiveBuilder<'_>>(
398+
sess,
399+
&codegen_results,
400+
outputs,
401+
&codegen_results.crate_name.as_str(),
402+
&target_cpu,
403+
);
404+
406405
Ok(())
407406
}
408407
}

0 commit comments

Comments
 (0)