Skip to content

Commit 644041e

Browse files
authored
Custom headers (#40)
1 parent 6a954d4 commit 644041e

File tree

3 files changed

+50
-66
lines changed

3 files changed

+50
-66
lines changed

c2wasm-api/src/chooks.ts

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
import fastify from 'fastify';
2-
import fs from 'fs';
31
import { mkdirSync, writeFileSync, existsSync, openSync, closeSync, readFileSync, renameSync, rmSync, unlinkSync } from "fs";
42
import { deflateSync } from "zlib";
53
import { execSync } from "child_process";
64
import { z } from 'zod';
7-
import fastifyCors from 'fastify-cors';
8-
import fastifyWebSocket from 'fastify-websocket';
9-
10-
const server = fastify();
11-
12-
server.register(fastifyCors, {
13-
// put your options here
14-
origin: '*'
15-
})
16-
server.register(fastifyWebSocket);
175

186
// Compilation code
197
const llvmDir = process.cwd() + "/clang/wasi-sdk";
208
const tempDir = "/tmp";
219
const sysroot = llvmDir + "/share/wasi-sysroot";
10+
const defaultHeaderDir = '/app/clang/includes';
2211

2312
export interface ResponseData {
2413
success: boolean;
@@ -35,20 +24,27 @@ export interface Task {
3524
output?: string;
3625
}
3726

38-
const requestBodySchema = z.object({
27+
export const requestBodySchema = z.object({
3928
output: z.enum(['wasm']),
4029
files: z.array(z.object({
4130
type: z.string(),
4231
name: z.string(),
4332
options: z.string().optional(),
4433
src: z.string()
4534
})),
35+
headers: z.array(
36+
z.object({
37+
type: z.string(),
38+
name: z.string(),
39+
src: z.string(),
40+
})
41+
).optional(),
4642
link_options: z.string().optional(),
4743
compress: z.boolean().optional(),
4844
strip: z.boolean().optional()
4945
});
5046

51-
type RequestBody = z.infer<typeof requestBodySchema>;
47+
export type RequestBody = z.infer<typeof requestBodySchema>;
5248

5349
// Input: JSON in the following format
5450
// {
@@ -130,9 +126,12 @@ function get_optimization_options() {
130126
return options.join(' ');
131127
}
132128

133-
function get_clang_options() {
134-
const clang_flags = `--sysroot=${sysroot} -xc -I/app/clang/includes -fdiagnostics-print-source-range-info -Werror=implicit-function-declaration`;
129+
function get_include_path(include_path: string) {
130+
return `-I${include_path}`;
131+
}
135132

133+
function get_clang_options() {
134+
const clang_flags = `--sysroot=${sysroot} -xc -fdiagnostics-print-source-range-info -Werror=implicit-function-declaration`;
136135
return clang_flags;
137136
}
138137

@@ -173,12 +172,10 @@ function validate_filename(name: string) {
173172
return parts;
174173
}
175174

176-
function link_c_files(source_files: string[], link_options: string, cwd: string, output: string, result_obj: Task) {
175+
function link_c_files(source_files: string[], include_path: string, link_options: string, cwd: string, output: string, result_obj: Task) {
177176
const files = source_files.join(' ');
178177
const clang = llvmDir + '/bin/clang';
179-
180-
const cmd = clang + ' ' + optimization_level + ' ' + get_clang_options() + ' ' + get_lld_options(link_options) + ' ' + files + ' -o ' + output;
181-
178+
const cmd = clang + ' ' + optimization_level + ' ' + get_clang_options() + ' ' + get_lld_options(link_options) + ' ' + files + ' -o ' + output + ' ' + get_include_path(include_path);
182179
const out = shell_exec(cmd, cwd);
183180
result_obj.console = sanitize_shell_output(out);
184181
if (!existsSync(output)) {
@@ -266,6 +263,7 @@ export function build_project(project: RequestBody, base: string) {
266263
};
267264
const dir = base + '.$';
268265
const result = base + '.wasm';
266+
const customHeadersDir = dir + "/includes";
269267

270268
const complete = (success: boolean, message: string) => {
271269
rmSync(dir, { recursive: true });
@@ -292,7 +290,13 @@ export function build_project(project: RequestBody, base: string) {
292290
mkdirSync(dir);
293291
}
294292

293+
const headerFiles = project.headers;
294+
if (!existsSync(customHeadersDir)) {
295+
mkdirSync(customHeadersDir);
296+
}
297+
295298
const sources = [];
299+
const headers = [];
296300
let options;
297301
for (let file of files) {
298302
const name = file.name;
@@ -316,12 +320,30 @@ export function build_project(project: RequestBody, base: string) {
316320

317321
writeFileSync(fileName, src);
318322
}
323+
324+
if (headerFiles) {
325+
for (let file of headerFiles) {
326+
const name = file.name;
327+
if (!validate_filename(name)) {
328+
return complete(false, "Invalid filename " + name);
329+
}
330+
let fileName = customHeadersDir + "/" + name;
331+
headers.push(fileName);
332+
333+
const src = file.src;
334+
if (!src) {
335+
return complete(false, "Header file " + name + " is empty");
336+
}
337+
writeFileSync(fileName, src);
338+
}
339+
}
319340
const link_options = project.link_options;
320341
const link_result_obj = {
321342
name: 'building wasm'
322343
};
323344
build_result.tasks.push(link_result_obj);
324-
if (!link_c_files(sources, link_options || '', dir, result, link_result_obj)) {
345+
346+
if (!link_c_files(sources, headerFiles && headers?.length ? customHeadersDir : defaultHeaderDir, link_options || '', dir, result, link_result_obj)) {
325347
return complete(false, 'Build error');
326348
}
327349

c2wasm-api/src/index.ts

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import fastify from 'fastify';
22
import { readFileSync, readdirSync } from "fs";
3-
import { z } from 'zod';
43
import fastifyCors from 'fastify-cors';
54
import fastifyWebSocket from 'fastify-websocket';
65
import * as ws from 'ws';
76
import * as rpc from 'vscode-ws-jsonrpc';
87
import * as rpcServer from 'vscode-ws-jsonrpc/lib/server';
9-
import { build_project as build_c_project } from './chooks';
10-
import { build_project as build_js_project } from './jshooks';
8+
import { build_project as build_c_project, requestBodySchema as requestCBodySchema, RequestBody as RequestCBody } from './chooks';
9+
import { build_project as build_js_project, requestBodySchema as requestJSBodySchema, RequestBody as RequestJSBody } from './jshooks';
1110

1211
const server = fastify();
1312

@@ -36,34 +35,6 @@ export interface Task {
3635
output?: string;
3736
}
3837

39-
const requestCBodySchema = z.object({
40-
output: z.enum(['wasm']),
41-
files: z.array(z.object({
42-
type: z.string(),
43-
name: z.string(),
44-
options: z.string().optional(),
45-
src: z.string()
46-
})),
47-
link_options: z.string().optional(),
48-
compress: z.boolean().optional(),
49-
strip: z.boolean().optional()
50-
});
51-
const requestJSBodySchema = z.object({
52-
output: z.enum(['bc']),
53-
files: z.array(z.object({
54-
type: z.string(),
55-
name: z.string(),
56-
options: z.string().optional(),
57-
src: z.string()
58-
})),
59-
link_options: z.string().optional(),
60-
compress: z.boolean().optional(),
61-
strip: z.boolean().optional()
62-
});
63-
64-
type RequestCBody = z.infer<typeof requestCBodySchema>;
65-
type RequestJSBody = z.infer<typeof requestJSBodySchema>;
66-
6738
server.post('/api/build', async (req, reply) => {
6839
// Bail out early if not HTTP POST
6940
if (req.method !== 'POST') {
@@ -82,6 +53,7 @@ server.post('/api/build', async (req, reply) => {
8253
const result = build_c_project(body, baseName);
8354
return reply.code(200).send(result);
8455
} catch (ex) {
56+
console.error(ex);
8557
return reply.code(500).send(`500 Internal server error: ${ex}`)
8658
}
8759
// return reply.code(200).send({ hello: 'world' });
@@ -105,6 +77,7 @@ server.post('/api/build/js', async (req, reply) => {
10577
const result = build_js_project(body, baseName);
10678
return reply.code(200).send(result);
10779
} catch (ex) {
80+
console.error(ex);
10881
return reply.code(500).send(`500 Internal server error: ${ex}`)
10982
}
11083
// return reply.code(200).send({ hello: 'world' });

c2wasm-api/src/jshooks.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
1-
import fastify from 'fastify';
21
import { mkdirSync, writeFileSync, existsSync, openSync, closeSync, readFileSync, rmSync, unlinkSync, copyFileSync } from "fs";
32
import { execSync } from "child_process";
43
import { z } from 'zod';
5-
import fastifyCors from 'fastify-cors';
6-
import fastifyWebSocket from 'fastify-websocket';
74
import { deflateSync } from 'zlib';
85

9-
const server = fastify();
10-
11-
server.register(fastifyCors, {
12-
// put your options here
13-
origin: '*'
14-
})
15-
server.register(fastifyWebSocket);
16-
176
export interface ResponseData {
187
success: boolean;
198
message: string;
@@ -29,7 +18,7 @@ export interface Task {
2918
output?: string;
3019
}
3120

32-
const requestBodySchema = z.object({
21+
export const requestBodySchema = z.object({
3322
output: z.enum(['bc']),
3423
files: z.array(z.object({
3524
type: z.string(),
@@ -42,7 +31,7 @@ const requestBodySchema = z.object({
4231
strip: z.boolean().optional()
4332
});
4433

45-
type RequestBody = z.infer<typeof requestBodySchema>;
34+
export type RequestBody = z.infer<typeof requestBodySchema>;
4635

4736
// Input: JSON in the following format
4837
// {
@@ -207,4 +196,4 @@ export function build_project(project: RequestBody, base: string) {
207196

208197
return complete(true, 'Success');
209198
}
210-
// END Compile code
199+
// END Compile code

0 commit comments

Comments
 (0)