Skip to content

Commit f5a89b0

Browse files
authored
Merge pull request #63 from rust-osdev/build-with-cargo-build
Make `cargo bootimage` use `cargo build` instead of `cargo xbuild`
2 parents c4c9b93 + b3aaf4f commit f5a89b0

File tree

15 files changed

+108
-75
lines changed

15 files changed

+108
-75
lines changed

.github/workflows/build.yml

+6-8
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ jobs:
6262

6363
- name: "Install Rustup Components"
6464
run: rustup component add rust-src llvm-tools-preview
65-
- name: "Install cargo-xbuild"
66-
run: cargo install cargo-xbuild --debug
6765

6866
# install QEMU
6967
- name: Install QEMU (Linux)
@@ -103,20 +101,20 @@ jobs:
103101
shell: bash {0}
104102
working-directory: example-kernels
105103

106-
- name: 'Run `cargo xrun` for "runner" kernel'
104+
- name: 'Run `cargo run` for "runner" kernel'
107105
run: |
108-
cargo xrun
106+
cargo run
109107
if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi
110108
shell: bash {0}
111109
working-directory: example-kernels/runner
112110

113-
- run: cargo xtest
111+
- run: cargo test
114112
working-directory: example-kernels/runner-test
115-
name: 'Run `cargo xtest` for "runner-test" kernel'
113+
name: 'Run `cargo test` for "runner-test" kernel'
116114

117-
- run: cargo xtest -Z doctest-xcompile
115+
- run: cargo test -Z doctest-xcompile
118116
working-directory: example-kernels/runner-doctest
119-
name: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel'
117+
name: 'Run `cargo test -Z doctest-xcompile` for "runner-doctest" kernel'
120118

121119
check_formatting:
122120
name: "Check Formatting"

Readme.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Now you can build the kernel project and create a bootable disk image from it by
3131
cargo bootimage --target your_custom_target.json [other_args]
3232
```
3333

34-
The command will invoke [`cargo xbuild`](https://github.com/rust-osdev/cargo-xbuild), forwarding all passed options. Then it will build the specified bootloader together with the kernel to create a bootable disk image.
34+
The command will invoke `cargo build`, forwarding all passed options. Then it will build the specified bootloader together with the kernel to create a bootable disk image.
3535

3636
### Running
3737

@@ -60,6 +60,10 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i
6060

6161
```toml
6262
[package.metadata.bootimage]
63+
# The cargo subcommand that will be used for building the kernel.
64+
#
65+
# For building using the `cargo-xbuild` crate, set this to `xbuild`.
66+
build-command = ["build"]
6367
# The command invoked with the created bootimage (the "{}" will be replaced
6468
# with the path to the bootable disk image)
6569
# Applies to `bootimage run` and `bootimage runner`

example-kernels/.cargo/config.toml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[unstable]
2+
build-std = ["core", "compiler_builtins"]

example-kernels/Cargo.lock

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

example-kernels/basic/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ authors = ["Philipp Oppermann <[email protected]>"]
55
edition = "2018"
66

77
[dependencies]
8-
bootloader = "0.9.3"
8+
bootloader = "0.9.7"
99
x86_64 = "0.11.0"

example-kernels/runner-doctest/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ authors = ["Philipp Oppermann <[email protected]>"]
55
edition = "2018"
66

77
[dependencies]
8-
bootloader = "0.9.3"
8+
bootloader = "0.9.7"
99
x86_64 = "0.11.0"
10+
rlibc = "1.0.0"
1011

1112
[package.metadata.bootimage]
1213
test-success-exit-code = 33 # (0x10 << 1) | 1

example-kernels/runner-doctest/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#![test_runner(crate::test_runner)]
55
#![reexport_test_harness_main = "test_main"]
66

7+
extern crate rlibc;
8+
79
/// add two numbers
810
///
911
/// ```

example-kernels/runner-test/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ name = "no-harness"
99
harness = false
1010

1111
[dependencies]
12-
bootloader = "0.9.3"
12+
bootloader = "0.9.7"
1313
x86_64 = "0.11.0"
14+
rlibc = "1.0.0"
1415

1516
[package.metadata.bootimage]
1617
test-success-exit-code = 33 # (0x10 << 1) | 1

example-kernels/runner-test/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#![test_runner(crate::test_runner)]
66
#![reexport_test_harness_main = "test_main"]
77

