libc: add openlibm, hide compiler_builtins in static lib
This commit is contained in:
parent
0b9f1c0fac
commit
9e187a4e94
14
test.c
14
test.c
@ -1,13 +1,11 @@
|
|||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <math.h>
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv) {
|
||||||
int x = 1234;
|
double x = round(1234.123);
|
||||||
printf("Hello %d!!!\n", x);
|
assert(fabs(x - 1234.000) < 0.00001);
|
||||||
|
double y = round(1234.5678);
|
||||||
|
assert(fabs(y - 1235.000) < 0.00001);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -65,14 +65,13 @@ fn compile_crt0(arch: &str, output_dir: impl AsRef<Path>) {
|
|||||||
command
|
command
|
||||||
.arg(format!("--target={}-unknown-none", arch))
|
.arg(format!("--target={}-unknown-none", arch))
|
||||||
.arg("-nostdlib")
|
.arg("-nostdlib")
|
||||||
.arg("-nostdinc")
|
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg("-o")
|
.arg("-o")
|
||||||
.arg(output_dir.join("crt0.o"))
|
.arg(output_dir.join("crt0.o"))
|
||||||
.arg(format!("crt/{}/crt0.S", arch));
|
.arg(format!("crt/{}/crt0.c", arch));
|
||||||
|
|
||||||
if !command.status().unwrap().success() {
|
if !command.status().unwrap().success() {
|
||||||
panic!("Couldn't compile crt0.S");
|
panic!("Couldn't compile crt0.o");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
.section .text
|
|
||||||
|
|
||||||
.global _start
|
|
||||||
.extern __ygglibc_entry
|
|
||||||
|
|
||||||
.type _start, %function
|
|
||||||
_start:
|
|
||||||
// %rdi -- kernel argument
|
|
||||||
leaq __ygglibc_entry(%rip), %rax
|
|
||||||
jmp *%rax
|
|
||||||
.size _start, . - _start
|
|
15
userspace/lib/ygglibc/crt/x86_64/crt0.c
Normal file
15
userspace/lib/ygglibc/crt/x86_64/crt0.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
extern __attribute__((noreturn)) void __ygglibc_entry(const void *);
|
||||||
|
|
||||||
|
// // rust's shlib export breaks memset symbol
|
||||||
|
// void *memset(void *dst, int val, size_t len) __attribute__((weak)) {
|
||||||
|
// for (size_t i = 0; i < len; ++i) {
|
||||||
|
// ((char *) dst)[i] = (char) val;
|
||||||
|
// }
|
||||||
|
// return dst;
|
||||||
|
// }
|
||||||
|
|
||||||
|
[[noreturn]] void _start(const void *arg) {
|
||||||
|
__ygglibc_entry(arg);
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
|
||||||
"max-atomic-width": 64,
|
"max-atomic-width": 64,
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
"features": "-avx,-sse,+soft-float",
|
"features": "+sse",
|
||||||
|
|
||||||
"disable-redzone": true,
|
"disable-redzone": true,
|
||||||
"executables": true,
|
"executables": true,
|
||||||
@ -22,6 +22,11 @@
|
|||||||
"linker": "rust-lld",
|
"linker": "rust-lld",
|
||||||
"linker-flavor": "ld.lld",
|
"linker-flavor": "ld.lld",
|
||||||
|
|
||||||
|
"late-link-args-static": {
|
||||||
|
"ld.lld": [
|
||||||
|
"--gc-sections"
|
||||||
|
]
|
||||||
|
},
|
||||||
"late-link-args-dynamic": {
|
"late-link-args-dynamic": {
|
||||||
"ld.lld": [
|
"ld.lld": [
|
||||||
"--dynamic-linker=/libexec/dyn-loader"
|
"--dynamic-linker=/libexec/dyn-loader"
|
||||||
|
20
userspace/lib/ygglibc/include/math.h
Normal file
20
userspace/lib/ygglibc/include/math.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <openlibm_math.h>
|
||||||
|
|
||||||
|
typedef float float_t;
|
||||||
|
typedef double double_t;
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846 /* pi */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_PI_2
|
||||||
|
#define M_PI_2 1.57079632679489661923 /* pi/2 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_PI_4
|
||||||
|
#define M_PI_4 0.78539816339744830962 /* pi/4 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_2_PI
|
||||||
|
#define M_2_PI 0.63661977236758134308 /* 2/pi */
|
||||||
|
#endif
|
@ -7,13 +7,7 @@ use core::{
|
|||||||
use libyalloc::{allocator::BucketAllocator, sys::PageProvider};
|
use libyalloc::{allocator::BucketAllocator, sys::PageProvider};
|
||||||
use yggdrasil_rt::{mem::MappingSource, sys as syscall};
|
use yggdrasil_rt::{mem::MappingSource, sys as syscall};
|
||||||
|
|
||||||
use crate::{
|
use crate::{error::EResult, headers::{errno, string::mem::{memcpy, memset}}, sync::Mutex};
|
||||||
error::EResult,
|
|
||||||
headers::{
|
|
||||||
errno,
|
|
||||||
string::{memcpy, memset},
|
|
||||||
}, sync::Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Allocator;
|
struct Allocator;
|
||||||
struct PageProviderImpl;
|
struct PageProviderImpl;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use core::ffi::c_int;
|
use core::ffi::{c_int, c_short};
|
||||||
|
|
||||||
use super::locale::locale_t;
|
use super::locale::locale_t;
|
||||||
|
|
||||||
@ -159,3 +159,8 @@ unsafe extern "C" fn tolower_l(_ch: c_int, _locale: locale_t) -> c_int {
|
|||||||
unsafe extern "C" fn toupper_l(_ch: c_int, _locale: locale_t) -> c_int {
|
unsafe extern "C" fn toupper_l(_ch: c_int, _locale: locale_t) -> c_int {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn __ctype_b_loc() -> *mut *mut c_short {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
use core::{
|
||||||
use core::{ffi::{c_int, c_void}, ptr::null_mut};
|
ffi::{c_int, c_void},
|
||||||
|
ptr::null_mut,
|
||||||
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn memccpy(
|
unsafe extern "C" fn memccpy(
|
||||||
@ -69,3 +71,23 @@ pub(super) unsafe extern "C" fn mempcpy(
|
|||||||
}
|
}
|
||||||
dst.add(n) as _
|
dst.add(n) as _
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn memset(dst: *mut c_void, val: c_int, n: usize) -> *mut c_void {
|
||||||
|
compiler_builtins::mem::memset(dst.cast(), val, n).cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn memcpy(dst: *mut c_void, src: *const c_void, n: usize) -> *mut c_void {
|
||||||
|
compiler_builtins::mem::memcpy(dst.cast(), src.cast(), n).cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn memmove(dst: *mut c_void, src: *const c_void, n: usize) -> *mut c_void {
|
||||||
|
compiler_builtins::mem::memmove(dst.cast(), src.cast(), n).cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn memcmp(s1: *const c_void, s2: *const c_void, n: usize) -> c_int {
|
||||||
|
compiler_builtins::mem::memcmp(s1.cast(), s2.cast(), n)
|
||||||
|
}
|
||||||
|
@ -2,9 +2,3 @@ use core::ffi::{c_char, c_int, c_void};
|
|||||||
|
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
pub fn strlen(s: *const c_char) -> usize;
|
|
||||||
pub fn memset(a: *mut c_void, c: c_int, n: usize) -> *mut c_void;
|
|
||||||
pub fn memcpy(dst: *mut c_void, src: *const c_void, n: usize) -> *mut c_void;
|
|
||||||
}
|
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{mem::mempcpy, memcpy, memset, strlen};
|
use super::mem::{memcpy, mempcpy, memset};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn stpcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char {
|
unsafe extern "C" fn stpcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char {
|
||||||
@ -120,6 +120,11 @@ unsafe extern "C" fn strerror_r(e: c_int, buf: *mut c_char, n: usize) -> *mut c_
|
|||||||
strncpy(buf, source, n)
|
strncpy(buf, source, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn strlen(s: *const c_char) -> usize {
|
||||||
|
compiler_builtins::mem::strlen(s.cast())
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn strncat(dst: *mut c_char, src: *const c_char, n: usize) -> *mut c_char {
|
unsafe extern "C" fn strncat(dst: *mut c_char, src: *const c_char, n: usize) -> *mut c_char {
|
||||||
if dst.is_null() || src.is_null() {
|
if dst.is_null() || src.is_null() {
|
||||||
@ -336,6 +341,11 @@ unsafe extern "C" fn strxfrm(_a: *mut c_char, _b: *const c_char, _n: usize) -> u
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn strxfrm_l(_a: *mut c_char, _b: *const c_char, _n: usize, _l: locale_t) -> usize {
|
unsafe extern "C" fn strxfrm_l(
|
||||||
|
_a: *mut c_char,
|
||||||
|
_b: *const c_char,
|
||||||
|
_n: usize,
|
||||||
|
_l: locale_t,
|
||||||
|
) -> usize {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,17 @@
|
|||||||
c_variadic,
|
c_variadic,
|
||||||
arbitrary_self_types_pointers,
|
arbitrary_self_types_pointers,
|
||||||
maybe_uninit_slice,
|
maybe_uninit_slice,
|
||||||
slice_internals
|
slice_internals,
|
||||||
|
linkage,
|
||||||
|
rustc_private
|
||||||
)]
|
)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![cfg_attr(not(test), no_std)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
extern crate compiler_builtins;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
|
||||||
|
186
xtask/src/build/c.rs
Normal file
186
xtask/src/build/c.rs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{env::BuildEnv, error::Error, util};
|
||||||
|
|
||||||
|
use super::cargo::CargoBuilder;
|
||||||
|
|
||||||
|
pub struct Llvm {
|
||||||
|
root: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Ygglibc {
|
||||||
|
static_lib_file: PathBuf,
|
||||||
|
shared_lib_file: PathBuf,
|
||||||
|
crt0_file: PathBuf,
|
||||||
|
include_paths: Vec<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Openlibm {
|
||||||
|
shared_lib_file: PathBuf,
|
||||||
|
static_lib_file: PathBuf,
|
||||||
|
include_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Llvm {
|
||||||
|
pub fn c_clang(&self, env: &BuildEnv) -> Command {
|
||||||
|
let mut command = Command::new(self.root.join("bin/clang"));
|
||||||
|
command.arg(format!("--target={}-unknown-yggdrasil", env.arch.name()));
|
||||||
|
command.arg(format!("--sysroot={}", env.llvm_sysroot.display()));
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clang(&self) -> PathBuf {
|
||||||
|
self.root.join("bin/clang")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_test_c_program(
|
||||||
|
env: &BuildEnv,
|
||||||
|
llvm: &Llvm,
|
||||||
|
install: &mut Vec<(PathBuf, PathBuf)>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
log::info!("Building a test C program");
|
||||||
|
let target_dir = &env.userspace_output_dir;
|
||||||
|
|
||||||
|
let mut command = llvm.c_clang(env);
|
||||||
|
command
|
||||||
|
.args([
|
||||||
|
"-Bdynamic",
|
||||||
|
"-fpie",
|
||||||
|
"-O0",
|
||||||
|
"-ggdb",
|
||||||
|
"-lm",
|
||||||
|
"-fstack-protector-strong",
|
||||||
|
])
|
||||||
|
.arg("-o")
|
||||||
|
.arg(target_dir.join("c-test"))
|
||||||
|
.arg(env.workspace_root.join("test.c"));
|
||||||
|
|
||||||
|
if !command.status()?.success() {
|
||||||
|
return Err(Error::ExternalCommandFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut command = llvm.c_clang(env);
|
||||||
|
command
|
||||||
|
.args(["-static", "-O0", "-ggdb", "-fstack-protector-strong", "-lm"])
|
||||||
|
.arg("-o")
|
||||||
|
.arg(target_dir.join("c-test-static"))
|
||||||
|
.arg(env.workspace_root.join("test.c"));
|
||||||
|
|
||||||
|
if !command.status()?.success() {
|
||||||
|
return Err(Error::ExternalCommandFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
install.push((target_dir.join("c-test"), "c-test".into()));
|
||||||
|
install.push((target_dir.join("c-test-static"), "c-test-static".into()));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_ygglibc(env: &BuildEnv, ygglibc: &Ygglibc) -> Result<(), Error> {
|
||||||
|
log::info!("Installing ygglibc into LLVM sysroot");
|
||||||
|
|
||||||
|
let dst_lib_dir = env.llvm_sysroot.join("lib");
|
||||||
|
let dst_include_dir = env.llvm_sysroot.join("usr/include");
|
||||||
|
|
||||||
|
fs::create_dir_all(&dst_lib_dir)?;
|
||||||
|
fs::create_dir_all(&dst_include_dir)?;
|
||||||
|
|
||||||
|
fs::copy(&ygglibc.static_lib_file, dst_lib_dir.join("libygglibc.a"))?;
|
||||||
|
fs::copy(&ygglibc.shared_lib_file, dst_lib_dir.join("libygglibc.so"))?;
|
||||||
|
fs::copy(&ygglibc.crt0_file, dst_lib_dir.join("crt0.o"))?;
|
||||||
|
|
||||||
|
for path in ygglibc.include_paths.iter() {
|
||||||
|
util::copy_dir_recursive(path, &dst_include_dir)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_ygglibc(env: &BuildEnv) -> Result<Ygglibc, Error> {
|
||||||
|
let ygglibc_dir = env.workspace_root.join("userspace/lib/ygglibc");
|
||||||
|
let target_dir = ygglibc_dir.join(format!(
|
||||||
|
"target/{}-unknown-none/{}",
|
||||||
|
env.arch.name(),
|
||||||
|
env.profile.dir()
|
||||||
|
));
|
||||||
|
CargoBuilder::Ygglibc(env).build(&ygglibc_dir)?;
|
||||||
|
|
||||||
|
let static_lib_file = target_dir.join("libygglibc.a");
|
||||||
|
let shared_lib_file = target_dir.join("libygglibc.so");
|
||||||
|
let crt0_file = target_dir.join("crt0.o");
|
||||||
|
let generated_includes = target_dir.join("include");
|
||||||
|
let static_includes = ygglibc_dir.join("include");
|
||||||
|
|
||||||
|
Ok(Ygglibc {
|
||||||
|
static_lib_file,
|
||||||
|
shared_lib_file,
|
||||||
|
crt0_file,
|
||||||
|
include_paths: vec![generated_includes, static_includes],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO clone openlibm
|
||||||
|
fn build_openlibm(env: &BuildEnv, llvm: &Llvm) -> Result<Openlibm, Error> {
|
||||||
|
fn make(env: &BuildEnv, llvm: &Llvm, libm_path: &Path) -> Command {
|
||||||
|
let mut command = Command::new("make");
|
||||||
|
command.env("SYSROOT", &env.llvm_sysroot);
|
||||||
|
command.env("ARCH", env.arch.name());
|
||||||
|
command.env("TRIPLE", format!("{}-unknown-yggdrasil", env.arch.name()));
|
||||||
|
command.env("USEGCC", "0");
|
||||||
|
command.env("USECLANG", "1");
|
||||||
|
command.env("CC", llvm.clang());
|
||||||
|
command.current_dir(&libm_path);
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!("Building openlibm");
|
||||||
|
|
||||||
|
let libm_path = env.workspace_root.join("toolchain-c/libs/openlibm");
|
||||||
|
|
||||||
|
let mut command = make(env, llvm, &libm_path);
|
||||||
|
if !command.status()?.success() {
|
||||||
|
return Err(Error::ExternalCommandFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Openlibm {
|
||||||
|
shared_lib_file: libm_path.join("libopenlibm.so.4.0"),
|
||||||
|
static_lib_file: libm_path.join("libopenlibm.a"),
|
||||||
|
include_path: libm_path.join("include"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_openlibm(env: &BuildEnv, libm: &Openlibm) -> Result<(), Error> {
|
||||||
|
fs::copy(&libm.static_lib_file, env.llvm_sysroot.join("lib/libm.a"))?;
|
||||||
|
fs::copy(&libm.shared_lib_file, env.llvm_sysroot.join("lib/libm.so"))?;
|
||||||
|
|
||||||
|
util::copy_dir_recursive(&libm.include_path, env.llvm_sysroot.join("usr/include"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_llvm(env: &BuildEnv) -> Result<Llvm, Error> {
|
||||||
|
// TODO actually build and install LLVM
|
||||||
|
Ok(Llvm {
|
||||||
|
root: env.workspace_root.join("toolchain-c/prefix/host"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_c(env: &BuildEnv, install: &mut Vec<(PathBuf, PathBuf)>) -> Result<(), Error> {
|
||||||
|
let llvm = build_llvm(env)?;
|
||||||
|
let ygglibc = build_ygglibc(env)?;
|
||||||
|
install_ygglibc(env, &ygglibc)?;
|
||||||
|
let libm = build_openlibm(env, &llvm)?;
|
||||||
|
install_openlibm(env, &libm)?;
|
||||||
|
|
||||||
|
build_test_c_program(env, &llvm, install)?;
|
||||||
|
|
||||||
|
install.push((ygglibc.shared_lib_file, "lib/libygglibc.so".into()));
|
||||||
|
install.push((libm.shared_lib_file, "lib/libopenlibm.so.4".into()));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -90,7 +90,8 @@ impl<'e> CargoBuilder<'e> {
|
|||||||
|
|
||||||
command
|
command
|
||||||
.arg(arg)
|
.arg(arg)
|
||||||
.arg("-Zbuild-std=core,alloc,compiler_builtins")
|
.arg("-Zbuild-std=core,alloc")
|
||||||
|
.arg("-Zbuild-std-features=compiler-builtins-mangled-names,compiler-builtins-mem")
|
||||||
.arg(&format!("--target={target}"));
|
.arg(&format!("--target={target}"));
|
||||||
|
|
||||||
if env.verbose {
|
if env.verbose {
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
use std::{path::PathBuf, process::Command};
|
|
||||||
|
|
||||||
use crate::{env::BuildEnv, error::Error};
|
|
||||||
|
|
||||||
pub struct Llvm {
|
|
||||||
root: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Llvm {
|
|
||||||
pub fn c_clang(&self, env: &BuildEnv) -> Command {
|
|
||||||
let mut command = Command::new(self.root.join("bin/clang"));
|
|
||||||
command.arg(format!("--target={}-unknown-yggdrasil", env.arch.name()));
|
|
||||||
command.arg(format!("--sysroot={}", env.llvm_sysroot.display()));
|
|
||||||
command
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_llvm(env: &BuildEnv) -> Result<Llvm, Error> {
|
|
||||||
// TODO actually build and install LLVM
|
|
||||||
Ok(Llvm {
|
|
||||||
root: env.workspace_root.join("toolchain-c/prefix/host"),
|
|
||||||
})
|
|
||||||
}
|
|
@ -13,8 +13,8 @@ use crate::{
|
|||||||
pub mod i686;
|
pub mod i686;
|
||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
|
|
||||||
|
pub mod c;
|
||||||
mod cargo;
|
mod cargo;
|
||||||
pub mod llvm;
|
|
||||||
mod module;
|
mod module;
|
||||||
pub mod toolchain;
|
pub mod toolchain;
|
||||||
mod userspace;
|
mod userspace;
|
||||||
|
@ -7,21 +7,14 @@ use std::{
|
|||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
build::{cargo::CargoBuilder, llvm},
|
build::{c, cargo::CargoBuilder},
|
||||||
check::AllOk,
|
check::AllOk,
|
||||||
env::BuildEnv,
|
env::BuildEnv,
|
||||||
error::Error,
|
error::Error,
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{llvm::Llvm, InitrdGenerated};
|
use super::InitrdGenerated;
|
||||||
|
|
||||||
pub struct Ygglibc {
|
|
||||||
static_lib_file: PathBuf,
|
|
||||||
shared_lib_file: PathBuf,
|
|
||||||
crt0_file: PathBuf,
|
|
||||||
include_paths: Vec<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const PROGRAMS: &[(&str, &str)] = &[
|
const PROGRAMS: &[(&str, &str)] = &[
|
||||||
// init
|
// init
|
||||||
@ -73,102 +66,22 @@ const PROGRAMS: &[(&str, &str)] = &[
|
|||||||
("c-test-static", "c-test-static"),
|
("c-test-static", "c-test-static"),
|
||||||
];
|
];
|
||||||
|
|
||||||
fn build_test_c_program(env: &BuildEnv, llvm: &Llvm) -> Result<(), Error> {
|
fn build_userspace(
|
||||||
log::info!("Building a test C program");
|
env: &BuildEnv,
|
||||||
let target_dir = &env.userspace_output_dir;
|
extra: &mut Vec<(PathBuf, PathBuf)>,
|
||||||
|
_: AllOk,
|
||||||
let mut command = llvm.c_clang(env);
|
) -> Result<(), Error> {
|
||||||
command
|
|
||||||
.args([
|
|
||||||
"-v",
|
|
||||||
"-Bdynamic",
|
|
||||||
"-fpie",
|
|
||||||
"-O0",
|
|
||||||
"-ggdb",
|
|
||||||
"-fstack-protector-strong",
|
|
||||||
])
|
|
||||||
.arg("-o")
|
|
||||||
.arg(target_dir.join("c-test"))
|
|
||||||
.arg(env.workspace_root.join("test.c"));
|
|
||||||
|
|
||||||
if !command.status()?.success() {
|
|
||||||
return Err(Error::ExternalCommandFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut command = llvm.c_clang(env);
|
|
||||||
command
|
|
||||||
.args(["-v", "-static", "-O0", "-ggdb", "-fstack-protector-strong"])
|
|
||||||
.arg("-o")
|
|
||||||
.arg(target_dir.join("c-test-static"))
|
|
||||||
.arg(env.workspace_root.join("test.c"));
|
|
||||||
|
|
||||||
if !command.status()?.success() {
|
|
||||||
return Err(Error::ExternalCommandFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn install_ygglibc(env: &BuildEnv, ygglibc: &Ygglibc) -> Result<(), Error> {
|
|
||||||
log::info!("Installing ygglibc into LLVM sysroot");
|
|
||||||
|
|
||||||
let dst_lib_dir = env.llvm_sysroot.join("lib");
|
|
||||||
let dst_include_dir = env.llvm_sysroot.join("usr/include");
|
|
||||||
|
|
||||||
fs::create_dir_all(&dst_lib_dir)?;
|
|
||||||
fs::create_dir_all(&dst_include_dir)?;
|
|
||||||
|
|
||||||
fs::copy(&ygglibc.static_lib_file, dst_lib_dir.join("libygglibc.a"))?;
|
|
||||||
fs::copy(&ygglibc.shared_lib_file, dst_lib_dir.join("libygglibc.so"))?;
|
|
||||||
fs::copy(&ygglibc.crt0_file, dst_lib_dir.join("crt0.o"))?;
|
|
||||||
|
|
||||||
for path in ygglibc.include_paths.iter() {
|
|
||||||
util::copy_dir_recursive(path, &dst_include_dir)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_ygglibc(env: &BuildEnv) -> Result<Ygglibc, Error> {
|
|
||||||
let ygglibc_dir = env.workspace_root.join("userspace/lib/ygglibc");
|
|
||||||
let target_dir = ygglibc_dir.join(format!(
|
|
||||||
"target/{}-unknown-none/{}",
|
|
||||||
env.arch.name(),
|
|
||||||
env.profile.dir()
|
|
||||||
));
|
|
||||||
CargoBuilder::Ygglibc(env).build(&ygglibc_dir)?;
|
|
||||||
|
|
||||||
let static_lib_file = target_dir.join("libygglibc.a");
|
|
||||||
let shared_lib_file = target_dir.join("libygglibc.so");
|
|
||||||
let crt0_file = target_dir.join("crt0.o");
|
|
||||||
let generated_includes = target_dir.join("include");
|
|
||||||
let static_includes = ygglibc_dir.join("include");
|
|
||||||
|
|
||||||
Ok(Ygglibc {
|
|
||||||
static_lib_file,
|
|
||||||
shared_lib_file,
|
|
||||||
crt0_file,
|
|
||||||
include_paths: vec![generated_includes, static_includes],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_userspace(env: &BuildEnv, _: AllOk) -> Result<Ygglibc, Error> {
|
|
||||||
log::info!("Building userspace");
|
log::info!("Building userspace");
|
||||||
CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace"))?;
|
CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace"))?;
|
||||||
CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace/dynload-program"))?;
|
CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace/dynload-program"))?;
|
||||||
|
c::build_c(env, extra)?;
|
||||||
|
|
||||||
let ygglibc = build_ygglibc(env)?;
|
Ok(())
|
||||||
let llvm = llvm::build_llvm(env)?;
|
|
||||||
install_ygglibc(env, &ygglibc)?;
|
|
||||||
build_test_c_program(env, &llvm)?;
|
|
||||||
|
|
||||||
Ok(ygglibc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_rootfs<S: AsRef<Path>, D: AsRef<Path>>(
|
fn build_rootfs<S: AsRef<Path>, D: AsRef<Path>>(
|
||||||
env: &BuildEnv,
|
env: &BuildEnv,
|
||||||
install_extra: Vec<(PathBuf, PathBuf)>,
|
install_extra: Vec<(PathBuf, PathBuf)>,
|
||||||
ygglibc: &Ygglibc,
|
|
||||||
build_dir: S,
|
build_dir: S,
|
||||||
rootfs_dir: D,
|
rootfs_dir: D,
|
||||||
_: AllOk,
|
_: AllOk,
|
||||||
@ -218,11 +131,6 @@ fn build_rootfs<S: AsRef<Path>, D: AsRef<Path>>(
|
|||||||
|
|
||||||
log::info!("Installing ygglibc");
|
log::info!("Installing ygglibc");
|
||||||
|
|
||||||
util::copy_file(
|
|
||||||
&ygglibc.shared_lib_file,
|
|
||||||
rootfs_dir.join("lib/libygglibc.so"),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
log::info!("Installing extras");
|
log::info!("Installing extras");
|
||||||
for (src, dst) in install_extra {
|
for (src, dst) in install_extra {
|
||||||
util::copy_file(src, rootfs_dir.join(dst))?;
|
util::copy_file(src, rootfs_dir.join(dst))?;
|
||||||
@ -281,16 +189,16 @@ fn pack_initrd<P: AsRef<Path>>(env: &BuildEnv, rootfs_dir: P) -> Result<InitrdGe
|
|||||||
|
|
||||||
pub fn build_initrd(
|
pub fn build_initrd(
|
||||||
env: &BuildEnv,
|
env: &BuildEnv,
|
||||||
install_extra: Vec<(PathBuf, PathBuf)>,
|
mut install_extra: Vec<(PathBuf, PathBuf)>,
|
||||||
check: AllOk,
|
check: AllOk,
|
||||||
) -> Result<InitrdGenerated, Error> {
|
) -> Result<InitrdGenerated, Error> {
|
||||||
let rootfs_dir = env.userspace_output_dir.join("rootfs");
|
let rootfs_dir = env.userspace_output_dir.join("rootfs");
|
||||||
|
|
||||||
let ygglibc = build_userspace(env, check)?;
|
build_userspace(env, &mut install_extra, check)?;
|
||||||
|
|
||||||
build_rootfs(
|
build_rootfs(
|
||||||
env,
|
env,
|
||||||
install_extra,
|
install_extra,
|
||||||
&ygglibc,
|
|
||||||
&env.userspace_output_dir,
|
&env.userspace_output_dir,
|
||||||
&rootfs_dir,
|
&rootfs_dir,
|
||||||
check,
|
check,
|
||||||
|
@ -41,6 +41,7 @@ fn check_commands_x86_64() -> Result<CommandsOk, Error> {
|
|||||||
("mtools", "Install the `mtools` package"),
|
("mtools", "Install the `mtools` package"),
|
||||||
("mkfs.vfat", "Install the `dosfstools` package"),
|
("mkfs.vfat", "Install the `dosfstools` package"),
|
||||||
("ld64.lld", "Install LLVM"),
|
("ld64.lld", "Install LLVM"),
|
||||||
|
("cmake", "Install cmake"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user