Skip to content

Commit d4ed46f

Browse files
authored
Merge pull request rust-lang#495 from bjorn3/use_cg_clif_link
Use cg clif link
2 parents 964edb9 + aeecb45 commit d4ed46f

File tree

10 files changed

+90
-842
lines changed

10 files changed

+90
-842
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,8 @@ indexmap = "1.0.2"
3838
#[patch."https://github.com/gimli-rs/gimli.git"]
3939
#gimli = { path = "../" }
4040

41+
[patch.crates-io]
42+
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "non_multiple_of_two_identifiers_gnu_format" }
43+
4144
[profile.dev.overrides."*"]
4245
opt-level = 3

build_sysroot/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ alloc_system = { path = "./alloc_system" }
1313

1414
[patch.crates-io]
1515
rustc-std-workspace-core = { path = "./sysroot_src/src/tools/rustc-std-workspace-core" }
16+
rustc-std-workspace-alloc = { path = "./rustc-std-workspace-alloc" }
1617
compiler_builtins = { path = "./compiler_builtins" }
1718

1819
[profile.release]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "rustc-std-workspace-alloc"
3+
version = "1.0.0"
4+
authors = ["Alex Crichton <[email protected]>"]
5+
license = 'MIT/Apache-2.0'
6+
description = """
7+
Hack for the compiler's own build system
8+
"""
9+
edition = "2018"
10+
11+
[lib]
12+
path = "lib.rs"
13+
14+
[dependencies]
15+
alloc = { path = "../sysroot_src/src/liballoc" }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(no_core)]
2+
#![no_core]
3+
#![deny(rust_2018_idioms)]
4+
5+
pub use ::alloc::*;

example/alloc_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc, alloc_prelude, alloc_error_handler)]
1+
#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)]
22
#![no_std]
33

44
extern crate alloc;

src/archive.rs

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::collections::HashMap;
21
use std::fs::File;
32
use std::path::{Path, PathBuf};
43

@@ -8,12 +7,14 @@ use rustc_codegen_ssa::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
87
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library};
98

109
struct ArchiveConfig<'a> {
11-
pub sess: &'a Session,
12-
pub dst: PathBuf,
13-
pub src: Option<PathBuf>,
14-
pub lib_search_paths: Vec<PathBuf>,
10+
sess: &'a Session,
11+
dst: PathBuf,
12+
src: Option<PathBuf>,
13+
lib_search_paths: Vec<PathBuf>,
14+
use_gnu_style_archive: bool,
1515
}
1616

17+
#[derive(Debug)]
1718
enum ArchiveEntry {
1819
FromArchive { archive_index: usize, entry_index: usize },
1920
File(File),
@@ -22,7 +23,9 @@ enum ArchiveEntry {
2223
pub struct ArArchiveBuilder<'a> {
2324
config: ArchiveConfig<'a>,
2425
src_archives: Vec<ar::Archive<File>>,
25-
entries: HashMap<String, ArchiveEntry>,
26+
// Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
27+
// the end of an archive for linkers to not get confused.
28+
entries: Vec<(String, ArchiveEntry)>,
2629
update_symbols: bool,
2730
}
2831

@@ -34,25 +37,27 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
3437
dst: output.to_path_buf(),
3538
src: input.map(|p| p.to_path_buf()),
3639
lib_search_paths: archive_search_paths(sess),
40+
// FIXME test for linux and System V derivatives instead
41+
use_gnu_style_archive: !sess.target.target.options.is_like_osx,
3742
};
3843

3944
let (src_archives, entries) = if let Some(src) = &config.src {
4045
let mut archive = ar::Archive::new(File::open(src).unwrap());
41-
let mut entries = HashMap::new();
46+
let mut entries = Vec::new();
4247

4348
let mut i = 0;
4449
while let Some(entry) = archive.next_entry() {
4550
let entry = entry.unwrap();
46-
entries.insert(
51+
entries.push((
4752
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
4853
ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
49-
);
54+
));
5055
i += 1;
5156
}
5257

5358
(vec![archive], entries)
5459
} else {
55-
(vec![], HashMap::new())
60+
(vec![], Vec::new())
5661
};
5762

5863
ArArchiveBuilder {
@@ -64,22 +69,22 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
6469
}
6570

6671
fn src_files(&mut self) -> Vec<String> {
67-
self.entries.keys().cloned().collect()
72+
self.entries.iter().map(|(name, _)| name.clone()).collect()
6873
}
6974

7075
fn remove_file(&mut self, name: &str) {
71-
let file = self.entries.remove(name);
72-
assert!(
73-
file.is_some(),
74-
"Tried to remove file not existing in src archive",
75-
);
76+
let index = self.entries
77+
.iter()
78+
.position(|(entry_name, _)| entry_name == name)
79+
.expect("Tried to remove file not existing in src archive");
80+
self.entries.remove(index);
7681
}
7782

7883
fn add_file(&mut self, file: &Path) {
79-
self.entries.insert(
84+
self.entries.push((
8085
file.file_name().unwrap().to_str().unwrap().to_string(),
8186
ArchiveEntry::File(File::open(file).unwrap()),
82-
);
87+
));
8388
}
8489

8590
fn add_native_library(&mut self, name: &str) {
@@ -119,24 +124,44 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
119124
}
120125

