aboutsummaryrefslogtreecommitdiff
path: root/lib/base-compiler.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/base-compiler.js')
-rw-r--r--lib/base-compiler.js119
1 files changed, 85 insertions, 34 deletions
diff --git a/lib/base-compiler.js b/lib/base-compiler.js
index 41e549b2e..7b19b4149 100644
--- a/lib/base-compiler.js
+++ b/lib/base-compiler.js
@@ -30,10 +30,12 @@ const temp = require('temp'),
AsmParser = require('./asm-parser'),
utils = require('./utils'),
_ = require('underscore'),
+ packager = require('./packager').Packager,
exec = require('./exec'),
logger = require('./logger').logger,
compilerOptInfo = require("compiler-opt-info"),
argumentParsers = require("./compilers/argument-parsers"),
+ CompilerArguments = require("./compiler-arguments"),
cfg = require('./cfg'),
languages = require('./languages').list;
@@ -66,8 +68,13 @@ class BaseCompiler {
this.asm = new AsmParser(this.compilerProps);
this.llvmIr = new LlvmIrParser(this.compilerProps);
+ this.possibleArguments = new CompilerArguments(this.compiler.id);
this.possibleTools = _.values(compilerInfo.tools);
this.possibleLibs = compilerInfo.libs;
+
+ this.outputFilebase = "output";
+
+ this.packager = new packager();
}
newTempDir() {
@@ -110,6 +117,10 @@ class BaseCompiler {
execOptions = this.getDefaultExecOptions();
}
+ if (!execOptions.customCwd) {
+ execOptions.customCwd = path.dirname(inputFilename);
+ }
+
return this.exec(compiler, options, execOptions).then(result => {
result.inputFilename = inputFilename;
result.stdout = utils.parseOutput(result.stdout, inputFilename);
@@ -137,9 +148,11 @@ class BaseCompiler {
}
execBinary(executable, maxSize, executeParameters) {
+ // We might want to save this in the compilation environment once execution is made available
+ const timeoutMs = this.env.ceProps('binaryExecTimeoutMs', 2000);
return exec.sandbox(executable, executeParameters, {
maxOutput: maxSize,
- timeoutMs: 2000
+ timeoutMs: timeoutMs
}) // TODO make config
.then(execResult => {
execResult.stdout = utils.parseOutput(execResult.stdout);
@@ -290,34 +303,68 @@ class BaseCompiler {
return this.runCompiler(compiler, options, inputFilename, execOptions);
}
- getOrBuildExecutable(key) {
- // todo: ask cache for executable if it already exists
+ buildExecutableInFolder(key, dirPath) {
+ const inputFilename = path.join(dirPath, this.compileFilename);
+ return this.writeFile(inputFilename, key.source).then(() => {
+ return {
+ inputFilename: inputFilename,
+ dirPath: dirPath
+ };
+ }).then((dirResult) => {
+ const outputFilename = this.getExecutableFilename(dirResult.dirPath, this.outputFilebase);
- return this.newTempDir()
- .then(dirPath => {
- const inputFilename = path.join(dirPath, this.compileFilename);
- return this.writeFile(inputFilename, key.source).then(() => ({
- inputFilename: inputFilename,
- dirPath: dirPath
- }));
- }).then((dirResult) => {
- const outputFilebase = "output";
- const outputFilename = this.getExecutableFilename(dirResult.dirPath, outputFilebase);
-
- let buildFilters = Object.assign({}, key.filters);
- buildFilters.binary = true;
- buildFilters.execute = true;
-
- const compilerArguments = _.compact(
- this.prepareArguments(key.options, buildFilters, key.backendOptions,
- dirResult.inputFilename, outputFilename)
- );
-
- return this.buildExecutable(key.compiler.exe, compilerArguments,
- dirResult.inputFilename, this.getDefaultExecOptions()).then(result => {
+ let buildFilters = Object.assign({}, key.filters);
+ buildFilters.binary = true;
+ buildFilters.execute = true;
+
+ const compilerArguments = _.compact(
+ this.prepareArguments(key.options, buildFilters, key.backendOptions,
+ dirResult.inputFilename, outputFilename)
+ );
+
+ return this.buildExecutable(key.compiler.exe, compilerArguments,
+ dirResult.inputFilename, this.getDefaultExecOptions())
+ .then(result => {
result.executableFilename = outputFilename;
return result;
});
+ });
+ }
+
+ getOrBuildExecutable(key) {
+ return this.newTempDir()
+ .then(dirPath => {
+ return this.env.executableGet(key, dirPath).then(outputFilename => {
+ logger.debug("Using cached package " + outputFilename);
+ return this.packager.unpack(outputFilename, dirPath).then(() => {
+ return {
+ code: 0,
+ inputFilename: path.join(dirPath, this.compileFilename),
+ dirPath: dirPath,
+ executableFilename: this.getExecutableFilename(dirPath, this.outputFilebase)
+ };
+ });
+ }).catch((err) => {
+ logger.debug("Tried to get executable from cache, but... " + err);
+
+ return this.buildExecutableInFolder(key, dirPath).then(result => {
+ if (result.code !== 0) {
+ return result;
+ } else {
+ return this.newTempDir().then(packDir => {
+ const packagedfile = path.join(packDir, "package.tgz");
+ return this.packager.package(result.executableFilename, packagedfile).then(() => {
+ return this.env.executablePut(key, packagedfile).then(() => {
+ fs.remove(packDir);
+ return result;
+ });
+ }).catch((e) => {
+ logger.error(e);
+ });
+ });
+ }
+ });
+ });
});
}
@@ -333,7 +380,7 @@ class BaseCompiler {
if (buildResult.code !== 0) {
return buildResult;
} else {
- return this.runExecutable(buildResult.executableFilename,
+ return this.runExecutable(buildResult.executableFilename,
executeParameters);
}
});
@@ -396,8 +443,7 @@ class BaseCompiler {
const inputFilename = info.inputFilename;
const inputFilenameSafe = this.filename(inputFilename);
const dirPath = info.dirPath;
- const outputFilebase = "output";
- const outputFilename = this.getOutputFilename(dirPath, outputFilebase);
+ const outputFilename = this.getOutputFilename(dirPath, this.outputFilebase);
options = _.compact(
this.prepareArguments(options, filters, backendOptions, inputFilename, outputFilename)
@@ -459,7 +505,7 @@ class BaseCompiler {
}
if (this.compiler.supportsOptOutput && this.optOutputRequested(options)) {
- const optPath = path.join(dirPath, `${outputFilebase}.opt.yaml`);
+ const optPath = path.join(dirPath, `${this.outputFilebase}.opt.yaml`);
if (fs.existsSync(optPath)) {
asmResult.hasOptOutput = true;
asmResult.optPath = optPath;
@@ -505,8 +551,7 @@ class BaseCompiler {
return result;
})
.then(result => {
- const outputFilebase = "output";
- const outputFilename = this.getOutputFilename(result.dirPath, outputFilebase);
+ const outputFilename = this.getOutputFilename(result.dirPath, this.outputFilebase);
const postToolsPromise = this.runToolsOfType(
result.inputFilename, tools, "postcompilation",
@@ -533,11 +578,17 @@ class BaseCompiler {
.then(result => filters.demangle ? this.postProcessAsm(result, filters) : result)
.then(result => {
if (this.compiler.supportsCfg && backendOptions && backendOptions.produceCfg) {
- result.cfg = cfg.generateStructure(this.compiler.version, result.asm);
+ result.cfg = cfg.generateStructure(this.compiler.compilerType,
+ this.compiler.version, result.asm);
}
return result;
})
.then(result => {
+ result.popularArguments = this.possibleArguments.getPopularArguments(options);
+
+ return result;
+ })
+ .then(result => {
if (result.okToCache) {
this.env.cachePut(key, result);
}
@@ -612,8 +663,8 @@ class BaseCompiler {
isCfgCompiler(compilerVersion) {
return compilerVersion.includes("clang") ||
- compilerVersion.indexOf("g++") === 0 ||
- compilerVersion.indexOf("gdc") === 0;
+ compilerVersion.match(/^([\w-]*-)?g((\+\+)|(cc)|(dc))/g) !== null;
+
}
processAstOutput(output) {