Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create asbuild tool to fix passing asc parameters on the npm run command line #975

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions bin/asbuild
@@ -0,0 +1,10 @@
#!/usr/bin/env node

/* tslint:disable */

try { require("source-map-support").install(); } catch (e) {}

const asbuild = module.exports = require("../cli/asbuild/asbuild.js");
if (/\basbuild$/.test(process.argv[1])) {
process.exitCode = asbuild.main(process.argv.slice(2));
}
4 changes: 2 additions & 2 deletions bin/asinit
Expand Up @@ -224,8 +224,8 @@ function ensureGitignore() {
function ensurePackageJson() {
console.log("- Making sure that 'package.json' contains the build commands...")
const entryPath = path.relative(projectDir, entryFile).replace(/\\/g, "/");
const buildUntouched = "asc " + entryPath + " -b build/untouched.wasm -t build/untouched.wat --validate --sourceMap --debug";
const buildOptimized = "asc " + entryPath + " -b build/optimized.wasm -t build/optimized.wat --validate --sourceMap --optimize";
const buildUntouched = "asbuild --debug --";
const buildOptimized = "asbuild --release --";
const buildAll = "npm run asbuild:untouched && npm run asbuild:optimized";
if (!fs.existsSync(packageFile)) {
fs.writeFileSync(packageFile, JSON.stringify({
Expand Down
111 changes: 111 additions & 0 deletions cli/asbuild/asbuild.js
@@ -0,0 +1,111 @@
"use strict";
/**
* A tool to run asc, suitable for use by NPM or manually.
*
* It wraps the build process by allowing flags to be grouped into profiles.
*
* Run with --help for more information.
*
* @module cli/asbuild
*/

const util = require("util");
const execFile = util.promisify(require("child_process").execFile);

const fs = require("fs");
const path = require("path");

const optionsUtil = require("../util/options");
exports.options = require("./asbuild.json");

const profiles = require("./profiles.json");

// Assembles the build directory and profile information into an output wasm file path.
function outputWasmName(profile, options) {
if(profiles[profile] !== undefined) {
return path.join(options.buildDir, profiles[profile].default_name + ".wasm")
} else {
return "" // intentionally cause an asc error due to missing file name
}
}

// Assembles the build directory and profile information into an output wat file path.
function outputWatName(profile, options) {
if(profiles[profile] !== undefined) {
return path.join(options.buildDir, profiles[profile].default_name + ".wat")
} else {
return "" // intentionally cause an asc error due to missing file name
}
}

// Gather all the flags and options into an ASC command line, and run the compiler.
function ascRun(profile, argv) {
var execargs = [
argv.options.entryPath,
"-b", outputWasmName(profile, argv.options),
"-t", outputWatName(profile, argv.options)
];
if(profiles[profile] !== undefined) {
profiles[profile].args.forEach(e => execargs.push(e));
}
argv.trailing.forEach(e => execargs.push(e));

return execFile("asc", execargs);
}

// Nail down directories for the build if the user omitted them.
function cleanUpBuildDirs(argv) {
argv.options.baseDir = path.resolve(argv.options.baseDir);
while (!fs.existsSync(path.join(argv.options.baseDir, "package.json"))) {
argv.options.baseDir = path.normalize(path.join(argv.options.baseDir, ".."));
var p = path.parse(argv.options.baseDir);
if (p.root === p.dir) {
throw new Error("cannot find package.json; please specify --baseDir option");
}
}

if(argv.options.buildDir === undefined) {
argv.options.buildDir = path.relative(argv.options.baseDir,
path.join(argv.options.baseDir, "build"));
}
argv.options.assemblyDir = path.join(argv.options.baseDir, "assembly");
if (fs.existsSync(path.join(argv.options.assemblyDir, "index.ts"))) {
argv.options.entryPath = path.join(argv.options.assemblyDir, "index.ts");
} else {
argv.options.entryPath = argv.options.assemblyDir;
}

// NB: asc only accepts relative root paths, hence this trick
process.chdir(argv.options.baseDir);
argv.options.baseDir = path.relative(process.cwd(), argv.options.baseDir);
argv.options.buildDir = path.relative(process.cwd(), argv.options.buildDir);
argv.options.assemblyDir = path.relative(process.cwd(), argv.options.assemblyDir);
argv.options.entryPath = path.relative(process.cwd(), argv.options.entryPath);

return argv;
}

// Merge profile information with static options to populate the full list of options of asbuild.
function mergeConfigOptions() {
var config = {};
Object.keys(exports.options).forEach(k => config[k] = exports.options[k]);
Object.keys(profiles).forEach(k => config[k] = {
description: [ profiles[k].description ],
type: "b",
default: false
});
return config;
}

exports.main = async function main(argv) {
var argv = cleanUpBuildDirs(optionsUtil.parse(argv, mergeConfigOptions()));

if (argv.options.debug && argv.options.release) {
await ascRun("debug", argv)
.then(function() { return ascRun("release", argv) });
} else if (argv.options.release) {
await ascRun("release", argv);
} else {
await ascRun("debug", argv);
}
}
37 changes: 37 additions & 0 deletions cli/asbuild/asbuild.json
@@ -0,0 +1,37 @@
{
"help": {
"description": "Prints this message and exits.",
"type": "b",
"alias": "h"
},
"baseDir": {
"description": "Specifies the base directory of input and output files.",
"type": "s",
"default": "."
},
"outFile": {
"description": "Specifies an output file. File extension indicates format.",
"type": "s",
"alias": "o"
},
"binaryFile": {
"description": "Specifies the WebAssembly output file (.wasm).",
"type": "s",
"alias": "b"
},
"textFile": {
"description": "Specifies the text output file (.wat).",
"type": "s",
"alias": "t"
},
"idlFile": {
"description": "Specifies the interface definition output file (.idl).",
"type": "s",
"alias": "t"
},
"tsdFile": {
"description": "Specifies the TypeScript definition output file (.tsd).",
"type": "s",
"alias": "t"
}
}
17 changes: 17 additions & 0 deletions cli/asbuild/profiles.json
@@ -0,0 +1,17 @@
{
"debug": {
"default_name": "untouched",
"args": ["--validate", "--sourceMap", "--debug"],
"description": "builds a dbug wasm file: +debuginfo +assertions -optimizations ++size"
},
"release": {
"default_name": "optimized",
"args": ["--validate", "--sourceMap", "-O3", "--noAssert"],
"description": "builds an optimized wasm file: -debuginfo -assertions +optimizations +size"
},
"releasemin": {
"default_name": "optimizedmin",
"args": ["--validate", "--sourceMap", "-O3z", "--noAssert"],
"description": "builds a size-optimized wasm file: -debuginfo -assertions +optimizations -size"
}
}
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -44,7 +44,8 @@
"types": "index.d.ts",
"bin": {
"asc": "bin/asc",
"asinit": "bin/asinit"
"asinit": "bin/asinit",
"asbuild": "bin/asbuild"
},
"scripts": {
"build": "npm run build:bundle && npm run build:dts && npm run build:sdk",
Expand Down