Skip to content

Commit e1c6330

Browse files
bors[bot]phil-opp
andcommitted
Merge #51
51: Rewrite build system r=phil-opp a=phil-opp - [x] Blocked on rust-lang/rust#59351 - [x] Blocked on rust-lang/cargo#6778 Fixes #33 Fixes #48 Co-authored-by: Philipp Oppermann <dev@phil-opp.com>
2 parents a472a18 + 01a0828 commit e1c6330

15 files changed

+120
-385
lines changed

.cargo/config

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "x86_64-bootloader.json"

.travis.yml

-45
This file was deleted.

Cargo.lock

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

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ description = "An experimental pure-Rust x86 bootloader."
99
repository = "https://github.com/rust-osdev/bootloader"
1010
publish-lockfile = true
1111
edition = "2018"
12+
build = "build.rs"
1213

1314
[dependencies]
1415
xmas-elf = "0.6.2"
@@ -21,6 +22,9 @@ version = "0.2.4"
2122
default-features = false
2223
features = ["unicode"]
2324

25+
[build-dependencies]
26+
llvm-tools = "0.1"
27+
2428
[features]
2529
default = []
2630
vga_320x200 = []

azure-pipelines.yml

+10-17
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ trigger:
1010
- trying
1111
# Build pull requests.
1212
- master
13-
# Build post braches
14-
- post-*
1513

1614
strategy:
1715
matrix:
@@ -64,11 +62,11 @@ steps:
6462
displayName: 'Print Rust Version'
6563
continueOnError: true
6664

67-
- script: rustup component add rust-src
68-
displayName: 'Install Rustup Src Component'
65+
- script: rustup component add rust-src llvm-tools-preview
66+
displayName: 'Install Rustup Components'
6967

70-
- script: cargo install cargo-xbuild bootimage --debug
71-
displayName: 'Install cargo-xbuild and bootimage'
68+
- script: cargo install cargo-xbuild cargo-binutils --debug
69+
displayName: 'Install cargo-xbuild cargo-binutils'
7270

7371
- script: sudo apt update && sudo apt install qemu-system-x86
7472
condition: eq( variables['Agent.OS'], 'Linux' )
@@ -96,20 +94,15 @@ steps:
9694
workingDirectory: example-kernel
9795
displayName: 'Build Example Kernel'
9896

99-
- script: cargo run -- --kernel ../example-kernel/target/x86_64-example-kernel/debug/example-kernel
100-
workingDirectory: builder
97+
- script: cargo xbuild --release
10198
displayName: 'Build Bootloader'
99+
env: { KERNEL: "example-kernel/target/x86_64-example-kernel/debug/example-kernel" }
100+
101+
- script: cargo objcopy -- -I elf64-x86-64 -O binary --binary-architecture=i386:x86-64 target/x86_64-bootloader/release/bootloader target/x86_64-bootloader/release/bootloader.bin
102+
displayName: 'Convert Bootloader ELF to Binary'
102103

103104
- bash: |
104-
qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootloader/release/bootimage.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
105+
qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootloader/release/bootloader.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
105106
if [ $? -eq 123 ]; then (exit 0); else (exit 1); fi
106107
displayName: 'Test Bootloader'
107108

108-
- script: cargo run -- --kernel ../example-kernel/target/x86_64-example-kernel/debug/example-kernel --features vga_320x200
109-
workingDirectory: builder
110-
displayName: 'Build Bootloader (Feature vga_320x200)'
111-
112-
- bash: |
113-
qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootloader/release/bootimage.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none
114-
if [ $? -eq 123 ]; then (exit 0); else (exit 1); fi
115-
displayName: 'Test Bootloader (Feature vga_320x200)'