8+
extern crate rlibc;
9+
810
pub fn test_runner(tests: &[&dyn Fn()]) {
911
for test in tests.iter() {
1012
test();

example-kernels/runner/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ authors = ["Philipp Oppermann <[email protected]>"]
55
edition = "2018"
66

77
[dependencies]
8-
bootloader = "0.9.3"
8+
bootloader = "0.9.7"
99
x86_64 = "0.11.0"
1010

1111
[package.metadata.bootimage]

src/bin/cargo-bootimage.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use anyhow::{anyhow, Context, Result};
22
use bootimage::{
33
args::{BuildArgs, BuildCommand},
44
builder::Builder,
5-
help,
5+
config, help,
66
};
77
use std::{
88
env,
@@ -43,9 +43,10 @@ pub fn main() -> Result<()> {
4343

4444
fn build(args: BuildArgs) -> Result<()> {
4545
let mut builder = Builder::new(args.manifest_path().map(PathBuf::from))?;
46+
let config = config::read_config(builder.manifest_path())?;
4647
let quiet = args.quiet();
4748

48-
let executables = builder.build_kernel(&args.cargo_args(), quiet)?;
49+
let executables = builder.build_kernel(&args.cargo_args(), &config, quiet)?;
4950
if executables.is_empty() {
5051
return Err(anyhow!("no executables built"));
5152
}

src/builder/error.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@ pub enum BuildKernelError {
2929
)]
3030
XbuildNotFound,
3131

32-
/// Running `cargo xbuild` failed.
32+
/// Running `cargo build` failed.
3333
#[error("Kernel build failed.\nStderr: {}", String::from_utf8_lossy(.stderr))]
34-
XbuildFailed {
34+
BuildFailed {
3535
/// The standard error output.
3636
stderr: Vec<u8>,
3737
},
3838

39-
/// The output of `cargo xbuild --message-format=json` was not valid UTF-8
39+
/// The output of `cargo build --message-format=json` was not valid UTF-8
4040
#[error("Output of kernel build with --message-format=json is not valid UTF-8:\n{0}")]
41-
XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error),
42-
/// The output of `cargo xbuild --message-format=json` was not valid JSON
41+
BuildJsonOutputInvalidUtf8(std::string::FromUtf8Error),
42+
/// The output of `cargo build --message-format=json` was not valid JSON
4343
#[error("Output of kernel build with --message-format=json is not valid JSON:\n{0}")]
44-
XbuildJsonOutputInvalidJson(json::Error),
44+
BuildJsonOutputInvalidJson(json::Error),
4545
}
4646

4747
/// Represents an error that occurred when creating a bootimage.
@@ -59,7 +59,7 @@ pub enum CreateBootimageError {
5959
/// Building the bootloader failed
6060
#[error("Bootloader build failed.\nStderr: {}", String::from_utf8_lossy(.stderr))]
6161
BootloaderBuildFailed {
62-
/// The `cargo xbuild` output to standard error
62+
/// The `cargo build` output to standard error
6363
stderr: Vec<u8>,
6464
},
6565

@@ -76,12 +76,12 @@ pub enum CreateBootimageError {
7676
error: io::Error,
7777
},
7878

79-
/// The output of `cargo xbuild --message-format=json` was not valid UTF-8
79+
/// The output of `cargo build --message-format=json` was not valid UTF-8
8080
#[error("Output of bootloader build with --message-format=json is not valid UTF-8:\n{0}")]
81-
XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error),
82-
/// The output of `cargo xbuild --message-format=json` was not valid JSON
81+
BuildJsonOutputInvalidUtf8(std::string::FromUtf8Error),
82+
/// The output of `cargo build --message-format=json` was not valid JSON
8383
#[error("Output of bootloader build with --message-format=json is not valid JSON:\n{0}")]
84-
XbuildJsonOutputInvalidJson(json::Error),
84+
BuildJsonOutputInvalidJson(json::Error),
8585
}
8686

8787
/// There is something wrong with the bootloader dependency.

src/builder/mod.rs

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Provides functions to build the kernel and the bootloader.
22
3+
use crate::config::Config;
34
use cargo_metadata::Metadata;
45
use error::{BootloaderError, BuildKernelError, BuilderError, CreateBootimageError};
56
use std::{
@@ -37,25 +38,26 @@ impl Builder {
3738
&self.manifest_path
3839
}
3940

40-
/// Builds the kernel by executing `cargo xbuild` with the given arguments.
41+
/// Builds the kernel by executing `cargo build` with the given arguments.
4142
///
4243
/// Returns a list of paths to all built executables. For crates with only a single binary,
4344
/// the returned list contains only a single element.
4445
///
4546
/// If the quiet argument is set to true, all output to stdout is suppressed.
4647
pub fn build_kernel(
47-
&self,
48+
&mut self,
4849
args: &[String],
50+
config: &Config,
4951
quiet: bool,
5052
) -> Result<Vec<PathBuf>, BuildKernelError> {
5153
if !quiet {
5254
println!("Building kernel");
5355
}
5456

55-
// try to run cargo xbuild
57+
// try to build kernel
5658
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned());
5759
let mut cmd = process::Command::new(&cargo);
58-
cmd.arg("xbuild");
60+
cmd.args(&config.build_command);
5961
cmd.args(args);
6062
if !quiet {
6163
cmd.stdout(process::Stdio::inherit());
@@ -66,42 +68,44 @@ impl Builder {
6668
error: err,
6769
})?;
6870
if !output.status.success() {
69-
// try executing `cargo xbuild --help` to check whether cargo-xbuild is installed
70-
let mut help_command = process::Command::new("cargo");
71-
help_command.arg("xbuild").arg("--help");
72-
help_command.stdout(process::Stdio::null());
73-
help_command.stderr(process::Stdio::null());
74-
if let Ok(help_exit_status) = help_command.status() {
75-
if !help_exit_status.success() {
76-
return Err(BuildKernelError::XbuildNotFound);
71+
if config.build_command.starts_with(&["xbuild".into()]) {
72+
// try executing `cargo xbuild --help` to check whether cargo-xbuild is installed
73+
let mut help_command = process::Command::new("cargo");
74+
help_command.arg("xbuild").arg("--help");
75+
help_command.stdout(process::Stdio::null());
76+
help_command.stderr(process::Stdio::null());
77+
if let Ok(help_exit_status) = help_command.status() {
78+
if !help_exit_status.success() {
79+
return Err(BuildKernelError::XbuildNotFound);
80+
}
7781
}
7882
}
79-
return Err(BuildKernelError::XbuildFailed {
83+
return Err(BuildKernelError::BuildFailed {
8084
stderr: output.stderr,
8185
});
8286
}
8387

8488
// Retrieve binary paths
8589
let mut cmd = process::Command::new(cargo);
86-
cmd.arg("xbuild");
90+
cmd.args(&config.build_command);
8791
cmd.args(args);
8892
cmd.arg("--message-format").arg("json");
8993
let output = cmd.output().map_err(|err| BuildKernelError::Io {
9094
message: "failed to execute kernel build with json output",
9195
error: err,
9296
})?;
9397
if !output.status.success() {
94-
return Err(BuildKernelError::XbuildFailed {
98+
return Err(BuildKernelError::BuildFailed {
9599
stderr: output.stderr,
96100
});
97101
}
98102
let mut executables = Vec::new();
99103
for line in String::from_utf8(output.stdout)
100-
.map_err(BuildKernelError::XbuildJsonOutputInvalidUtf8)?
104+
.map_err(BuildKernelError::BuildJsonOutputInvalidUtf8)?
101105
.lines()
102106
{
103107
let mut artifact =
104-
json::parse(line).map_err(BuildKernelError::XbuildJsonOutputInvalidJson)?;
108+
json::parse(line).map_err(BuildKernelError::BuildJsonOutputInvalidJson)?;
105109
if let Some(executable) = artifact["executable"].take_string() {
106110
executables.push(PathBuf::from(executable));
107111
}
@@ -161,11 +165,11 @@ impl Builder {
161165
}
162166
let mut bootloader_elf_path = None;
163167
for line in String::from_utf8(output.stdout)
164-
.map_err(CreateBootimageError::XbuildJsonOutputInvalidUtf8)?
168+
.map_err(CreateBootimageError::BuildJsonOutputInvalidUtf8)?
165169
.lines()
166170
{
167171
let mut artifact =
168-
json::parse(line).map_err(CreateBootimageError::XbuildJsonOutputInvalidJson)?;
172+
json::parse(line).map_err(CreateBootimageError::BuildJsonOutputInvalidJson)?;
169173
if let Some(executable) = artifact["executable"].take_string() {
170174
if bootloader_elf_path
171175
.replace(PathBuf::from(executable))

0 commit comments

Comments
 (0)