Skip to content

Commit 1dc7882

Browse files
jprendesCopilot
andauthored
Use static picolibc.h file instead of generating it at buildtime (#1407)
* Use static picolibc.h file instead of generating it at buildtime Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com> * Update src/hyperlight_guest_bin/include/picolibc.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com> * address review comments Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com> * fix c guests include path Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com> * bump to latest cargo-hyperlight Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com> --------- Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent f46aa22 commit 1dc7882

6 files changed

Lines changed: 162 additions & 153 deletions

File tree

.github/workflows/RustNightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
- name: Install cargo-hyperlight
8181
uses: taiki-e/install-action@74e87cbfa15a59692b158178d8905a61bf6fca95 # v2.75.20
8282
with:
83-
tool: cargo-hyperlight@0.1.8
83+
tool: cargo-hyperlight@0.1.9
8484

8585
- name: Build and move Rust guests
8686
run: |

.github/workflows/dep_build_guests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
- name: Install cargo-hyperlight
7171
uses: taiki-e/install-action@74e87cbfa15a59692b158178d8905a61bf6fca95 # v2.75.20
7272
with:
73-
tool: cargo-hyperlight@0.1.8
73+
tool: cargo-hyperlight@0.1.9
7474

7575
- name: Build Rust guests
7676
run: |

.github/workflows/dep_code_checks.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ jobs:
7676
- name: Install cargo-hyperlight
7777
uses: taiki-e/install-action@74e87cbfa15a59692b158178d8905a61bf6fca95 # v2.75.20
7878
with:
79-
tool: cargo-hyperlight@0.1.8
79+
tool: cargo-hyperlight@0.1.9
8080

8181
- name: clippy exhaustive check (debug)
8282
run: just clippy-exhaustive debug
@@ -149,7 +149,7 @@ jobs:
149149
- name: Install cargo-hyperlight
150150
uses: taiki-e/install-action@74e87cbfa15a59692b158178d8905a61bf6fca95 # v2.75.20
151151
with:
152-
tool: cargo-hyperlight@0.1.8
152+
tool: cargo-hyperlight@0.1.9
153153

154154
- name: clippy (debug)
155155
run: |

c.just

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mkdir := if os() == "windows" { "mkdir -f -p" } else { "mkdir -p"}
33
# Elf options
44
# We don't support stack protectors at the moment, but Arch Linux clang auto-enables them for -linux platforms, so explicitly disable them.
55
c-compile-options-elf := '-nostdlibinc -H --target=x86_64-unknown-linux-none -fno-stack-protector -fstack-clash-protection -mstack-probe-size=4096 -fPIC'
6-
c-include-flags-elf := "-I " + root / "src/hyperlight_guest_capi/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/picolibc/libc/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/picolibc/libc/stdio/"
6+
c-include-flags-elf := "-I " + root / "src/hyperlight_guest_capi/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/picolibc/libc/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/picolibc/libc/stdio/" + " -I " + root / "src/hyperlight_guest_bin/include/"
77
c-linker-options-elf := '--entry "entrypoint" --nostdlib -pie --no-dynamic-linker'
88
c-flags-debug-elf := '-O0'
99
c-flags-release-elf := '-O3'

src/hyperlight_guest_bin/build.rs

Lines changed: 12 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ limitations under the License.
1616

1717
mod build_files;
1818

19-
use std::io::Write;
2019
use std::path::{Path, PathBuf};
21-
use std::process::{Command, Stdio};
20+
use std::process::Command;
2221
use std::{env, fs};
2322

2423
use anyhow::{Context, Result, bail};
@@ -51,144 +50,6 @@ fn copy_includes<P: AsRef<Path>, Q: AsRef<Path> + std::fmt::Debug>(
5150
Ok(())
5251
}
5352

54-
fn detect_cc_feature(test_code: &str) -> Result<bool> {
55-
let cc = std::env::var("HYPERLIGHT_GUEST_clang").unwrap_or_else(|_| "clang".into());
56-
57-
let mut cmd = Command::new(&cc)
58-
.arg("-std=c18")
59-
.arg("-x")
60-
.arg("c")
61-
.arg("-")
62-
.arg("-fsyntax-only")
63-
.stdin(Stdio::piped())
64-
.stderr(Stdio::null())
65-
.stdout(Stdio::null())
66-
.spawn()
67-
.with_context(|| "failed to spawn compiler for feature test")?;
68-
69-
cmd.stdin
70-
.as_mut()
71-
.unwrap()
72-
.write_all(test_code.as_bytes())
73-
.with_context(|| "failed to write test code")?;
74-
75-
Ok(cmd
76-
.wait()
77-
.with_context(|| "failed to wait on cc command")?
78-
.success())
79-
}
80-
81-
fn gen_config_file(config_dir: &Path) -> Result<()> {
82-
let config_h = config_dir.join("picolibc.h");
83-
84-
let mut file = fs::File::create(&config_h)
85-
.with_context(|| format!("Could not create config file {:?}", config_h))?;
86-
87-
writeln!(file, "/* Generated by hyperlight build script */")?;
88-
writeln!(file, "#pragma once")?;
89-
writeln!(file)?;
90-
91-
writeln!(file, "#define _NEWLIB_VERSION \"4.3.0\"")?;
92-
writeln!(file, "#define __NEWLIB_VERSION__ \"4.3.0\"")?;
93-
writeln!(file, "#define __NEWLIB__ 4")?;
94-
writeln!(file, "#define __NEWLIB_MINOR__ 3")?;
95-
writeln!(file, "#define __NEWLIB_PATCHLEVEL__ 0")?;
96-
writeln!(file, "#define __PICOLIBC_VERSION__ \"1.8.11\"")?;
97-
writeln!(file, "#define __PICOLIBC__ 1")?;
98-
writeln!(file, "#define __PICOLIBC_MINOR__ 8")?;
99-
writeln!(file, "#define __PICOLIBC_PATCHLEVEL__ 11")?;
100-
writeln!(file)?;
101-
102-
// Static configuration
103-
writeln!(file, "#define __ASSERT_VERBOSE")?;
104-
writeln!(file, "#define __SINGLE_THREAD")?; // -Dsingle-thread=true
105-
writeln!(file, "#define __GLOBAL_ERRNO")?; // -Dnewlib-global-errno=true
106-
writeln!(file, "#define __INIT_FINI_ARRAY")?; // -Dinitfini-array=true
107-
writeln!(file, "#define __TINY_STDIO")?; // tinystdio is now the only stdio
108-
writeln!(file, "#define __IO_DEFAULT 'd'")?; // -Dformat-default=double
109-
writeln!(file, "#define __IO_FLOAT_EXACT")?; // default
110-
writeln!(file, "#define __IO_WCHAR")?; // -Dio-wchar=true
111-
writeln!(file, "#define __IEEE_LIBM")?; // math library without errno
112-
writeln!(file, "#define __FAST_STRCMP")?; // default optimization
113-
writeln!(file, "#define __FAST_BUFIO")?; // -Dfast-bufio=true
114-
writeln!(file, "#define __IO_SMALL_ULTOA")?; // avoid division in conversion
115-
116-
for test in &[
117-
"__builtin_alloca",
118-
"__builtin_ffs",
119-
"__builtin_ffsl",
120-
"__builtin_ffsll",
121-
"__builtin_ctz",
122-
"__builtin_ctzl",
123-
"__builtin_ctzll",
124-
"__builtin_copysign",
125-
"__builtin_copysignl",
126-
"__builtin_isinf",
127-
"__builtin_isinfl",
128-
"__builtin_isnan",
129-
"__builtin_isnanl",
130-
"__builtin_isfinite",
131-
"__builtin_finitel",
132-
"__builtin_issignalingl",
133-
"__builtin_expect",
134-
"__builtin_complex",
135-
"__builtin_add_overflow",
136-
"__builtin_mul_overflow",
137-
] {
138-
let code = format!(
139-
r#"
140-
#if __has_builtin({test})
141-
int main() {{ return 0; }}
142-
#else
143-
#error "Builtin not supported"
144-
#endif
145-
"#
146-
);
147-
148-
let has = if detect_cc_feature(&code)? { 1 } else { 0 };
149-
writeln!(
150-
file,
151-
"#define __HAVE_BUILTIN_{} {has}",
152-
test.trim_start_matches("__builtin_").to_uppercase()
153-
)?;
154-
}
155-
156-
let code = r#"_Complex double x = 1.0 + 2.0*I; int main() { return 0; }"#;
157-
let has = if detect_cc_feature(code)? { 1 } else { 0 };
158-
writeln!(file, "#define __HAVE_COMPLEX {has}")?;
159-
160-
// Static undefs
161-
writeln!(file, "#undef __ARM_SEMIHOST")?; // -Dsemihost=false
162-
writeln!(file, "#undef __SEMIHOST")?; // -Dsemihost=false
163-
writeln!(file, "#undef __THREAD_LOCAL_STORAGE")?; // -Dthread-local-storage=false
164-
writeln!(file, "#undef __THREAD_LOCAL_STORAGE_API")?;
165-
writeln!(file, "#undef __THREAD_LOCAL_STORAGE_RP2040")?;
166-
writeln!(file, "#undef __THREAD_LOCAL_STORAGE_STACK_GUARD")?;
167-
writeln!(file, "#undef __ENABLE_MALLOC")?; // -Denable-malloc=false
168-
writeln!(file, "#undef __MALLOC_CLEAR_FREED")?;
169-
writeln!(file, "#undef __MB_CAPABLE")?; // no multibyte support
170-
writeln!(file, "#undef __HAVE_FCNTL")?; // freestanding environment
171-
writeln!(file, "#undef __STDIO_LOCKING")?; // single-thread
172-
writeln!(file, "#undef __IO_C99_FORMATS")?; // -Dio-c99-formats=false
173-
writeln!(file, "#undef __IO_LONG_DOUBLE")?; // not enabled
174-
writeln!(file, "#undef __IO_LONG_LONG")?; // minimal format
175-
writeln!(file, "#undef __IO_MINIMAL_LONG_LONG")?;
176-
writeln!(file, "#undef __IO_PERCENT_B")?; // not enabled
177-
writeln!(file, "#undef __IO_PERCENT_N")?; // not enabled
178-
writeln!(file, "#undef __IO_POS_ARGS")?; // not enabled
179-
writeln!(file, "#undef __MATH_ERRNO")?; // IEEE math only
180-
writeln!(file, "#undef __OBSOLETE_MATH")?;
181-
writeln!(file, "#undef __OBSOLETE_MATH_DOUBLE")?;
182-
writeln!(file, "#undef __OBSOLETE_MATH_FLOAT")?;
183-
writeln!(file, "#undef __PREFER_SIZE_OVER_SPEED")?; // release build
184-
writeln!(file, "#undef __ATOMIC_UNGETC")?; // single-thread
185-
writeln!(file, "#undef __IEEEFP_FUNCS")?;
186-
writeln!(file, "#undef __INIT_FINI_FUNCS")?; // using INIT_FINI_ARRAY instead
187-
writeln!(file, "#undef __HAVE_BITFIELDS_IN_PACKED_STRUCTS")?;
188-
189-
Ok(())
190-
}
191-
19253
fn cc_build(picolibc_dir: &PathBuf, target: &str) -> Result<cc::Build> {
19354
let mut build = cc::Build::new();
19455
let compiler = env::var("HYPERLIGHT_GUEST_clang").unwrap_or("clang".to_string());
@@ -252,11 +113,6 @@ fn cc_build(picolibc_dir: &PathBuf, target: &str) -> Result<cc::Build> {
252113
.define("_LIBC", None)
253114
.define("_FILE_OFFSET_BITS", "64");
254115

255-
// TODO: this is wrong, it should generate config file to out_dir/include
256-
// but how downstream crates get at it then? And TBH I think having piclibc
257-
// headers (features.h) depend on a build time header is odd
258-
gen_config_file(&picolibc_dir.join("libc/include"))?;
259-
260116
match target {
261117
"x86" | "x86_64" => {
262118
build.include(picolibc_dir.join("libm/machine/x86"));
@@ -323,6 +179,7 @@ fn init_submodule() -> Result<()> {
323179
fn cargo_main() -> Result<()> {
324180
println!("cargo:rerun-if-changed=build.rs");
325181
println!("cargo:rerun-if-changed=third_party/picolibc");
182+
println!("cargo:rerun-if-changed=include/picolibc.h");
326183
println!("cargo:rerun-if-env-changed=HYPERLIGHT_GUEST_TOOLCHAIN_ROOT");
327184

328185
let out_dir = env::var("OUT_DIR").expect("cargo OUT_DIR not set");
@@ -332,15 +189,21 @@ fn cargo_main() -> Result<()> {
332189
fs::create_dir_all(&include_dir)
333190
.with_context(|| format!("Could not create include dir {include_dir:?}"))?;
334191

192+
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("cargo MANIFEST_DIR not set");
193+
let manifest_dir = PathBuf::from(manifest_dir);
194+
let picolibc_dir = manifest_dir.join("third_party/picolibc");
195+
335196
if cfg!(feature = "libc") {
336-
if !Path::new("third_party/picolibc/COPYING.picolibc").exists() {
197+
if !picolibc_dir.join("COPYING.picolibc").exists() {
337198
eprintln!("Setting up submodules");
338199
init_submodule().with_context(|| "failed to init picolibc submodule")?;
339200
}
340201

341-
let picolibc_dir = PathBuf::from("third_party/picolibc");
342202
let mut build = cc_build(&picolibc_dir, &target)?;
343203

204+
// include for picolibc configuration: picolibc.h
205+
build.include(manifest_dir.join("include"));
206+
344207
add_libc(&mut build, &picolibc_dir, &target)?;
345208
add_libm(&mut build, &picolibc_dir, &target)?;
346209

@@ -349,7 +212,8 @@ fn cargo_main() -> Result<()> {
349212
}
350213

351214
build.compile("hyperlight_guest_bin");
352-
copy_includes(&include_dir, "third_party/picolibc/libc/include")?;
215+
copy_includes(&include_dir, picolibc_dir.join("libc/include"))?;
216+
copy_includes(&include_dir, manifest_dir.join("include"))?;
353217
}
354218

355219
let include_str = include_dir

0 commit comments

Comments
 (0)