Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 43 additions & 21 deletions c2wasm-api/src/chooks.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import fastify from 'fastify';
import fs from 'fs';
import { mkdirSync, writeFileSync, existsSync, openSync, closeSync, readFileSync, renameSync, rmSync, unlinkSync } from "fs";
import { deflateSync } from "zlib";
import { execSync } from "child_process";
import { z } from 'zod';
import fastifyCors from 'fastify-cors';
import fastifyWebSocket from 'fastify-websocket';

const server = fastify();

server.register(fastifyCors, {
// put your options here
origin: '*'
})
server.register(fastifyWebSocket);

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

export interface ResponseData {
success: boolean;
Expand All @@ -35,20 +24,27 @@ export interface Task {
output?: string;
}

const requestBodySchema = z.object({
export const requestBodySchema = z.object({
output: z.enum(['wasm']),
files: z.array(z.object({
type: z.string(),
name: z.string(),
options: z.string().optional(),
src: z.string()
})),
headers: z.array(
z.object({
type: z.string(),
name: z.string(),
src: z.string(),
})
).optional(),
link_options: z.string().optional(),
compress: z.boolean().optional(),
strip: z.boolean().optional()
});

type RequestBody = z.infer<typeof requestBodySchema>;
export type RequestBody = z.infer<typeof requestBodySchema>;

// Input: JSON in the following format
// {
Expand Down Expand Up @@ -130,9 +126,12 @@ function get_optimization_options() {
return options.join(' ');
}

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

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

Expand Down Expand Up @@ -173,12 +172,10 @@ function validate_filename(name: string) {
return parts;
}

function link_c_files(source_files: string[], link_options: string, cwd: string, output: string, result_obj: Task) {
function link_c_files(source_files: string[], include_path: string, link_options: string, cwd: string, output: string, result_obj: Task) {
const files = source_files.join(' ');
const clang = llvmDir + '/bin/clang';

const cmd = clang + ' ' + optimization_level + ' ' + get_clang_options() + ' ' + get_lld_options(link_options) + ' ' + files + ' -o ' + output;

const cmd = clang + ' ' + optimization_level + ' ' + get_clang_options() + ' ' + get_lld_options(link_options) + ' ' + files + ' -o ' + output + ' ' + get_include_path(include_path);
const out = shell_exec(cmd, cwd);
result_obj.console = sanitize_shell_output(out);
if (!existsSync(output)) {
Expand Down Expand Up @@ -266,6 +263,7 @@ export function build_project(project: RequestBody, base: string) {
};
const dir = base + '.$';
const result = base + '.wasm';
const customHeadersDir = dir + "/includes";

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

const headerFiles = project.headers;
if (!existsSync(customHeadersDir)) {
mkdirSync(customHeadersDir);
}

const sources = [];
const headers = [];
let options;
for (let file of files) {
const name = file.name;
Expand All @@ -316,12 +320,30 @@ export function build_project(project: RequestBody, base: string) {

writeFileSync(fileName, src);
}

if (headerFiles) {
for (let file of headerFiles) {
const name = file.name;
if (!validate_filename(name)) {
return complete(false, "Invalid filename " + name);
}
let fileName = customHeadersDir + "/" + name;
headers.push(fileName);

const src = file.src;
if (!src) {
return complete(false, "Header file " + name + " is empty");
}
writeFileSync(fileName, src);
}
}
const link_options = project.link_options;
const link_result_obj = {
name: 'building wasm'
};
build_result.tasks.push(link_result_obj);
if (!link_c_files(sources, link_options || '', dir, result, link_result_obj)) {

if (!link_c_files(sources, headerFiles && headers?.length ? customHeadersDir : defaultHeaderDir, link_options || '', dir, result, link_result_obj)) {
return complete(false, 'Build error');
}

Expand Down
35 changes: 4 additions & 31 deletions c2wasm-api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import fastify from 'fastify';
import { readFileSync, readdirSync } from "fs";
import { z } from 'zod';
import fastifyCors from 'fastify-cors';
import fastifyWebSocket from 'fastify-websocket';
import * as ws from 'ws';
import * as rpc from 'vscode-ws-jsonrpc';
import * as rpcServer from 'vscode-ws-jsonrpc/lib/server';
import { build_project as build_c_project } from './chooks';
import { build_project as build_js_project } from './jshooks';
import { build_project as build_c_project, requestBodySchema as requestCBodySchema, RequestBody as RequestCBody } from './chooks';
import { build_project as build_js_project, requestBodySchema as requestJSBodySchema, RequestBody as RequestJSBody } from './jshooks';

const server = fastify();

Expand Down Expand Up @@ -36,34 +35,6 @@ export interface Task {
output?: string;
}

const requestCBodySchema = z.object({
output: z.enum(['wasm']),
files: z.array(z.object({
type: z.string(),
name: z.string(),
options: z.string().optional(),
src: z.string()
})),
link_options: z.string().optional(),
compress: z.boolean().optional(),
strip: z.boolean().optional()
});
const requestJSBodySchema = z.object({
output: z.enum(['bc']),
files: z.array(z.object({
type: z.string(),
name: z.string(),
options: z.string().optional(),
src: z.string()
})),
link_options: z.string().optional(),
compress: z.boolean().optional(),
strip: z.boolean().optional()
});

type RequestCBody = z.infer<typeof requestCBodySchema>;
type RequestJSBody = z.infer<typeof requestJSBodySchema>;

server.post('/api/build', async (req, reply) => {
// Bail out early if not HTTP POST
if (req.method !== 'POST') {
Expand All @@ -82,6 +53,7 @@ server.post('/api/build', async (req, reply) => {
const result = build_c_project(body, baseName);
return reply.code(200).send(result);
} catch (ex) {
console.error(ex);
return reply.code(500).send(`500 Internal server error: ${ex}`)
}
// return reply.code(200).send({ hello: 'world' });
Expand All @@ -105,6 +77,7 @@ server.post('/api/build/js', async (req, reply) => {
const result = build_js_project(body, baseName);
return reply.code(200).send(result);
} catch (ex) {
console.error(ex);
return reply.code(500).send(`500 Internal server error: ${ex}`)
}
// return reply.code(200).send({ hello: 'world' });
Expand Down
17 changes: 3 additions & 14 deletions c2wasm-api/src/jshooks.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import fastify from 'fastify';
import { mkdirSync, writeFileSync, existsSync, openSync, closeSync, readFileSync, rmSync, unlinkSync, copyFileSync } from "fs";
import { execSync } from "child_process";
import { z } from 'zod';
import fastifyCors from 'fastify-cors';
import fastifyWebSocket from 'fastify-websocket';
import { deflateSync } from 'zlib';

const server = fastify();

server.register(fastifyCors, {
// put your options here
origin: '*'
})
server.register(fastifyWebSocket);

export interface ResponseData {
success: boolean;
message: string;
Expand All @@ -29,7 +18,7 @@ export interface Task {
output?: string;
}

const requestBodySchema = z.object({
export const requestBodySchema = z.object({
output: z.enum(['bc']),
files: z.array(z.object({
type: z.string(),
Expand All @@ -42,7 +31,7 @@ const requestBodySchema = z.object({
strip: z.boolean().optional()
});

type RequestBody = z.infer<typeof requestBodySchema>;
export type RequestBody = z.infer<typeof requestBodySchema>;

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

return complete(true, 'Success');
}
// END Compile code
// END Compile code
Loading