build.rs

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use std::{env, path::{Path, PathBuf}, process::{self, Command}};
2+
3+
fn main() {
4+
let target = env::var("TARGET").expect("TARGET not set");
5+
if Path::new(&target)
6+
.file_stem()
7+
.expect("target has no file stem")
8+
!= "x86_64-bootloader"
9+
{
10+
return;
11+
}
12+
13+
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
14+
let kernel = PathBuf::from(match env::var("KERNEL") {
15+
Ok(kernel) => kernel,
16+
Err(_) => {
17+
eprintln!(
18+
"The KERNEL environment variable must be set for building the bootloader."
19+
);
20+
process::exit(1);
21+
}
22+
});
23+
24+
let kernel_file_name = kernel.file_name().expect("KERNEL has no valid file name").to_str().expect("kernel file name not valid utf8");
25+
let kernel_file_name_replaced = kernel_file_name.replace('-', "_");
26+
let kernel_out_path = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
27+
let kernel_archive_path = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));
28+
29+
let llvm_tools = match llvm_tools::LlvmTools::new() {
30+
Ok(tools) => tools,
31+
Err(llvm_tools::Error::NotFound) => {
32+
eprintln!("Error: llvm-tools not found");
33+
eprintln!("Maybe the rustup component `llvm-tools-preview` is missing?");
34+
eprintln!(" Install it through: `rustup component add llvm-tools-preview`");
35+
process::exit(1);
36+
}
37+
Err(err) => {
38+
eprintln!("Failed to retrieve llvm-tools component: {:?}", err);
39+
process::exit(1);
40+
}
41+
};
42+
let objcopy = llvm_tools.tool(&llvm_tools::exe("llvm-objcopy")).expect("llvm-objcopy not found in llvm-tools");
43+
44+
let mut cmd = Command::new(objcopy);
45+
cmd.arg("-I").arg("binary");
46+
cmd.arg("-O").arg("elf64-x86-64");
47+
cmd.arg("--binary-architecture=i386:x86-64");
48+
cmd.arg("--rename-section").arg(".data=.kernel");
49+
cmd.arg("--redefine-sym").arg(format!("_binary_{}_start=_kernel_start_addr", kernel_file_name_replaced));
50+
cmd.arg("--redefine-sym").arg(format!("_binary_{}_end=_kernel_end_addr", kernel_file_name_replaced));
51+
cmd.arg("--redefine-sym").arg(format!("_binary_{}_size=_kernel_size", kernel_file_name_replaced));
52+
cmd.current_dir(kernel.parent().expect("KERNEL has no valid parent dir"));
53+
cmd.arg(&kernel_file_name);
54+
cmd.arg(&kernel_out_path);
55+
let exit_status = cmd.status().expect("failed to run objcopy");
56+
if !exit_status.success() {
57+
eprintln!("Error: Running objcopy failed");
58+
process::exit(1);
59+
}
60+
61+
let ar = llvm_tools.tool(&llvm_tools::exe("llvm-ar")).unwrap_or_else(|| {
62+
eprintln!("Failed to retrieve llvm-ar component");
63+
eprint!("This component is available since nightly-XXXX-XX-XX,");
64+
eprintln!("so try updating your toolchain if you're using an older nightly");
65+
process::exit(1);
66+
});
67+
let mut cmd = Command::new(ar);
68+
cmd.arg("crs");
69+
cmd.arg(&kernel_archive_path);
70+
cmd.arg(&kernel_out_path);
71+
let exit_status = cmd.status().expect("failed to run ar");
72+
if !exit_status.success() {
73+
eprintln!("Error: Running ar failed");
74+
process::exit(1);
75+
}
76+
77+
println!("cargo:rerun-if-env-changed=KERNEL");
78+
println!("cargo:rerun-if-changed={}", kernel.display());
79+
println!("cargo:rerun-if-changed=build.rs");
80+
println!("cargo:rustc-link-search=native={}", out_dir.display());
81+
println!("cargo:rustc-link-lib=static=kernel_bin-{}", kernel_file_name);
82+
}

builder/.gitignore

-2
This file was deleted.

builder/Cargo.lock

-74
This file was deleted.

builder/Cargo.toml

-11
This file was deleted.

0 commit comments

Comments
 (0)