mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 07:04:04 -05:00
Ewavr (#1707)
* basic IAR EWAVR compiler support * basic line number parsing for colored lines * Better Line Number Parsing (line numbers are right aligned) * remove unused imports in compiler object * removed unused lines from asm-parser-ewavr.js since Travis complained about them * Assorted fixes from code review * update processAsm() method to work with new style after rebase * rework EWAVR asm parser. IAR seems to be closer to msvc. * filter section initialize labels as assembler directives * Add documentation for EWAVR
This commit is contained in:
@@ -85,3 +85,4 @@ From oldest to newest contributor, we would like to thank:
|
||||
- [Dave Rodgman](https://github.com/daverodgman)
|
||||
- [Will Lovett](https://github.com/willlovett-arm)
|
||||
- [Mark Gillard](https://github.com/marzer)
|
||||
- [Ethan Slattery](https://github.com/CrustyAuklet)
|
||||
|
||||
112
docs/EWAVR.md
Normal file
112
docs/EWAVR.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Running EWAVR compilers using linux docker images
|
||||
|
||||
Contact: [Ethan Slattery](https://github.com/CrustyAuklet)
|
||||
|
||||
## Prerequisites
|
||||
To run the IAR compiler for IAR on linux you will need the following things:
|
||||
- A valid copy of the IAR compiler
|
||||
- A license for the compiler
|
||||
- wine set up for win32 and i386
|
||||
|
||||
### Getting a copy of IAR
|
||||
Assuming you already have a valid copy of IAR installed on a windows machine, you can simply zip the installation directory. The installation is "portable" for all use cases needed by compiler explorer. The one thing that doesn't work so far is building a project file. Individual file compilation works well using `iccavr.exe`.
|
||||
|
||||
If you installed to the default location this means creating an archive of the directory `C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0`
|
||||
|
||||
### Compiler license
|
||||
The machine used for compiling needs to have access to a license, or compilation will fail. Ensure the server running compiler explorer can access the license server. If you want to use a dongle, then modify the following instructions accordingly, and good luck.
|
||||
|
||||
Note: Each time a compilation happens the machine doing that compilation claims the license for 20 minutes. Each docker instance counts as a different machine. Because of this it is a good idea to ensure that the machine running IAR is a long lived container/VM/machine to prevent using up all licenses and irritating your coworkers.
|
||||
|
||||
### Wine
|
||||
There are many places online to learn how to set up wine. A very simplified setup I often use in a fresh ubuntu docker container is:
|
||||
|
||||
```bash
|
||||
$ apt-get update
|
||||
$ dpkg --add-architecture i386
|
||||
$ apt-get -y update
|
||||
$ apt-get -y install wine-stable wine32 git curl bzip2 make
|
||||
$ WINEARCH=win32 winecfg
|
||||
```
|
||||
|
||||
## Setup and Configuration
|
||||
### Running locally on a windows workstation or a windows server
|
||||
Refer to the readme on runnining [Native on Windows](WindowsNative.md) for general setup of Compiler Explorer and other compilers.
|
||||
Then add EWAVR as an additional compiler in your `c++.local.properties` file. The example in the compiler explorer
|
||||
[documentation folder](EWAVR.properties) is written for linux so just modify the paths as needed.
|
||||
The following properties are the ones that need to be set in addition to the typical settings you do for any compiler.
|
||||
|
||||
- `versionRe=^IAR C\/C\+\+ Compiler.*AVR$`
|
||||
- `isSemVer=true`
|
||||
- `options=--eec++`
|
||||
- `supportsDemangler=false`
|
||||
|
||||
### Running on a linux server using docker
|
||||
#### Step 1: provide configuartion files, compilers, and librarys
|
||||
*If you are more experienced with docker this can be done with a volume, but I just use a local folder on my server*
|
||||
|
||||
Create a folder on the server `/opt/compiler_explorer`. We are focusing on ewavr but you can see we also include
|
||||
several other embedded compilers, the native compilers, and many open source and internal libraries. the EWAVR specific portions
|
||||
of `c++.local.properties` is provided in the [example](EWAVR.properties), the rest is generic library and compiler settings.
|
||||
`compiler-explorer.local.properties` contains server specific sub-domain settings.
|
||||
|
||||
The EWAVR directories are just the archives of the install folders from windows un-tarred there, as you can see from the layout.
|
||||
|
||||
```bash
|
||||
/opt/compiler_explorer/
|
||||
├── c++.local.properties
|
||||
├── compiler-explorer.local.properties
|
||||
├── compilers
|
||||
│ ├── avr-gcc-5.4.0-atmel
|
||||
│ ├── avr-gcc-9.2.0-P0829
|
||||
│ ├── bin -> /usr/bin
|
||||
│ ├── ewavr_7108
|
||||
│ │ ├── avr
|
||||
│ │ ├── common
|
||||
│ │ └── install-info
|
||||
│ ├── ewavr_7205
|
||||
│ │ ├── avr
|
||||
│ │ ├── common
|
||||
│ │ └── install-info
|
||||
│ ├── gcc-arm-none-eabi-6.3.1-atmel
|
||||
│ ├── gcc-arm-none-eabi-8-2018-q4-major
|
||||
│ └── gcc-arm-none-eabi-9-2019-q4-major
|
||||
└── libs
|
||||
├── bitpacker
|
||||
├── boost_1_72_0
|
||||
├── cunpack
|
||||
├── dyno
|
||||
├── expected
|
||||
├── function_ref
|
||||
├── gsl
|
||||
├── span
|
||||
├── static_string
|
||||
├── static_vector
|
||||
├── tl-optional
|
||||
└── xmega-hal
|
||||
```
|
||||
|
||||
#### Step 2: Make iccavr callable
|
||||
To invoke `iccavr` you need to use the command `wine /opt/compiler_explorer/compilers/ewavr_7108/avr/bin/iccavr.exe` which created some issues for me in CE.
|
||||
I create small bash script aliases using the following commands, for each versions `bin` folder:
|
||||
|
||||
```bash
|
||||
$ IAR_ROOT=/opt/compiler_explorer/compilers/ewavr_7108
|
||||
$ echo -e "#\!/bin/bash\nwine $IAR_ROOT/avr/bin/iccavr.exe\n" > $IAR_ROOT/avr/bin/iccavr && chmod +x $IAR_ROOT/avr/bin/iccavr
|
||||
$ IAR_ROOT=/opt/compiler_explorer/compilers/ewavr_7205
|
||||
$ echo -e "#\!/bin/bash\nwine $IAR_ROOT/avr/bin/iccavr.exe\n" > $IAR_ROOT/avr/bin/iccavr && chmod +x $IAR_ROOT/avr/bin/iccavr
|
||||
```
|
||||
|
||||
#### Step 3: Start Compiler Explorer as a docker image
|
||||
A [docker image](https://hub.docker.com/repository/docker/crustyauklet/compiler_explorer) is available that bundles a working version of Compiler Explorer
|
||||
and wine so that no additional setup is needed on the host server. The IAR liscense needs to be run once, at system startup to register with the liscense server,
|
||||
so that can be seen in the the docker command. If you have multiple IAR versions, only one needs to be run and it doesn't matter which one.
|
||||
|
||||
```bash
|
||||
$ IAR_SERVER=my.liscense_server.ip.address
|
||||
$ docker run --restart=always -d --name compiler_explorer \
|
||||
-v /opt/compiler_explorer:/opt/compiler_explorer \
|
||||
-v /opt/compiler_explorer/c++.local.properties:/compiler-explorer/etc/config/c++.local.properties \
|
||||
-p 80:10240 crustyauklet/compiler_explorer \
|
||||
/bin/bash -c "wine /opt/compiler_explorer/compilers/ewavr_7108/common/bin/LightLicenseManager.exe setup -s ${IAR_SERVER} && make"
|
||||
```
|
||||
46
docs/EWAVR.properties
Normal file
46
docs/EWAVR.properties
Normal file
@@ -0,0 +1,46 @@
|
||||
defaultCompiler=ewavr720
|
||||
compilers=&avr
|
||||
|
||||
#######################################################
|
||||
# AVR CROSS COMPILERS
|
||||
#######################################################
|
||||
group.avr.compilers=&avrg:&ewavr
|
||||
group.avr.groupName=Atmel AVR
|
||||
group.avr.supportsBinary=false
|
||||
group.avr.supportsExecute=false
|
||||
|
||||
################################
|
||||
# GCC for AVR
|
||||
group.avrg.compilers=avrg920:avrg542
|
||||
group.avrg.groupName=AVR GCC
|
||||
group.avrg.baseName=AVR gcc
|
||||
group.avrg.isSemVer=true
|
||||
group.avrg.supportsBinary=false
|
||||
|
||||
compiler.avrg920.exe=/opt/compiler_explorer/compilers/avr-gcc-9.2.0-P0829/bin/avr-g++
|
||||
compiler.avrg920.objdumper=/opt/compiler_explorer/compilers/avr-gcc-9.2.0-P0829/bin/avr-objdump
|
||||
compiler.avrg920.name=AVR-GCC 9.2.0 (P0829)
|
||||
compiler.avrg920.semver=9.2.0
|
||||
|
||||
compiler.avrg542.exe=/opt/compiler_explorer/compilers/avr-gcc-5.4.0-atmel/bin/avr-g++
|
||||
compiler.avrg542.objdumper=/opt/compiler_explorer/compilers/avr-gcc-5.4.0-atmel/bin/avr-objdump
|
||||
compiler.avrg542.name=AVR-GCC 5.4.2
|
||||
compiler.avrg542.semver=5.4.2
|
||||
|
||||
#################################
|
||||
# EWAVR - IAR for AVR
|
||||
group.ewavr.compilers=ewavr720:ewavr710
|
||||
group.ewavr.groupName=IAR compiler for AVR
|
||||
group.ewavr.compilerType=ewavr
|
||||
group.ewavr.versionRe=^IAR C\/C\+\+ Compiler.*AVR$
|
||||
group.ewavr.isSemVer=true
|
||||
group.ewavr.options=--eec++
|
||||
group.ewavr.supportsDemangler=false
|
||||
|
||||
compiler.ewavr720.exe=/opt/compiler_explorer/compilers/ewavr_7205/avr/bin/iccavr
|
||||
compiler.ewavr720.name=EWAVR 7.20
|
||||
compiler.ewavr720.semver=7.20
|
||||
|
||||
compiler.ewavr710.exe=/opt/compiler_explorer/compilers/ewavr_7108/avr/bin/iccavr
|
||||
compiler.ewavr710.name=EWAVR 7.10
|
||||
compiler.ewavr710.semver=7.10
|
||||
310
lib/asm-parser-ewavr.js
Normal file
310
lib/asm-parser-ewavr.js
Normal file
@@ -0,0 +1,310 @@
|
||||
// Copyright (c) 2019, Ethan Slattery
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
const AsmParserBase = require('./asm-parser'),
|
||||
logger = require('./logger').logger,
|
||||
utils = require('./utils'),
|
||||
AsmRegex = require('./asmregex').AsmRegex;
|
||||
|
||||
class AsmEWAVRParser extends AsmParserBase {
|
||||
constructor(compilerProps) {
|
||||
super(compilerProps);
|
||||
this.commentOnly = /^\s*(((#|@|\$|\/\/).*)|(\/\*.*\*\/))$/;
|
||||
this.filenameComment = /^\/\/\s[a-zA-Z]?:?(\\\\?([^\\/]*[\\/])*)([^\\/]+)$/;
|
||||
this.lineNumberComment = /^\/\/\s*([0-9]+)\s(?!bytes).*/;
|
||||
|
||||
// categories of directives. remove if filters.directives set
|
||||
this.segmentBegin = /^\s*(ASEG|ASEGN|COMMON|RSEG|STACK)\s*([a-zA-Z_][a-zA-Z0-9_:()]*)/;
|
||||
this.segmentControl = /^\s*(ALIGN|EVEN|ODD|ORG)/;
|
||||
this.definesGlobal = /^\s*(EXTERN|EXTRN|IMPORT|EXPORT|PUBWEAK|PUBLIC)\s+(.+)$/;
|
||||
this.definesLocal = /^\s*((ASSIGN|DEFINE|LOCAL|ALIAS|EQU|VAR)|(([a-zA-Z_][a-zA-Z0-9_]*)=.+))$/;
|
||||
this.miscDirective = /^\s*(NAME|MODULE|PROGRAM|LIBRARY|ERROR|END|CASEOFF|CASEON|CFI|COL|RADIX)/;
|
||||
|
||||
// NOTE: Compiler generated labels can have spaces in them, but are quoted and in <>
|
||||
this.labelDef = /^`?[?]*<?([a-zA-Z_][ :a-zA-Z0-9_]*)>?`?:$/;
|
||||
this.dataStatement = /^\s*(DB|DC16|DC24|DC32|DC8|DD|DP|DS|DS16|DS24|DS32|DW)/;
|
||||
this.requireStatement = /^\s*REQUIRE\s+`?[?]*<?([a-zA-Z_][ a-zA-Z0-9_]*)>?`?/;
|
||||
this.beginFunctionMaybe = /^\s*RSEG\s*CODE:CODE:(.+)$/;
|
||||
}
|
||||
|
||||
hasOpcode(line) {
|
||||
// check for empty lines
|
||||
if (line.length === 0) return false;
|
||||
// check for a local label definition
|
||||
if (line.match(this.definesLocal)) return false;
|
||||
// check for global label definitions
|
||||
if (line.match(this.definesGlobal)) return false;
|
||||
// check for data definitions
|
||||
if (line.match(this.dataStatement)) return false;
|
||||
// check for segment begin and end
|
||||
if (line.match(this.segmentBegin) || line.match(this.segmentControl)) return false;
|
||||
// check for label definition
|
||||
if (line.match(this.labelDef)) return false;
|
||||
// check for miscellaneous directives
|
||||
if (line.match(this.miscDirective)) return false;
|
||||
// check for requre statement
|
||||
if (line.match(this.requireStatement)) return false;
|
||||
|
||||
return !!line.match(this.hasOpcodeRe);
|
||||
}
|
||||
|
||||
labelFindFor() {
|
||||
return this.labelDef;
|
||||
}
|
||||
|
||||
processAsm(asm, filters) {
|
||||
// NOTE: EWAVR assembly seems to be closest to visual studio
|
||||
const getFilenameFromComment = line => {
|
||||
const matches = line.match(this.filenameComment);
|
||||
if (!matches) {
|
||||
return null;
|
||||
} else {
|
||||
return matches[3];
|
||||
}
|
||||
};
|
||||
|
||||
const getLineNumberFromComment = line => {
|
||||
const matches = line.match(this.lineNumberComment);
|
||||
if (!matches) {
|
||||
return null;
|
||||
} else {
|
||||
return parseInt(matches[1]);
|
||||
}
|
||||
};
|
||||
|
||||
let asmLines = utils.splitLines(asm);
|
||||
|
||||
const stdInLooking = /<stdin>|^-$|example\.[^/]+$|<source>/;
|
||||
|
||||
// type source = {file: string option; line: int}
|
||||
// type line = {line: string; source: source option}
|
||||
// type label =
|
||||
// { lines: line array
|
||||
// ; name: string | undefined
|
||||
// ; initialLine: int
|
||||
// ; file: string option
|
||||
// ; require: string array }
|
||||
let resultObject = {
|
||||
prefix: [], // line array
|
||||
labels: [], // label array
|
||||
postfix: [] // line array
|
||||
};
|
||||
|
||||
let currentLabel = null; // func option
|
||||
let currentFile = undefined;
|
||||
let currentLine = undefined;
|
||||
|
||||
let seenEnd = false;
|
||||
|
||||
const definedLabels = {};
|
||||
|
||||
const createSourceFor = (line, currentFile, currentLine) => {
|
||||
const hasopc = this.hasOpcode(line);
|
||||
const createsData = line.match(this.dataStatement);
|
||||
if ((hasopc || createsData) && (currentFile || currentLine)) {
|
||||
return {
|
||||
file: (currentFile ? currentFile : null),
|
||||
line: (currentLine ? currentLine : null)
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const checkBeginLabel = (line) => {
|
||||
const matches = line.match(this.labelDef);
|
||||
if (matches) {
|
||||
currentLabel = {
|
||||
lines: [],
|
||||
initialLine: currentLine,
|
||||
name: matches[1],
|
||||
file: currentFile
|
||||
};
|
||||
definedLabels[matches[1]] = currentLine;
|
||||
resultObject.labels.push(currentLabel);
|
||||
}
|
||||
};
|
||||
|
||||
const checkRequiresStatement = (line) => {
|
||||
const matches = line.match(this.requireStatement);
|
||||
if (matches && currentLabel != null) {
|
||||
if (currentLabel.require != null) {
|
||||
currentLabel.require.push(matches[1]);
|
||||
} else {
|
||||
currentLabel.require = [ matches[1] ];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
asmLines.forEach(line => {
|
||||
if (line.trim() === "END") {
|
||||
seenEnd = true;
|
||||
if (!filters.directives) {
|
||||
resultObject.postfix.push({text: line, source: null});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (line.trim() === "") {
|
||||
const emptyLine = {text: "", source: null};
|
||||
if (seenEnd) {
|
||||
resultObject.postfix.push(emptyLine);
|
||||
}
|
||||
else if (currentLabel === null) {
|
||||
resultObject.prefix.push(emptyLine);
|
||||
}
|
||||
else {
|
||||
currentLabel.lines.push(emptyLine);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (seenEnd && !line.match(this.commentOnly)) {
|
||||
// There should be nothing but comments after END directive
|
||||
throw Error("EWAVR: non-comment line after the end statement");
|
||||
}
|
||||
|
||||
let tmp = getFilenameFromComment(line);
|
||||
if (tmp !== null) {
|
||||
// if the file is the "main file", give it the file `null`
|
||||
if (tmp.match(stdInLooking)) {
|
||||
currentFile = null;
|
||||
} else {
|
||||
currentFile = tmp;
|
||||
}
|
||||
if (currentLabel != null && currentLabel.file === undefined) {
|
||||
currentLabel.file = currentFile;
|
||||
}
|
||||
} else {
|
||||
tmp = getLineNumberFromComment(line);
|
||||
if (tmp !== null) {
|
||||
if (currentFile === undefined) {
|
||||
logger.error("Somehow, we have a line number comment without a file comment: %s",
|
||||
line);
|
||||
}
|
||||
if (currentLabel != null && currentLabel.initialLine === undefined) {
|
||||
currentLabel.initialLine = tmp;
|
||||
}
|
||||
currentLine = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
checkBeginLabel(line);
|
||||
checkRequiresStatement(line);
|
||||
|
||||
if (filters.commentOnly && line.match(this.commentOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldSkip = filters.directives && (
|
||||
line.match(this.segmentBegin) ||
|
||||
line.match(this.segmentControl) ||
|
||||
line.match(this.definesGlobal) ||
|
||||
line.match(this.definesLocal) ||
|
||||
line.match(this.miscDirective) ||
|
||||
line.match(this.requireStatement)
|
||||
);
|
||||
|
||||
if (shouldSkip) {
|
||||
return;
|
||||
}
|
||||
|
||||
line = utils.expandTabs(line);
|
||||
const textAndSource = {
|
||||
text: AsmRegex.filterAsmLine(line, filters),
|
||||
source: createSourceFor(line, currentFile, currentLine)
|
||||
};
|
||||
if (currentLabel === null) {
|
||||
resultObject.prefix.push(textAndSource);
|
||||
} else if (!shouldSkip) {
|
||||
currentLabel.lines.push(textAndSource);
|
||||
}
|
||||
});
|
||||
|
||||
return this.resultObjectIntoArray(resultObject, filters, definedLabels);
|
||||
}
|
||||
|
||||
resultObjectIntoArray(obj, filters, ddefLabels) {
|
||||
// NOTES on EWAVR function and labels:
|
||||
// - template functions are not mangled with type info.
|
||||
// Instead they simply have a `_#` appended to the end, with #
|
||||
// incrementing for each instantiation.
|
||||
// - labels for variables, functions, and code fragments are all the same.
|
||||
// - One exception.. functions SEEM to always have a segment command
|
||||
// with a few lines before the label. is this reliable?
|
||||
|
||||
// NOTES: compiler generated labels
|
||||
// 'Initializer for' is used to init variables. usually at end of file
|
||||
// 'Segment init:' is used to init sections. One per many 'Initializer for' labels.
|
||||
const compilerGeneratedLabel = /^(Initializer for |Segment init: )([ :a-zA-Z0-9_]*)$/i;
|
||||
const segInitLabel = /^Segment init: ([ :a-zA-Z0-9_]*)$/i;
|
||||
|
||||
let result = [];
|
||||
let lastLineWasWhitespace = true;
|
||||
let pushLine = line => {
|
||||
if (line.text.trim() === '') {
|
||||
if (!lastLineWasWhitespace) {
|
||||
result.push({text: "", source: null});
|
||||
lastLineWasWhitespace = true;
|
||||
}
|
||||
} else {
|
||||
result.push(line);
|
||||
lastLineWasWhitespace = false;
|
||||
}
|
||||
};
|
||||
|
||||
for (const line of obj.prefix) {
|
||||
pushLine(line);
|
||||
}
|
||||
|
||||
for (const label of obj.labels) {
|
||||
if (!filters.libraryCode || label.file === null) {
|
||||
const match = label.name.match(compilerGeneratedLabel);
|
||||
const segInitMatch = label.name.match(segInitLabel);
|
||||
pushLine({text: "", source: null});
|
||||
for (const line of label.lines) {
|
||||
// Match variable inits to the source line of declaration.
|
||||
// No source line for global section initilization
|
||||
if(match && line.source != null) {
|
||||
line.source.line = ddefLabels[match[2]];
|
||||
}
|
||||
// Filter section inits as directives
|
||||
if(segInitMatch && filters.directives) {
|
||||
continue;
|
||||
}
|
||||
pushLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const line of obj.postfix) {
|
||||
pushLine(line);
|
||||
}
|
||||
|
||||
return {
|
||||
asm: result
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AsmEWAVRParser;
|
||||
62
lib/compilers/ewavr.js
Normal file
62
lib/compilers/ewavr.js
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2019, Ethan Slattery
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"use strict";
|
||||
|
||||
const BaseCompiler = require('../base-compiler'),
|
||||
temp = require('temp'),
|
||||
AsmEWAVRParser = require('../asm-parser-ewavr.js');
|
||||
|
||||
class EWAVRCompiler extends BaseCompiler {
|
||||
constructor(info, env) {
|
||||
info.supportsDemangle = false;
|
||||
info.supportsLibraryCodeFilter = false;
|
||||
super(info, env);
|
||||
this.asm = new AsmEWAVRParser(this.compilerProps);
|
||||
}
|
||||
|
||||
newTempDir() {
|
||||
return new Promise((resolve, reject) => {
|
||||
temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.TMP}, (err, dirPath) => {
|
||||
if (err)
|
||||
reject(`Unable to open temp file: ${err}`);
|
||||
else
|
||||
resolve(dirPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
if (filters.binary) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'-lB', this.filename(outputFilename),
|
||||
'-o', this.filename(outputFilename + '.obj')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EWAVRCompiler;
|
||||
Reference in New Issue
Block a user