@@ -16,9 +16,8 @@ limitations under the License.
1616
1717mod build_files;
1818
19- use std:: io:: Write ;
2019use std:: path:: { Path , PathBuf } ;
21- use std:: process:: { Command , Stdio } ;
20+ use std:: process:: Command ;
2221use std:: { env, fs} ;
2322
2423use 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-
19253fn 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<()> {
323179fn 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