packages/runtime/gulpfile.js
const fs = require("fs");
const path = require("path");
const child_process = require("child_process");
const gulp = require("gulp");
const del = require("del");
const tmp = require("tmp");
const util = require("util");
const merge = require("merge-stream");
const runSequence = require("run-sequence");
const EMSCRIPTEN_CACHE_DIR = path.resolve(".emscripten_cache");
gulp.task("default", ["build"]);
gulp.task("build", function (cb) {
runSequence(
"build:clean",
"build:libs",
"build:runtime",
["copy:release", "copy:libs"],
cb
);
});
gulp.task("test", function (cb) {
runSequence(
"test:clean",
"test:build",
"test:run",
cb
);
});
gulp.task("build:clean", function () {
return del([
"./cmake-build-release",
EMSCRIPTEN_CACHE_DIR,
"./bin"
]);
});
gulp.task("build:runtime", function (cb) {
runSequence(
"build:runtime:configure",
"build:runtime:make",
"build:runtime:make", // We need to build the project twice. Otherwise the first artifact is missing on travis???
cb
);
});
gulp.task("build:runtime:configure", function () {
if (!fs.existsSync("cmake-build-release")) {
fs.mkdirSync("cmake-build-release");
}
const emscriptenCMake = path.resolve("./tools/emscripten/cmake/Modules/Platform/Emscripten.cmake");
const command = util.format('cmake -E chdir cmake-build-release cmake -DCMAKE_BUILD_TYPE=Release -DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=ON -DCMAKE_TOOLCHAIN_FILE="%s" ..', emscriptenCMake);
const env = Object.create(process.env);
env.EM_CONFIG = path.resolve("./.emscripten");
child_process.execSync(command, { env: env, stdio: "inherit" });
});
gulp.task("build:runtime:make", function () {
const command = "cmake --build cmake-build-release";
const env = Object.create(process.env);
env.EM_CONFIG = path.resolve("./.emscripten");
child_process.execSync(command, { env: env, stdio: "inherit" });
});
/**
* Generating libcxx.a with embuilder fails for the given source code.
* Therefore, just use another c++ source to generate the libcxx.a archive and
* perform the same operation as embuilder would (overall, just translate and link any c++ file) to generate the needed libraries.
* The output is generated in ./.emscripten_cache/wasm
*/
gulp.task("build:libs", function() {
if (!fs.existsSync(EMSCRIPTEN_CACHE_DIR)) {
fs.mkdirSync(EMSCRIPTEN_CACHE_DIR);
}
const em = path.resolve("./tools/emscripten/em++");
const sourceTmpFile = tmp.fileSync({ postfix: ".cc" });
fs.writeFileSync(sourceTmpFile.name,
"#include <iostream>\n" +
"int main() {\n" +
" std::cout << \"hello\";" +
" return 0;\n" +
"}"
);
const outputTmpFile = tmp.fileSync({ postfix: ".js" });
const env = Object.create(process.env);
env.EMCC_CFLAGS = (env.EMCC_CFLAGS || "") + " -s NO_EXIT_RUNTIME=1 -DMALLOC_INSPECT_ALL"; // expose the malloc_inspect_all function
child_process.execSync(util.format("%s %s -std=c++11 -o %s --cache %s --em-config %s", em, sourceTmpFile.name, outputTmpFile.name, EMSCRIPTEN_CACHE_DIR, path.resolve("./.emscripten")),
{
env: env,
stdio: "inherit"
});
sourceTmpFile.removeCallback();
outputTmpFile.removeCallback();
});
gulp.task("copy:libs", function () {
const libs = ["dlmalloc.bc", "libc.bc", "libcxx_noexcept.a", "libcxx.a", "libcxxabi.bc", "wasm-libc.bc", "wasm_compiler_rt.a", "wasm_libc_rt.a"];
const src = gulp.src(libs.map(lib => path.join(EMSCRIPTEN_CACHE_DIR, "wasm", lib)));
return src.pipe(gulp.dest("./bin/shared"));
});
gulp.task("copy:release", function () {
return gulp.src("./cmake-build-release/libspeedyjs-runtime*.bc").pipe(gulp.dest("./bin"));
});
gulp.task("test:clean", function () {
return del([
"./cmake-build-debug"
]);
});
gulp.task("test:build", function () {
fs.mkdirSync("cmake-build-debug");
const command = "cmake -E chdir cmake-build-debug cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build cmake-build-debug --target runUnitTests";
child_process.execSync(command, { stdio: "inherit" });
});
gulp.task("test:run", function () {
child_process.execSync("./cmake-build-debug/test/runUnitTests", { stdio: "inherit" });
});