@@ -19,6 +19,7 @@ server.register(fastifyWebSocket);
1919const llvmDir = process . cwd ( ) + "/clang/wasi-sdk" ;
2020const tempDir = "/tmp" ;
2121const sysroot = llvmDir + "/share/wasi-sysroot" ;
22+ const defaultHeaderDir = '/app/clang/includes' ;
2223
2324export interface ResponseData {
2425 success : boolean ;
@@ -43,6 +44,13 @@ const requestBodySchema = z.object({
4344 options : z . string ( ) . optional ( ) ,
4445 src : z . string ( )
4546 } ) ) ,
47+ headers : z . array (
48+ z . object ( {
49+ type : z . string ( ) ,
50+ name : z . string ( ) ,
51+ src : z . string ( ) ,
52+ } )
53+ ) . optional ( ) ,
4654 link_options : z . string ( ) . optional ( ) ,
4755 compress : z . boolean ( ) . optional ( ) ,
4856 strip : z . boolean ( ) . optional ( )
@@ -130,8 +138,12 @@ function get_optimization_options() {
130138 return options . join ( ' ' ) ;
131139}
132140
141+ function get_include_path ( include_path : string ) {
142+ return `-I${ include_path } ` ;
143+ }
144+
133145function get_clang_options ( ) {
134- const clang_flags = `--sysroot=${ sysroot } -xc -I/app/clang/includes - fdiagnostics-print-source-range-info -Werror=implicit-function-declaration` ;
146+ const clang_flags = `--sysroot=${ sysroot } -xc -fdiagnostics-print-source-range-info -Werror=implicit-function-declaration` ;
135147
136148 return clang_flags ;
137149}
@@ -173,12 +185,10 @@ function validate_filename(name: string) {
173185 return parts ;
174186}
175187
176- function link_c_files ( source_files : string [ ] , link_options : string , cwd : string , output : string , result_obj : Task ) {
188+ function link_c_files ( source_files : string [ ] , include_path : string , link_options : string , cwd : string , output : string , result_obj : Task ) {
177189 const files = source_files . join ( ' ' ) ;
178190 const clang = llvmDir + '/bin/clang' ;
179-
180- const cmd = clang + ' ' + optimization_level + ' ' + get_clang_options ( ) + ' ' + get_lld_options ( link_options ) + ' ' + files + ' -o ' + output ;
181-
191+ const cmd = clang + ' ' + optimization_level + ' ' + get_clang_options ( ) + ' ' + get_lld_options ( link_options ) + ' ' + files + ' -o ' + output + ' ' + get_include_path ( include_path ) ;
182192 const out = shell_exec ( cmd , cwd ) ;
183193 result_obj . console = sanitize_shell_output ( out ) ;
184194 if ( ! existsSync ( output ) ) {
@@ -266,6 +276,7 @@ export function build_project(project: RequestBody, base: string) {
266276 } ;
267277 const dir = base + '.$' ;
268278 const result = base + '.wasm' ;
279+ const customHeadersDir = dir + "/includes" ;
269280
270281 const complete = ( success : boolean , message : string ) => {
271282 rmSync ( dir , { recursive : true } ) ;
@@ -292,7 +303,13 @@ export function build_project(project: RequestBody, base: string) {
292303 mkdirSync ( dir ) ;
293304 }
294305
306+ const headerFiles = project . headers ;
307+ if ( ! existsSync ( customHeadersDir ) ) {
308+ mkdirSync ( customHeadersDir ) ;
309+ }
310+
295311 const sources = [ ] ;
312+ const headers = [ ] ;
296313 let options ;
297314 for ( let file of files ) {
298315 const name = file . name ;
@@ -316,12 +333,29 @@ export function build_project(project: RequestBody, base: string) {
316333
317334 writeFileSync ( fileName , src ) ;
318335 }
336+
337+ if ( headerFiles ) {
338+ for ( let file of headerFiles ) {
339+ const name = file . name ;
340+ if ( ! validate_filename ( name ) ) {
341+ return complete ( false , "Invalid filename " + name ) ;
342+ }
343+ let fileName = customHeadersDir + "/" + name ;
344+ headers . push ( fileName ) ;
345+
346+ const src = file . src ;
347+ if ( ! src ) {
348+ return complete ( false , "Header file " + name + " is empty" ) ;
349+ }
350+ writeFileSync ( fileName , src ) ;
351+ }
352+ }
319353 const link_options = project . link_options ;
320354 const link_result_obj = {
321355 name : 'building wasm'
322356 } ;
323357 build_result . tasks . push ( link_result_obj ) ;
324- if ( ! link_c_files ( sources , link_options || '' , dir , result , link_result_obj ) ) {
358+ if ( ! link_c_files ( sources , headerFiles && headers ?. length ? customHeadersDir : defaultHeaderDir , link_options || '' , dir , result , link_result_obj ) ) {
325359 return complete ( false , 'Build error' ) ;
326360 }
327361
0 commit comments