121126
fn build(mut self) {
122-
let mut builder = ar::Builder::new(File::create(&self.config.dst).unwrap());
127+
enum BuilderKind {
128+
Bsd(ar::Builder<File>),
129+
Gnu(ar::GnuBuilder<File>),
130+
}
131+
132+
let archive_file = File::create(&self.config.dst).unwrap();
133+
let mut builder = if self.config.use_gnu_style_archive {
134+
BuilderKind::Gnu(ar::GnuBuilder::new(
135+
archive_file,
136+
self.entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(),
137+
))
138+
} else {
139+
BuilderKind::Bsd(ar::Builder::new(archive_file))
140+
};
123141

124142
// Add all files
125143
for (entry_name, entry) in self.entries.into_iter() {
126144
match entry {
127145
ArchiveEntry::FromArchive { archive_index, entry_index } => {
128146
let entry = self.src_archives[archive_index].jump_to_entry(entry_index).unwrap();
129147
let orig_header = entry.header();
148+
130149
let mut header =
131150
ar::Header::new(orig_header.identifier().to_vec(), orig_header.size());
132151
header.set_mtime(orig_header.mtime());
133152
header.set_uid(orig_header.uid());
134153
header.set_gid(orig_header.gid());
135154
header.set_mode(orig_header.mode());
136-
builder.append(&header, entry).unwrap();
155+
match builder {
156+
BuilderKind::Bsd(ref mut builder) => builder.append(&header, entry).unwrap(),
157+
BuilderKind::Gnu(ref mut builder) => builder.append(&header, entry).unwrap(),
158+
}
137159
}
138160
ArchiveEntry::File(mut file) => {
139-
builder.append_file(entry_name.as_bytes(), &mut file).unwrap();
161+
match builder {
162+
BuilderKind::Bsd(ref mut builder) => builder.append_file(entry_name.as_bytes(), &mut file).unwrap(),
163+
BuilderKind::Gnu(ref mut builder) => builder.append_file(entry_name.as_bytes(), &mut file).unwrap(),
164+
}
140165
}
141166
}
142167
}
@@ -169,10 +194,10 @@ impl<'a> ArArchiveBuilder<'a> {
169194
let entry = entry.unwrap();
170195
let file_name = String::from_utf8(entry.header().identifier().to_vec()).unwrap();
171196
if !skip(&file_name) {
172-
self.entries.insert(
197+
self.entries.push((
173198
file_name,
174199
ArchiveEntry::FromArchive { archive_index, entry_index: i },
175-
);
200+
));
176201
}
177202
i += 1;
178203
}

src/lib.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use rustc::util::common::ErrorReported;
2828
use rustc_codegen_ssa::back::linker::LinkerInfo;
2929
use rustc_codegen_ssa::CrateInfo;
3030
use rustc_codegen_utils::codegen_backend::CodegenBackend;
31-
use rustc_codegen_utils::link::out_filename;
3231
use rustc_mir::monomorphize::partitioning::CodegenUnitExt;
3332

3433
use cranelift::codegen::settings;
@@ -46,8 +45,6 @@ mod common;
4645
mod constant;
4746
mod debuginfo;
4847
mod intrinsics;
49-
mod link;
50-
mod link_copied;
5148
mod linkage;
5249
mod main_shim;
5350
mod metadata;
@@ -343,13 +340,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
343340
} else {
344341
None
345342
},
346-
metadata_module: CompiledModule {
343+
metadata_module: Some(CompiledModule {
347344
name: "dummy_metadata".to_string(),
348345
kind: ModuleKind::Metadata,
349346
object: None,
350347
bytecode: None,
351348
bytecode_compressed: None,
352-
},
349+
}),
353350
crate_hash: tcx.crate_hash(LOCAL_CRATE),
354351
metadata,
355352
windows_subsystem: None, // Windows is not yet supported
@@ -366,20 +363,21 @@ impl CodegenBackend for CraneliftCodegenBackend {
366363
_dep_graph: &DepGraph,
367364
outputs: &OutputFilenames,
368365
) -> Result<(), ErrorReported> {
369-
let res = *res
366+
use rustc_codegen_ssa::back::link::link_binary;
367+
368+
let codegen_results = *res
370369
.downcast::<CodegenResults>()
371370
.expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");
372371

373-
for &crate_type in sess.crate_types.borrow().iter() {
374-
let output_name = out_filename(sess, crate_type, &outputs, &res.crate_name.as_str());
375-
match crate_type {
376-
CrateType::Rlib => link::link_rlib(sess, &res, output_name),
377-
CrateType::Dylib | CrateType::Executable => {
378-
link::link_natively(sess, crate_type, &res, &output_name);
379-
}
380-
_ => sess.fatal(&format!("Unsupported crate type: {:?}", crate_type)),
381-
}
382-
}
372+
let target_cpu = ::target_lexicon::HOST.to_string();
373+
link_binary::<crate::archive::ArArchiveBuilder<'_>>(
374+
sess,
375+
&codegen_results,
376+
outputs,
377+
&codegen_results.crate_name.as_str(),
378+
&target_cpu,
379+
);
380+
383381
Ok(())
384382
}
385383
}

0 commit comments

Comments
 (0)