mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 10:33:59 -05:00
The Grand Reformat (#3643)
* The Grand Reformat - everything made prettier...literally - some tweaks to include a few more files, including documentation - minor changes to format style - some tiny `// prettier-ignore` changes to keep a few things the way we like them - a couple of super minor tweaks to embedded document types to ensure they format correctly
This commit is contained in:
@@ -5,28 +5,28 @@ rules:
|
||||
header/header:
|
||||
- off
|
||||
- line
|
||||
- - pattern: "^ Copyright \\(c\\) \\d{4}, .*$"
|
||||
template: " Copyright (c) 2021, Compiler Explorer Authors"
|
||||
- " 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."
|
||||
- - pattern: '^ Copyright \\(c\\) \\d{4}, .*$'
|
||||
template: ' Copyright (c) 2021, Compiler Explorer Authors'
|
||||
- ' 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.'
|
||||
- 2
|
||||
|
||||
@@ -164,5 +164,5 @@ settings:
|
||||
node:
|
||||
tryExtensions: [.js, .ts]
|
||||
import/parsers:
|
||||
"@typescript-eslint/parser": [ .ts, .tsx ]
|
||||
import/resolver: "typescript"
|
||||
'@typescript-eslint/parser': [.ts, .tsx]
|
||||
import/resolver: 'typescript'
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
9
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us improve
|
||||
title: "[BUG]: "
|
||||
labels: ["bug"]
|
||||
title: '[BUG]: '
|
||||
labels: ['bug']
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
@@ -50,12 +50,13 @@ body:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "# System information"
|
||||
value: '# System information'
|
||||
- type: input
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: If applicable (i.e, an issue with how the site behaves for you) the OS version this bug is happening in
|
||||
description:
|
||||
If applicable (i.e, an issue with how the site behaves for you) the OS version this bug is happening in
|
||||
placeholder: Ubuntu Linux 20.04
|
||||
validations:
|
||||
required: false
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/compiler_request.yml
vendored
4
.github/ISSUE_TEMPLATE/compiler_request.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Compiler request
|
||||
description: Request a new compiler
|
||||
title: "[COMPILER REQUEST]: "
|
||||
labels: ["request", "new-compilers"]
|
||||
title: '[COMPILER REQUEST]: '
|
||||
labels: ['request', 'new-compilers']
|
||||
body:
|
||||
- type: input
|
||||
id: compiler-name
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
8
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Feature request
|
||||
description: Suggest an idea for the project
|
||||
title: "[REQUEST]: "
|
||||
labels: ["request"]
|
||||
title: '[REQUEST]: '
|
||||
labels: ['request']
|
||||
body:
|
||||
- type: textarea
|
||||
id: introduction
|
||||
@@ -23,7 +23,9 @@ body:
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: If applicable, please add a clear and concise description of any alternative solutions or features you've considered.
|
||||
description:
|
||||
If applicable, please add a clear and concise description of any alternative solutions or features you've
|
||||
considered.
|
||||
placeholder: You can pass -E to the compiler flags, but I'd like to easily side-by-side compare
|
||||
validations:
|
||||
required: true
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/library_request.yml
vendored
8
.github/ISSUE_TEMPLATE/library_request.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Library request
|
||||
description: Request a new library
|
||||
title: "[LIB REQUEST]: "
|
||||
labels: ["request", "new-libs"]
|
||||
title: '[LIB REQUEST]: '
|
||||
labels: ['request', 'new-libs']
|
||||
body:
|
||||
- type: input
|
||||
id: library-name
|
||||
@@ -15,7 +15,9 @@ body:
|
||||
id: library-description
|
||||
attributes:
|
||||
label: Library description
|
||||
description: A sentence that describes what this library does. It helps us when filling some of the UI elements when adding the library
|
||||
description:
|
||||
A sentence that describes what this library does. It helps us when filling some of the UI elements when adding
|
||||
the library
|
||||
placeholder: GoogleTest is a testing library for C++
|
||||
validations:
|
||||
required: true
|
||||
|
||||
2
.github/workflows/browserslist.yml
vendored
2
.github/workflows/browserslist.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
title: "[bot] Update browsers list"
|
||||
title: '[bot] Update browsers list'
|
||||
body: |
|
||||
Automatic run of `npm run-update-browerslist` which needs to
|
||||
be done periodically to keep in-date.
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -9,7 +9,7 @@
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/label.yml
vendored
2
.github/workflows/label.yml
vendored
@@ -13,4 +13,4 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/labeler@v3
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
repo-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
|
||||
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
@@ -62,5 +62,8 @@
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="yaml">
|
||||
<option name="SPACE_WITHIN_BRACKETS" value="false" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@@ -33,11 +33,9 @@ newrelic_agent.log
|
||||
# From .eslintignore
|
||||
|
||||
# Uninteresting folders (node_modules and dotfiles/dotfolders ignored by default)
|
||||
docs
|
||||
etc
|
||||
examples
|
||||
out
|
||||
views
|
||||
|
||||
# Autogenerated files
|
||||
lib/asm-docs/generated/asm-docs-*.js
|
||||
|
||||
@@ -5,9 +5,10 @@ module.exports = {
|
||||
arrowParens: 'avoid',
|
||||
tabWidth: 4,
|
||||
bracketSpacing: false,
|
||||
proseWrap: 'always',
|
||||
overrides: [
|
||||
{
|
||||
files: '*.{yml,json}',
|
||||
files: '*.{yml,json,md}',
|
||||
options: {
|
||||
tabWidth: 2,
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Currently, the people referred to when the documentation or policies mention
|
||||
the administration team of Compiler Explorer are:
|
||||
Currently, the people referred to when the documentation or policies mention the administration team of Compiler
|
||||
Explorer are:
|
||||
|
||||
- [Matt Godbolt](https://xania.org)
|
||||
- [Rubén Rincón](https://rinconblanco.es)
|
||||
- [Patrick Quist](https://github.com/partouf)
|
||||
@@ -8,6 +9,7 @@ Currently, the people referred to when the documentation or policies mention
|
||||
---
|
||||
|
||||
Additionally, these people have been immensely helpful in the development of Compiler Explorer:
|
||||
|
||||
- [Jared Wyles](https://github.com/jaredwy)
|
||||
- [Chedy Najjar](https://github.com/CppChedy)
|
||||
- [Simon Brand](https://blog.tartanllama.xyz/)
|
||||
|
||||
@@ -4,73 +4,60 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project
|
||||
and our community a harassment-free experience for everyone, regardless of age,
|
||||
body size, disability, ethnicity, gender identity, and expression,
|
||||
level of experience, nationality, personal appearance, race, religion,
|
||||
or sexual identity and orientation.
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make
|
||||
participation in our project and our community a harassment-free experience for everyone, regardless of age, body size,
|
||||
disability, ethnicity, gender identity, and expression, level of experience, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language.
|
||||
* Being respectful of differing viewpoints and experiences.
|
||||
* Gracefully accepting constructive criticism.
|
||||
* Focusing on what is best for the community.
|
||||
* Showing empathy towards other community members.
|
||||
- Using welcoming and inclusive language.
|
||||
- Being respectful of differing viewpoints and experiences.
|
||||
- Gracefully accepting constructive criticism.
|
||||
- Focusing on what is best for the community.
|
||||
- Showing empathy towards other community members.
|
||||
|
||||
Examples of **unacceptable** behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances.
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks.
|
||||
* Public or private harassment.
|
||||
* Publishing others' private information, such as a physical or electronic address,
|
||||
without explicit permission.
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting.
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or advances.
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks.
|
||||
- Public or private harassment.
|
||||
- Publishing others' private information, such as a physical or electronic address, without explicit permission.
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting.
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take
|
||||
appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban
|
||||
temporarily or permanently any contributor for other behaviors that they deem
|
||||
inappropriate, threatening, offensive, or harmful.
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits,
|
||||
issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any
|
||||
contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as
|
||||
an appointed representative at an online or offline event.
|
||||
Representation of a project may be further defined and clarified by the project
|
||||
maintainers.
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the
|
||||
project or its community. Examples of representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed representative at an online or offline
|
||||
event. Representation of a project may be further defined and clarified by the project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project owner at
|
||||
[matt@godbolt.org](mailto:matt@godbolt.org). The project team will review
|
||||
and investigate all complaints, and will respond in a way that it deems
|
||||
appropriate to the circumstances. The project team is obligated to maintain
|
||||
confidentiality concerning the reporter of an incident. Further details of
|
||||
specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project owner at
|
||||
[matt@godbolt.org](mailto:matt@godbolt.org). The project team will review and investigate all complaints, and will
|
||||
respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain
|
||||
confidentiality concerning the reporter of an incident. Further details of specific enforcement policies may be posted
|
||||
separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent
|
||||
repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 1.4, available at [contributor-covenant.org/version/1/4][version]
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at
|
||||
[contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org/
|
||||
[version]: https://www.contributor-covenant.org/version/1/4/
|
||||
|
||||
120
CONTRIBUTING.md
120
CONTRIBUTING.md
@@ -1,94 +1,78 @@
|
||||
# Contributing to Compiler Explorer
|
||||
|
||||
First off, if you're reading this: thank you! Even considering contributing to
|
||||
**Compiler Explorer** is very much appreciated!
|
||||
Before we go too far, an apology: **Compiler Explorer** grew out of a bit of
|
||||
hacky JavaScript into a pretty large and well-used project pretty quickly.
|
||||
Not all the code was originally well-written or well-tested.
|
||||
Please be forgiving of that.
|
||||
First off, if you're reading this: thank you! Even considering contributing to **Compiler Explorer** is very much
|
||||
appreciated! Before we go too far, an apology: **Compiler Explorer** grew out of a bit of hacky JavaScript into a pretty
|
||||
large and well-used project pretty quickly. Not all the code was originally well-written or well-tested. Please be
|
||||
forgiving of that.
|
||||
|
||||
**Compiler Explorer** follows a [Code of Conduct](CODE_OF_CONDUCT.md) which
|
||||
aims to foster an open and welcoming environment.
|
||||
**Compiler Explorer** follows a [Code of Conduct](CODE_OF_CONDUCT.md) which aims to foster an open and welcoming
|
||||
environment.
|
||||
|
||||
# Where to start
|
||||
|
||||
We have labeled issues which should be easy to do that you can find [here](https://github.com/compiler-explorer/compiler-explorer/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
We have labeled issues which should be easy to do that you can find
|
||||
[here](https://github.com/compiler-explorer/compiler-explorer/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
|
||||
If you have any questions, don't hesitate: [Contact us].
|
||||
|
||||
If there is something you would like to do yourself, it might help to make an issue so people can weigh in and point you in the right direction.
|
||||
|
||||
If there is something you would like to do yourself, it might help to make an issue so people can weigh in and point you
|
||||
in the right direction.
|
||||
|
||||
## Node version
|
||||
**Compiler Explorer** currently targets [Node.js](https://nodejs.org/) LTS version 16
|
||||
so it's better if you do so as well when testing your changes locally.
|
||||
|
||||
**Compiler Explorer** currently targets [Node.js](https://nodejs.org/) LTS version 16 so it's better if you do so as
|
||||
well when testing your changes locally.
|
||||
|
||||
## In brief
|
||||
* Make your changes, trying to stick to the style and format where possible.
|
||||
* We use [ESLint](https://eslint.org/) to ensure a consistent code base
|
||||
and PRs won't pass unless it detects no errors.
|
||||
* Running `make lint` will run the linter, which will auto-fix everything
|
||||
it can and report back any errors and warnings.
|
||||
* If you're adding a new server-side component, please do your best to add a test to
|
||||
cover it. For client-side changes that's trickier.
|
||||
* Tests should run automatically as a pre-commit step.
|
||||
_You can disable this check with `git commit --no-verify` if needed_.
|
||||
* You can run `make check` to run both the linter and the code tests
|
||||
* Do a smoke test:
|
||||
Run `make` and ensure the site works as you'd expect. Concentrate on the
|
||||
areas you'd expect to have changed, but if you can, click about generally to
|
||||
help check you haven't unintentionally broken something else
|
||||
* Submit a Pull Request.
|
||||
|
||||
- Make your changes, trying to stick to the style and format where possible.
|
||||
- We use [ESLint](https://eslint.org/) to ensure a consistent code base and PRs won't pass unless it detects no
|
||||
errors.
|
||||
- Running `make lint` will run the linter, which will auto-fix everything it can and report back any errors and
|
||||
warnings.
|
||||
- If you're adding a new server-side component, please do your best to add a test to cover it. For client-side changes
|
||||
that's trickier.
|
||||
- Tests should run automatically as a pre-commit step. _You can disable this check with `git commit --no-verify` if
|
||||
needed_.
|
||||
- You can run `make check` to run both the linter and the code tests
|
||||
- Do a smoke test: Run `make` and ensure the site works as you'd expect. Concentrate on the areas you'd expect to have
|
||||
changed, but if you can, click about generally to help check you haven't unintentionally broken something else
|
||||
- Submit a Pull Request.
|
||||
|
||||
## Basic code layout
|
||||
|
||||
Code is separated into server-side code and client-side code.
|
||||
All dependencies (server and client side) are installed via `package.json`.
|
||||
_Server code_ is in `app.js` and in the `lib` directory.
|
||||
_Client code_ is all in the `static` directory.
|
||||
Code is separated into server-side code and client-side code. All dependencies (server and client side) are installed
|
||||
via `package.json`. _Server code_ is in `app.js` and in the `lib` directory. _Client code_ is all in the `static`
|
||||
directory.
|
||||
|
||||
In the server code, the `app.js` sets up a basic `express`
|
||||
middleware-driven web server, delegating to the various compiler backends in
|
||||
`lib/compilers/`. All of them inherit from `lib/base-compiler.js` which does
|
||||
most of the work of running compilers, then parsing the output and forming a
|
||||
JSON object to send to the client. Any assembly parsing is done in the
|
||||
`lib/asm-parser.js`, and similar, files.
|
||||
In the server code, the `app.js` sets up a basic `express` middleware-driven web server, delegating to the various
|
||||
compiler backends in `lib/compilers/`. All of them inherit from `lib/base-compiler.js` which does most of the work of
|
||||
running compilers, then parsing the output and forming a JSON object to send to the client. Any assembly parsing is done
|
||||
in the `lib/asm-parser.js`, and similar, files.
|
||||
|
||||
In the client code, [GoldenLayout](https://www.golden-layout.com/) is used as
|
||||
the container. If you look at some components like the
|
||||
`static/compiler.js`, you'll see the general flow.
|
||||
Any state stored makes it into the URL, so be careful not to stash
|
||||
anything too big in there.
|
||||
In the client code, [GoldenLayout](https://www.golden-layout.com/) is used as the container. If you look at some
|
||||
components like the `static/compiler.js`, you'll see the general flow. Any state stored makes it into the URL, so be
|
||||
careful not to stash anything too big in there.
|
||||
|
||||
The client code follows GoldenLayout's message-based system:
|
||||
no component has a reference to any other and everything is done via messages.
|
||||
This will allow us to use pop-out windows, if we ever need to, as the messages
|
||||
are JSON-serializable between separate windows.
|
||||
The client code follows GoldenLayout's message-based system: no component has a reference to any other and everything is
|
||||
done via messages. This will allow us to use pop-out windows, if we ever need to, as the messages are JSON-serializable
|
||||
between separate windows.
|
||||
|
||||
## Editing flow
|
||||
|
||||
The recommended way to work on **Compiler Explorer** is to just run `make dev`
|
||||
and let the automatic reloading do its magic.
|
||||
Any changes to the server code will cause the server to reload, and any changes
|
||||
to the client code will be reflected upon a page reload.
|
||||
This makes for a pretty quick turnaround.
|
||||
Note that a current issue makes every project media asset to be locally
|
||||
unavailable. We will hopefully fix this in the near future.
|
||||
The recommended way to work on **Compiler Explorer** is to just run `make dev` and let the automatic reloading do its
|
||||
magic. Any changes to the server code will cause the server to reload, and any changes to the client code will be
|
||||
reflected upon a page reload. This makes for a pretty quick turnaround. Note that a current issue makes every project
|
||||
media asset to be locally unavailable. We will hopefully fix this in the near future.
|
||||
|
||||
## Gotchas
|
||||
|
||||
* New client-side code should preferably be written in TypeScript,
|
||||
but we will always accept js code too. Be aware that in that case,
|
||||
you must stick to **ES5** (so no `let` or arrow operators) js code.
|
||||
Sadly there are still enough users out there on old browsers.
|
||||
Note that this restriction does not apply to the server side code,
|
||||
in which you can use all the cool features you want.
|
||||
In lieu of ES6 features, [Underscore.js](https://underscorejs.org/) is available
|
||||
as a way to bridge the feature gap. The library is available both
|
||||
in the client and server code.
|
||||
* Be aware that **Compiler Explorer** runs on a cluster on the live site.
|
||||
No local state is kept between invocations, and the user's next request will
|
||||
likely hit a different node in the cluster, so don't rely on
|
||||
any in-memory state.
|
||||
- New client-side code should preferably be written in TypeScript, but we will always accept js code too. Be aware that
|
||||
in that case, you must stick to **ES5** (so no `let` or arrow operators) js code. Sadly there are still enough users
|
||||
out there on old browsers. Note that this restriction does not apply to the server side code, in which you can use all
|
||||
the cool features you want. In lieu of ES6 features, [Underscore.js](https://underscorejs.org/) is available as a way
|
||||
to bridge the feature gap. The library is available both in the client and server code.
|
||||
- Be aware that **Compiler Explorer** runs on a cluster on the live site. No local state is kept between invocations,
|
||||
and the user's next request will likely hit a different node in the cluster, so don't rely on any in-memory state.
|
||||
|
||||
[Contact us]: README.md#contact-us
|
||||
[contact us]: README.md#contact-us
|
||||
|
||||
119
README.md
119
README.md
@@ -5,102 +5,98 @@
|
||||
|
||||
# Compiler Explorer
|
||||
|
||||
**Compiler Explorer** is an interactive compiler exploration website. Edit code in C, C++, C#, F#, Rust, Go, D, Haskell, Swift, Pascal, [ispc](https://ispc.github.io/), Python, Java
|
||||
or in any of the other [30+ supported languages](https://godbolt.org/api/languages), and see how that code looks after being compiled in real time.
|
||||
Multiple compilers are supported for each language, many different tools and visualisations are available, and the UI layout
|
||||
is configurable (thanks to [GoldenLayout](https://www.golden-layout.com/)).
|
||||
**Compiler Explorer** is an interactive compiler exploration website. Edit code in C, C++, C#, F#, Rust, Go, D, Haskell,
|
||||
Swift, Pascal, [ispc](https://ispc.github.io/), Python, Java or in any of the other
|
||||
[30+ supported languages](https://godbolt.org/api/languages), and see how that code looks after being compiled in real
|
||||
time. Multiple compilers are supported for each language, many different tools and visualisations are available, and the
|
||||
UI layout is configurable (thanks to [GoldenLayout](https://www.golden-layout.com/)).
|
||||
|
||||
Try out at [godbolt.org](https://godbolt.org), or [run your own local instance](#running-a-local-instance).
|
||||
|
||||
**Compiler Explorer** follows a [Code of Conduct](CODE_OF_CONDUCT.md) which
|
||||
aims to foster an open and welcoming environment.
|
||||
**Compiler Explorer** follows a [Code of Conduct](CODE_OF_CONDUCT.md) which aims to foster an open and welcoming
|
||||
environment.
|
||||
|
||||
**Compiler Explorer** was started in 2012 to show how C++ constructs translated to assembly code. It started out as a
|
||||
`tmux` session with `vi` running in one pane and `watch gcc -S foo.cc -o -` running in the other.
|
||||
|
||||
Since then, it has become a public website serving around [3,000,000 compilations per week](https://www.stathat.com/cards/Tk5csAWI0O7x).
|
||||
Since then, it has become a public website serving around
|
||||
[3,000,000 compilations per week](https://www.stathat.com/cards/Tk5csAWI0O7x).
|
||||
|
||||
You can financially support [this project on Patreon](https://patreon.com/mattgodbolt),
|
||||
[GitHub](https://github.com/sponsors/mattgodbolt/), [Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=KQWQZ7GPY2GZ6&item_name=Compiler+Explorer+development¤cy_code=USD&source=url), or by
|
||||
buying cool gear on the [Compiler Explorer store](https://shop.spreadshirt.com/compiler-explorer/).
|
||||
[GitHub](https://github.com/sponsors/mattgodbolt/),
|
||||
[Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=KQWQZ7GPY2GZ6&item_name=Compiler+Explorer+development¤cy_code=USD&source=url),
|
||||
or by buying cool gear on the [Compiler Explorer store](https://shop.spreadshirt.com/compiler-explorer/).
|
||||
|
||||
## Using Compiler Explorer
|
||||
|
||||
### FAQ
|
||||
|
||||
There is now a FAQ section [in the repository wiki](https://github.com/compiler-explorer/compiler-explorer/wiki/FAQ).
|
||||
If your question is not present, please contact us as described below, so we can help you.
|
||||
If you find that the FAQ is lacking some important point, please free to contribute to it and/or ask us to clarify it.
|
||||
There is now a FAQ section [in the repository wiki](https://github.com/compiler-explorer/compiler-explorer/wiki/FAQ). If
|
||||
your question is not present, please contact us as described below, so we can help you. If you find that the FAQ is
|
||||
lacking some important point, please free to contribute to it and/or ask us to clarify it.
|
||||
|
||||
### Videos
|
||||
|
||||
There are a number of videos that showcase some features of Compiler Explorer:
|
||||
|
||||
* [Presentation for CppCon 2019 about the project](https://www.youtube.com/watch?v=kIoZDUd5DKw)
|
||||
* [Older 2 part series of videos](https://www.youtube.com/watch?v=4_HL3PH4wDg) which go into a bit more detail
|
||||
into the more obscure features.
|
||||
* [Just Enough Assembly for Compiler Explorer](https://youtu.be/QLolzolunJ4): Practical introduction to Assembly with a focus on usage on Compiler Explorer, from CppCon 2021.
|
||||
* [Playlist: Compiler Explorer](https://www.youtube.com/playlist?list=PL2HVqYf7If8dNYVN6ayjB06FPyhHCcnhG): A collection of videos discussing Compiler Explorer; using it, installing it, what it's for, etc.
|
||||
- [Presentation for CppCon 2019 about the project](https://www.youtube.com/watch?v=kIoZDUd5DKw)
|
||||
- [Older 2 part series of videos](https://www.youtube.com/watch?v=4_HL3PH4wDg) which go into a bit more detail into the
|
||||
more obscure features.
|
||||
- [Just Enough Assembly for Compiler Explorer](https://youtu.be/QLolzolunJ4): Practical introduction to Assembly with a
|
||||
focus on usage on Compiler Explorer, from CppCon 2021.
|
||||
- [Playlist: Compiler Explorer](https://www.youtube.com/playlist?list=PL2HVqYf7If8dNYVN6ayjB06FPyhHCcnhG): A collection
|
||||
of videos discussing Compiler Explorer; using it, installing it, what it's for, etc.
|
||||
|
||||
A [Road map](docs/Roadmap.md) is available which gives a little insight into
|
||||
the future plans for **Compiler Explorer**.
|
||||
A [Road map](docs/Roadmap.md) is available which gives a little insight into the future plans for **Compiler Explorer**.
|
||||
|
||||
## Developing
|
||||
|
||||
**Compiler Explorer** is written in [Node.js](https://nodejs.org/).
|
||||
|
||||
Assuming you have a compatible version of `node` installed, on Linux simply running
|
||||
`make` ought to get you up and running with an Explorer running on port 10240
|
||||
on your local machine: [http://localhost:10240/](http://localhost:10240/). If this doesn't work for you, please contact
|
||||
us, as we consider it important you can quickly and easily get running.
|
||||
Currently, **Compiler Explorer**
|
||||
requires [`node` 16 _(LTS version)_](CONTRIBUTING.md#node-version) installed, either on the path or at `NODE_DIR`
|
||||
(an environment variable or `make` parameter).
|
||||
Assuming you have a compatible version of `node` installed, on Linux simply running `make` ought to get you up and
|
||||
running with an Explorer running on port 10240 on your local machine:
|
||||
[http://localhost:10240/](http://localhost:10240/). If this doesn't work for you, please contact us, as we consider it
|
||||
important you can quickly and easily get running. Currently, **Compiler Explorer** requires
|
||||
[`node` 16 _(LTS version)_](CONTRIBUTING.md#node-version) installed, either on the path or at `NODE_DIR` (an environment
|
||||
variable or `make` parameter).
|
||||
|
||||
Running with `make EXTRA_ARGS='--language LANG'` will allow you to load
|
||||
`LANG` exclusively, where `LANG` is one for the language ids/aliases defined
|
||||
in `lib/languages.js`. For example, to only run **Compiler Explorer** with C++ support, you'd run
|
||||
`make EXTRA_ARGS='--language c++'`. The `Makefile` will automatically install all the
|
||||
third party libraries needed to run; using `npm` to install server-side and
|
||||
client side components.
|
||||
Running with `make EXTRA_ARGS='--language LANG'` will allow you to load `LANG` exclusively, where `LANG` is one for the
|
||||
language ids/aliases defined in `lib/languages.js`. For example, to only run **Compiler Explorer** with C++ support,
|
||||
you'd run `make EXTRA_ARGS='--language c++'`. The `Makefile` will automatically install all the third party libraries
|
||||
needed to run; using `npm` to install server-side and client side components.
|
||||
|
||||
For development, we suggest using `make dev` to enable some useful features,
|
||||
such as automatic reloading on file changes and shorter startup times.
|
||||
For development, we suggest using `make dev` to enable some useful features, such as automatic reloading on file changes
|
||||
and shorter startup times.
|
||||
|
||||
You can also use `npm run dev` to run if `make dev` doesn't work on your machine.
|
||||
|
||||
Some languages need extra tools to demangle them, e.g. `rust`, `d`, or `haskell`.
|
||||
Such tools are kept separately in the
|
||||
Some languages need extra tools to demangle them, e.g. `rust`, `d`, or `haskell`. Such tools are kept separately in the
|
||||
[tools repo](https://github.com/compiler-explorer/compiler-explorer-tools).
|
||||
|
||||
Configuring compiler explorer is achieved via configuration files in the `etc/config` directory. Values are
|
||||
`key=value`. Options in a `{type}.local.properties` file (where `{type}` is `c++` or similar) override anything in the
|
||||
Configuring compiler explorer is achieved via configuration files in the `etc/config` directory. Values are `key=value`.
|
||||
Options in a `{type}.local.properties` file (where `{type}` is `c++` or similar) override anything in the
|
||||
`{type}.defaults.properties` file. There is a `.gitignore` file to ignore `*.local.*` files, so these won't be checked
|
||||
into git, and you won't find yourself fighting with updated versions when you `git pull`. For more information see
|
||||
[Adding a Compiler](docs/AddingACompiler.md).
|
||||
|
||||
Check [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed information about how you can contribute to **Compiler Explorer**,
|
||||
and the [docs](./docs) folder for specific details regarding various things you might want to do,
|
||||
such as how to add new compilers or languages to the site.
|
||||
Check [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed information about how you can contribute to **Compiler
|
||||
Explorer**, and the [docs](./docs) folder for specific details regarding various things you might want to do, such as
|
||||
how to add new compilers or languages to the site.
|
||||
|
||||
### Running a local instance
|
||||
|
||||
If you want to point it at your own GCC or similar binaries, either edit the
|
||||
`etc/config/LANG.defaults.properties` or else make a new one with
|
||||
the name `LANG.local.properties`, substituting `LANG` as needed.
|
||||
`*.local.properties` files have the highest priority when loading properties.
|
||||
If you want to point it at your own GCC or similar binaries, either edit the `etc/config/LANG.defaults.properties` or
|
||||
else make a new one with the name `LANG.local.properties`, substituting `LANG` as needed. `*.local.properties` files
|
||||
have the highest priority when loading properties.
|
||||
|
||||
When running in a corporate setting the URL shortening service can be replaced
|
||||
by an internal one if the default storage driver isn't appropriate for your
|
||||
environment. To do this, add a new module in `lib/shortener/myservice.js` and
|
||||
set the `urlShortenService` variable in configuration. This module should
|
||||
export a single function, see the [tinyurl module](lib/shortener/tinyurl.js)
|
||||
for an example.
|
||||
When running in a corporate setting the URL shortening service can be replaced by an internal one if the default storage
|
||||
driver isn't appropriate for your environment. To do this, add a new module in `lib/shortener/myservice.js` and set the
|
||||
`urlShortenService` variable in configuration. This module should export a single function, see the
|
||||
[tinyurl module](lib/shortener/tinyurl.js) for an example.
|
||||
|
||||
### RESTful API
|
||||
|
||||
There's a simple restful API that can be used to do compiles to asm and to
|
||||
list compilers.
|
||||
There's a simple restful API that can be used to do compiles to asm and to list compilers.
|
||||
|
||||
You can find the API documentation [here](docs/API.md).
|
||||
|
||||
@@ -108,7 +104,8 @@ You can find the API documentation [here](docs/API.md).
|
||||
|
||||
We run a [Compiler Explorer Discord](https://discord.gg/B5WacA7), which is a place to discuss using or developing
|
||||
Compiler Explorer. We also have a presence on the [cpplang](https://cppalliance.org/slack/) Slack channel
|
||||
`#compiler_explorer` and we have [a public mailing list](https://groups.google.com/forum/#!forum/compiler-explorer-discussion).
|
||||
`#compiler_explorer` and we have
|
||||
[a public mailing list](https://groups.google.com/forum/#!forum/compiler-explorer-discussion).
|
||||
|
||||
There's a development channel on the discord, and also a
|
||||
[development mailing list](https://groups.google.com/forum/#!forum/compiler-explorer-development).
|
||||
@@ -118,16 +115,14 @@ Feel free to raise an issue on [github](https://github.com/compiler-explorer/com
|
||||
|
||||
## Credits
|
||||
|
||||
**Compiler Explorer** is maintained by the awesome people listed in the
|
||||
[AUTHORS](AUTHORS.md) file.
|
||||
**Compiler Explorer** is maintained by the awesome people listed in the [AUTHORS](AUTHORS.md) file.
|
||||
|
||||
We would like to thank the contributors listed in the
|
||||
[CONTRIBUTORS](CONTRIBUTORS.md) file, who have helped shape **Compiler Explorer**.
|
||||
We would like to thank the contributors listed in the [CONTRIBUTORS](CONTRIBUTORS.md) file, who have helped shape
|
||||
**Compiler Explorer**.
|
||||
|
||||
We would also like to specially thank these people for their contributions to
|
||||
**Compiler Explorer**:
|
||||
- [Gabriel Devillers](https://github.com/voxelf)
|
||||
(_while working for [Kalray](http://www.kalrayinc.com/)_)
|
||||
We would also like to specially thank these people for their contributions to **Compiler Explorer**:
|
||||
|
||||
- [Gabriel Devillers](https://github.com/voxelf) (_while working for [Kalray](http://www.kalrayinc.com/)_)
|
||||
- [Johan Engelen](https://github.com/JohanEngelen)
|
||||
- [Joshua Sheard](https://github.com/jsheard)
|
||||
- [Marc Poulhiès](https://github.com/dkm)
|
||||
|
||||
17
SECURITY.md
17
SECURITY.md
@@ -1,16 +1,15 @@
|
||||
# Security Policy
|
||||
|
||||
Compiler Explorer allows remote users to compile and, if configured, execute
|
||||
code. We take security seriously, and encourage users to promptly report
|
||||
security vulnerabilities they find.
|
||||
Compiler Explorer allows remote users to compile and, if configured, execute code. We take security seriously, and
|
||||
encourage users to promptly report security vulnerabilities they find.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If the issue can be reported without revealing exploitable specifics, please
|
||||
file [an issue](https://github.com/compiler-explorer/compiler-explorer/issues/new/choose) as a bug.
|
||||
If the issue can be reported without revealing exploitable specifics, please file
|
||||
[an issue](https://github.com/compiler-explorer/compiler-explorer/issues/new/choose) as a bug.
|
||||
|
||||
Please email matt@godbolt.org with specifics, or if the bug can't be reported publically
|
||||
without leaving an obvious exploit in the public eye.
|
||||
Please email matt@godbolt.org with specifics, or if the bug can't be reported publically without leaving an obvious
|
||||
exploit in the public eye.
|
||||
|
||||
We expect to get back within a day or two. If you don't hear from us, please do ping us again,
|
||||
or reach out to us on the [Discord](https://discord.gg/wFXUwDp).
|
||||
We expect to get back within a day or two. If you don't hear from us, please do ping us again, or reach out to us on the
|
||||
[Discord](https://discord.gg/wFXUwDp).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function runFrontendTest(name) {
|
||||
it(name, () => {
|
||||
cy.window().then((win) => {
|
||||
cy.window().then(win => {
|
||||
return win.compilerExplorerFrontendTesting.run(name);
|
||||
});
|
||||
});
|
||||
|
||||
131
docs/API.md
131
docs/API.md
@@ -1,65 +1,59 @@
|
||||
# RESTful API
|
||||
|
||||
There's a simple restful API that can be used to do compiles to asm and to
|
||||
list compilers. In general all handlers live in `/api/*` endpoints, will
|
||||
accept JSON or text in POSTs, and will return text or JSON responses depending
|
||||
on the request's `Accept` header.
|
||||
There's a simple restful API that can be used to do compiles to asm and to list compilers. In general all handlers live
|
||||
in `/api/*` endpoints, will accept JSON or text in POSTs, and will return text or JSON responses depending on the
|
||||
request's `Accept` header.
|
||||
|
||||
At a later date there may be some form of rate-limiting:
|
||||
currently, requests will be queued and dealt with in the same way interactive
|
||||
requests are done for the main site. Authentication might be required at some
|
||||
point in the future (for the main **Compiler Explorer** site anyway).
|
||||
At a later date there may be some form of rate-limiting: currently, requests will be queued and dealt with in the same
|
||||
way interactive requests are done for the main site. Authentication might be required at some point in the future (for
|
||||
the main **Compiler Explorer** site anyway).
|
||||
|
||||
## Endpoints
|
||||
|
||||
### `GET /api/languages` - return a list of languages
|
||||
|
||||
Returns a list of the currently supported languages, as pairs of languages IDs
|
||||
and their names.
|
||||
Returns a list of the currently supported languages, as pairs of languages IDs and their names.
|
||||
|
||||
### `GET /api/compilers` - return a list of compilers
|
||||
|
||||
Returns a list of compilers. In text form, there's a simple formatting of the
|
||||
ID of the compiler, its description and its language ID. In JSON, all the
|
||||
information is returned as an array of compilers, with the `id` key being the
|
||||
primary identifier of each compiler.
|
||||
Returns a list of compilers. In text form, there's a simple formatting of the ID of the compiler, its description and
|
||||
its language ID. In JSON, all the information is returned as an array of compilers, with the `id` key being the primary
|
||||
identifier of each compiler.
|
||||
|
||||
Due to the amount of compilers and information available through this api call,
|
||||
by default you will only get these fields per compiler:
|
||||
`['id', 'name', 'lang', 'compilerType', 'semver', 'extensions', 'monaco']`
|
||||
Due to the amount of compilers and information available through this api call, by default you will only get these
|
||||
fields per compiler: `['id', 'name', 'lang', 'compilerType', 'semver', 'extensions', 'monaco']`
|
||||
|
||||
If you require different fields, you can specify them by adding `?fields=field1,field2,field3`
|
||||
to your query.
|
||||
If you require different fields, you can specify them by adding `?fields=field1,field2,field3` to your query.
|
||||
|
||||
To see all the available fields, you can use `?fields=all`. It is not recommended using this by default.
|
||||
|
||||
### `GET /api/compilers/<language-id>` - return a list of compilers with matching language
|
||||
|
||||
Returns a list of compilers for the provided language id. In text form,
|
||||
there's a simple formatting of the ID of the compiler, its description and its
|
||||
language ID. In JSON, all the information is returned as an array of compilers,
|
||||
with the `id` key being the primary identifier of each compiler.
|
||||
Returns a list of compilers for the provided language id. In text form, there's a simple formatting of the ID of the
|
||||
compiler, its description and its language ID. In JSON, all the information is returned as an array of compilers, with
|
||||
the `id` key being the primary identifier of each compiler.
|
||||
|
||||
The same field restrictions apply as with `GET /api/compilers`
|
||||
|
||||
### `GET /api/libraries/<language-id>` - return a list of libraries available with for a language
|
||||
|
||||
Returns a list of libraries and library versions available for the provided language id.
|
||||
This request only returns data in JSON.
|
||||
Returns a list of libraries and library versions available for the provided language id. This request only returns data
|
||||
in JSON.
|
||||
|
||||
You can use the given include paths to supply in the userArguments for compilation. *(deprecated)*
|
||||
You can use the given include paths to supply in the userArguments for compilation. _(deprecated)_
|
||||
|
||||
You will need the library id's, and the version id's to supply to **compile** if you want to include libraries during compilation.
|
||||
You will need the library id's, and the version id's to supply to **compile** if you want to include libraries during
|
||||
compilation.
|
||||
|
||||
### `GET /api/shortlinkinfo/<linkid>` - return information about a given link
|
||||
|
||||
Returns information like Sourcecode, Compiler settings and libraries for a given link id.
|
||||
This request only returns data in JSON.
|
||||
Returns information like Sourcecode, Compiler settings and libraries for a given link id. This request only returns data
|
||||
in JSON.
|
||||
|
||||
### `POST /api/compiler/<compiler-id>/compile` - perform a compilation
|
||||
|
||||
To specify a compilation request as a JSON document, post it as the appropriate
|
||||
type and send an object of the form:
|
||||
To specify a compilation request as a JSON document, post it as the appropriate type and send an object of the form:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"source": "<Source-to-compile>",
|
||||
@@ -94,6 +88,7 @@ To specify a compilation request as a JSON document, post it as the appropriate
|
||||
```
|
||||
|
||||
Execution Only request example:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"source": "int main () { return 1; }",
|
||||
@@ -120,27 +115,26 @@ Execution Only request example:
|
||||
}
|
||||
```
|
||||
|
||||
The filters are a JSON object with `true`/`false` values. If not supplied,
|
||||
defaults are used. If supplied, the provided filters override their default
|
||||
values. The `compilerOptions` is used to pass extra arguments to the back end,
|
||||
and is probably not useful for most REST users.
|
||||
The filters are a JSON object with `true`/`false` values. If not supplied, defaults are used. If supplied, the provided
|
||||
filters override their default values. The `compilerOptions` is used to pass extra arguments to the back end, and is
|
||||
probably not useful for most REST users.
|
||||
|
||||
To force a cache bypass, set `bypassCache` in the root of the request to `true`.
|
||||
|
||||
Filters include `binary`, `labels`, `intel`, `directives` and
|
||||
`demangle`, which correspond to the UI buttons on the HTML version.
|
||||
Filters include `binary`, `labels`, `intel`, `directives` and `demangle`, which correspond to the UI buttons on the HTML
|
||||
version.
|
||||
|
||||
With the tools array you can ask CE to execute certain tools available for
|
||||
the current compiler, and also supply arguments for this tool.
|
||||
With the tools array you can ask CE to execute certain tools available for the current compiler, and also supply
|
||||
arguments for this tool.
|
||||
|
||||
Libraries can be marked to have their directories available when including
|
||||
their header files. The can be listed by supplying the library ids and versions in an array.
|
||||
The id's to supply can be found with the `/api/libraries/<language-id>`
|
||||
Libraries can be marked to have their directories available when including their header files. The can be listed by
|
||||
supplying the library ids and versions in an array. The id's to supply can be found with the
|
||||
`/api/libraries/<language-id>`
|
||||
|
||||
### `GET /api/formats` - return available code formatters
|
||||
|
||||
Returns a list of code formatters. The API returns an array of formatter objects
|
||||
which have the following object structure:
|
||||
Returns a list of code formatters. The API returns an array of formatter objects which have the following object
|
||||
structure:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -178,8 +172,7 @@ The returned JSON body has the following object structure:
|
||||
}
|
||||
```
|
||||
|
||||
In cases of internal code formatter failure an additional field named `throw`
|
||||
is also provided and set to true.
|
||||
In cases of internal code formatter failure an additional field named `throw` is also provided and set to true.
|
||||
|
||||
# Non-REST API's
|
||||
|
||||
@@ -187,12 +180,10 @@ In cases of internal code formatter failure an additional field named `throw`
|
||||
|
||||
This is same endpoint as for compilation using JSON.
|
||||
|
||||
A text compilation request has the source as the body of the post, and uses
|
||||
query parameters to pass the options and filters. Filters are supplied as a
|
||||
comma-separated string. Use the query parameter `filters=XX` to set the
|
||||
filters directly, else `addFilters=XX` to add a filter to defaults,
|
||||
or `removeFilters` to remove from defaults.
|
||||
Compiler parameters should be passed as `options=-O2` and default to empty.
|
||||
A text compilation request has the source as the body of the post, and uses query parameters to pass the options and
|
||||
filters. Filters are supplied as a comma-separated string. Use the query parameter `filters=XX` to set the filters
|
||||
directly, else `addFilters=XX` to add a filter to defaults, or `removeFilters` to remove from defaults. Compiler
|
||||
parameters should be passed as `options=-O2` and default to empty.
|
||||
|
||||
The text request is designed for simplicity for command-line clients like `curl`
|
||||
|
||||
@@ -207,8 +198,7 @@ foo():
|
||||
ret
|
||||
```
|
||||
|
||||
If JSON is present in the request's `Accept` header, the compilation results
|
||||
are of the form:
|
||||
If JSON is present in the request's `Accept` header, the compilation results are of the form:
|
||||
|
||||
(_Optional values are marked with a `**`_)
|
||||
|
||||
@@ -250,12 +240,14 @@ If JSON is present in the request's `Accept` header, the compilation results
|
||||
}
|
||||
```
|
||||
|
||||
### `POST /api/shortener` - saves given state *forever* to a shortlink and returns the unique id for the link
|
||||
### `POST /api/shortener` - saves given state _forever_ to a shortlink and returns the unique id for the link
|
||||
|
||||
The body of this post should be in the format of a [ClientState](https://github.com/compiler-explorer/compiler-explorer/blob/main/lib/clientstate.js)
|
||||
Be sure that the Content-Type of your post is application/json
|
||||
The body of this post should be in the format of a
|
||||
[ClientState](https://github.com/compiler-explorer/compiler-explorer/blob/main/lib/clientstate.js) Be sure that the
|
||||
Content-Type of your post is application/json
|
||||
|
||||
An example of one the easiest forms of a clientstate:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"sessions": [
|
||||
@@ -286,6 +278,7 @@ An example of one the easiest forms of a clientstate:
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"url": "https://godbolt.org/z/Km_340"
|
||||
@@ -298,27 +291,27 @@ The storedId can be used in the api call /api/shortlinkinfo/<id> and to open in
|
||||
|
||||
This call opens the website in a state that was previously saved using the built-in shortener.
|
||||
|
||||
|
||||
### `GET /z/<id>/code/<sourceid>` - Returns just the sourcecode from a shortlink
|
||||
|
||||
This call returns plain/text for the code that was previously saved using the built-in shortener.
|
||||
|
||||
If there were multiple editors during the saved session, you can retrieve them by setting <sourceid> to 1, 2, 3, etcetera, otherwise <sourceid> can be set to 1.
|
||||
|
||||
If there were multiple editors during the saved session, you can retrieve them by setting <sourceid> to 1, 2, 3,
|
||||
etcetera, otherwise <sourceid> can be set to 1.
|
||||
|
||||
### `GET /clientstate/<base64>` - Opens the website in a given state
|
||||
|
||||
This call is to open the website with a given state (without having to store the state first with /api/shortener)
|
||||
Instead of sending the ClientState JSON in the post body, it will have to be encoded with base64 and attached directly onto the URL.
|
||||
|
||||
Instead of sending the ClientState JSON in the post body, it will have to be encoded with base64 and attached directly
|
||||
onto the URL.
|
||||
|
||||
# Implementations
|
||||
|
||||
Here are some examples of projects using the Compiler Explorer API:
|
||||
* [Commandline CE by ethanhs](https://github.com/ethanhs/cce) (Rust)
|
||||
* [VIM plugin by ldrumm](https://github.com/ldrumm/compiler-explorer.vim)
|
||||
* [API in Delphi by partouf](https://github.com/partouf/compilerexplorer-api) (Delphi)
|
||||
* [QTCreator Plugin by dobokirisame](https://github.com/dobokirisame/CompilerExplorer) (C++)
|
||||
* [CLion plugin by ogrebenyuk](https://github.com/ogrebenyuk/compilerexplorer) (Java)
|
||||
* [QCompilerExplorer - frontend in Qt](https://github.com/Waqar144/QCompilerExplorer) (C++)
|
||||
* [Emacs client - compiler-explorer.el](https://github.com/mkcms/compiler-explorer.el)
|
||||
|
||||
- [Commandline CE by ethanhs](https://github.com/ethanhs/cce) (Rust)
|
||||
- [VIM plugin by ldrumm](https://github.com/ldrumm/compiler-explorer.vim)
|
||||
- [API in Delphi by partouf](https://github.com/partouf/compilerexplorer-api) (Delphi)
|
||||
- [QTCreator Plugin by dobokirisame](https://github.com/dobokirisame/CompilerExplorer) (C++)
|
||||
- [CLion plugin by ogrebenyuk](https://github.com/ogrebenyuk/compilerexplorer) (Java)
|
||||
- [QCompilerExplorer - frontend in Qt](https://github.com/Waqar144/QCompilerExplorer) (C++)
|
||||
- [Emacs client - compiler-explorer.el](https://github.com/mkcms/compiler-explorer.el)
|
||||
|
||||
@@ -4,45 +4,53 @@
|
||||
|
||||
Libraries are hard. Libraries can be needed for user code, but also to run compilers.
|
||||
|
||||
For CE we use a lot of different compilers and environments that need to be separated from the OS's installation, and that makes things more complicated than just building with your standard OS's compiler.
|
||||
For CE we use a lot of different compilers and environments that need to be separated from the OS's installation, and
|
||||
that makes things more complicated than just building with your standard OS's compiler.
|
||||
|
||||
Including header files or equivalent is usually the easy part. If there are binaries involved, things get complicated.
|
||||
|
||||
We have a couple of separate stages where we use and mix different techniques to be able to produce the right assembly or executables.
|
||||
|
||||
* Compilation without linking
|
||||
* The `LD_LIBRARY_PATH` environment variable is used here to enable the compiler to find the `.so` files that they need to run.
|
||||
* If you're running a local installation, this is usually your own systems' `LD_LIBRARY_PATH` plus extra things that CE adds through properties.
|
||||
* On godbolt.org we always start with an empty `LD_LIBRARY_PATH` and add what is set in the properties.
|
||||
* Building an executable or binary
|
||||
* We use `-Wl,-rpath=` (or equivalent `rpathFlag`) to force library paths into the executable so that they will always find the same `.so` files no matter where they are run. Usually this also includes lib64 and lib folders that the compiler offers for standard libraries that the toolchain offers.
|
||||
* Library paths supplied through `-Wl,-rpath=` for shared libraries will be able to dynamically link to the right architecture's `.so` even if multiple paths are given that contain the same `.so` file.
|
||||
* We use `-L` (or equivalent `libpathFlag`) to enable the compiler to find both static (`.a`) and shared (`.so`) libraries.
|
||||
* We always add '.' as a path as well because that's where we put libraries that are downloaded from our Conan server.
|
||||
* We use `-l` (or equivalent `linkFlag`) to say we want to statically or dynamically link to a named library binary (the compiler and linker decide if it's gonna be static or dynamic).
|
||||
* Running the executable
|
||||
* We use `LD_LIBRARY_PATH` just in case these are dependencies inherited from the compiler - and for the libraries that are used (also just in case).
|
||||
We have a couple of separate stages where we use and mix different techniques to be able to produce the right assembly
|
||||
or executables.
|
||||
|
||||
- Compilation without linking
|
||||
- The `LD_LIBRARY_PATH` environment variable is used here to enable the compiler to find the `.so` files that they
|
||||
need to run.
|
||||
- If you're running a local installation, this is usually your own systems' `LD_LIBRARY_PATH` plus extra things that
|
||||
CE adds through properties.
|
||||
- On godbolt.org we always start with an empty `LD_LIBRARY_PATH` and add what is set in the properties.
|
||||
- Building an executable or binary
|
||||
- We use `-Wl,-rpath=` (or equivalent `rpathFlag`) to force library paths into the executable so that they will always
|
||||
find the same `.so` files no matter where they are run. Usually this also includes lib64 and lib folders that the
|
||||
compiler offers for standard libraries that the toolchain offers.
|
||||
- Library paths supplied through `-Wl,-rpath=` for shared libraries will be able to dynamically link to the right
|
||||
architecture's `.so` even if multiple paths are given that contain the same `.so` file.
|
||||
- We use `-L` (or equivalent `libpathFlag`) to enable the compiler to find both static (`.a`) and shared (`.so`)
|
||||
libraries.
|
||||
- We always add '.' as a path as well because that's where we put libraries that are downloaded from our Conan server.
|
||||
- We use `-l` (or equivalent `linkFlag`) to say we want to statically or dynamically link to a named library binary
|
||||
(the compiler and linker decide if it's gonna be static or dynamic).
|
||||
- Running the executable
|
||||
- We use `LD_LIBRARY_PATH` just in case these are dependencies inherited from the compiler - and for the libraries
|
||||
that are used (also just in case).
|
||||
|
||||
## Specific properties that are used in certain situations
|
||||
|
||||
* Compiler .ldPath
|
||||
* is used for `LD_LIBRARY_PATH` to support running the compiler
|
||||
* is used for linking (`-Wl,-rpath=` and/or `-L`) during building binaries
|
||||
* is used for `LD_LIBRARY_PATH` to enable the users's executable to find `.so` files
|
||||
* Compiler .libPath
|
||||
* is used for linking (`-Wl,-rpath=` and/or `-L`) during building binaries
|
||||
* is used for `LD_LIBRARY_PATH` to enable the users's executable to find `.so` files
|
||||
* Library .libPath
|
||||
* is used for linking (`-Wl,-rpath=` and/or `-L`) during building binaries
|
||||
* is used for `LD_LIBRARY_PATH` to enable the users's executable to find `.so` files (just in case)
|
||||
|
||||
- Compiler .ldPath
|
||||
- is used for `LD_LIBRARY_PATH` to support running the compiler
|
||||
- is used for linking (`-Wl,-rpath=` and/or `-L`) during building binaries
|
||||
- is used for `LD_LIBRARY_PATH` to enable the users's executable to find `.so` files
|
||||
- Compiler .libPath
|
||||
- is used for linking (`-Wl,-rpath=` and/or `-L`) during building binaries
|
||||
- is used for `LD_LIBRARY_PATH` to enable the users's executable to find `.so` files
|
||||
- Library .libPath
|
||||
- is used for linking (`-Wl,-rpath=` and/or `-L`) during building binaries
|
||||
- is used for `LD_LIBRARY_PATH` to enable the users's executable to find `.so` files (just in case)
|
||||
|
||||
## Example
|
||||
|
||||
Say we have the following things in a `c++.local.properties` file:
|
||||
|
||||
```
|
||||
```INI
|
||||
compilers=mycl
|
||||
compiler.mycl.exe=/home/ubuntu/mycl/bin
|
||||
compiler.mycl.ldPath=/home/ubuntu/mycl/lib/lib64
|
||||
@@ -57,24 +65,25 @@ libs.mylib.libpath=/home/ubuntu/mylib/lib
|
||||
libs.mylib.staticliblink=mylib
|
||||
```
|
||||
|
||||
This will result in the following situations if we want to compile some code with both the mycl compiler and the mylib library:
|
||||
This will result in the following situations if we want to compile some code with both the mycl compiler and the mylib
|
||||
library:
|
||||
|
||||
* Compilation without linking
|
||||
* `LD_LIBRARY_PATH` is set to `/home/ubuntu/mycl/lib/lib64`
|
||||
* `-I/home/ubuntu/mylib/include` is added to the compilation arguments
|
||||
* Building an executable or binary
|
||||
* `LD_LIBRARY_PATH` is set to `/home/ubuntu/mycl/lib/lib64`
|
||||
* The following are added to the compilation arguments
|
||||
* `-I/home/ubuntu/mylib/include` (library include path)
|
||||
* `-Wl,-rpath=/home/ubuntu/mycl/lib/lib64` (compiler library paths)
|
||||
* `-Wl,-rpath=/home/ubuntu/mycl/lib/lib32`
|
||||
* `-Wl,-rpath=.` (conan library path)
|
||||
* `-L.`
|
||||
* `-Wl,-rpath=/home/ubuntu/gcc10/lib/lib` (gcc toolchain library paths)
|
||||
* `-Wl,-rpath=/home/ubuntu/gcc10/lib/lib32`
|
||||
* `-Wl,-rpath=/home/ubuntu/gcc10/lib/lib64`
|
||||
* `-Wl,-rpath=/home/ubuntu/mylib/lib` (mylib library path - just in case there are `.so` files used)
|
||||
* `-L/home/ubuntu/mylib/lib` (mylib library path used to find `libmylib.a`)
|
||||
* `-lmylib` (mylib library name)
|
||||
* Running the executable
|
||||
* `LD_LIBRARY_PATH` is set to `/home/ubuntu/mycl/lib/lib64:/home/ubuntu/mycl/lib/lib32:/home/ubuntu/mylib/lib`
|
||||
- Compilation without linking
|
||||
- `LD_LIBRARY_PATH` is set to `/home/ubuntu/mycl/lib/lib64`
|
||||
- `-I/home/ubuntu/mylib/include` is added to the compilation arguments
|
||||
- Building an executable or binary
|
||||
- `LD_LIBRARY_PATH` is set to `/home/ubuntu/mycl/lib/lib64`
|
||||
- The following are added to the compilation arguments
|
||||
- `-I/home/ubuntu/mylib/include` (library include path)
|
||||
- `-Wl,-rpath=/home/ubuntu/mycl/lib/lib64` (compiler library paths)
|
||||
- `-Wl,-rpath=/home/ubuntu/mycl/lib/lib32`
|
||||
- `-Wl,-rpath=.` (conan library path)
|
||||
- `-L.`
|
||||
- `-Wl,-rpath=/home/ubuntu/gcc10/lib/lib` (gcc toolchain library paths)
|
||||
- `-Wl,-rpath=/home/ubuntu/gcc10/lib/lib32`
|
||||
- `-Wl,-rpath=/home/ubuntu/gcc10/lib/lib64`
|
||||
- `-Wl,-rpath=/home/ubuntu/mylib/lib` (mylib library path - just in case there are `.so` files used)
|
||||
- `-L/home/ubuntu/mylib/lib` (mylib library path used to find `libmylib.a`)
|
||||
- `-lmylib` (mylib library name)
|
||||
- Running the executable
|
||||
- `LD_LIBRARY_PATH` is set to `/home/ubuntu/mycl/lib/lib64:/home/ubuntu/mycl/lib/lib32:/home/ubuntu/mylib/lib`
|
||||
|
||||
@@ -1,51 +1,52 @@
|
||||
# Adding a new compiler
|
||||
|
||||
This document explains how to add a new compiler to Compiler Explorer ("CE" from here on), first for a local instance, and
|
||||
then how to submit PRs to get it into the main CE site.
|
||||
This document explains how to add a new compiler to Compiler Explorer ("CE" from here on), first for a local instance,
|
||||
and then how to submit PRs to get it into the main CE site.
|
||||
|
||||
## Configuration
|
||||
|
||||
Compiler configuration is done through the `etc/config/c++.*.properties` files
|
||||
(for C++, other languages follow the obvious pattern, replace as needed for your case).
|
||||
Compiler configuration is done through the `etc/config/c++.*.properties` files (for C++, other languages follow the
|
||||
obvious pattern, replace as needed for your case).
|
||||
|
||||
The various named configuration files are used in different contexts: for example `etc/config/c++.local.properties` take priority over
|
||||
`etc/config/c++.defaults.properties`. The `local` version is ignored by git, so you can make your own personalised changes there.
|
||||
The live site uses the `etc/config/c++.amazon.properties` file.
|
||||
The various named configuration files are used in different contexts: for example `etc/config/c++.local.properties` take
|
||||
priority over `etc/config/c++.defaults.properties`. The `local` version is ignored by git, so you can make your own
|
||||
personalised changes there. The live site uses the `etc/config/c++.amazon.properties` file.
|
||||
|
||||
Within the file, configuration is a set of key and value pairs, separated by an `=`. Whitespace is _not_ trimmed.
|
||||
Lines starting with `#` are considered comments and not parsed.
|
||||
The list of compilers is set by the `compilers` key and is a list of compiler identifiers or groups, separated by colons. Group names
|
||||
have an `&` prepended. As a nod to backwards compatibility with very old configurations, a path to a compiler can also be put
|
||||
in the list, but that doesn't let you configure many aspects of the compiler, nor does it allow paths with colons in them (since these
|
||||
are used as separators). The identifier itself is not important, but must be unique to that compiler.
|
||||
Within the file, configuration is a set of key and value pairs, separated by an `=`. Whitespace is _not_ trimmed. Lines
|
||||
starting with `#` are considered comments and not parsed. The list of compilers is set by the `compilers` key and is a
|
||||
list of compiler identifiers or groups, separated by colons. Group names have an `&` prepended. As a nod to backwards
|
||||
compatibility with very old configurations, a path to a compiler can also be put in the list, but that doesn't let you
|
||||
configure many aspects of the compiler, nor does it allow paths with colons in them (since these are used as
|
||||
separators). The identifier itself is not important, but must be unique to that compiler.
|
||||
|
||||
An example configuration:
|
||||
|
||||
```
|
||||
```INI
|
||||
compilers=gcc620:gcc720:&clang
|
||||
```
|
||||
|
||||
This says there are two compilers with identifiers `gcc620` and `gcc720`, and a group of compilers called `clang`. For the
|
||||
compilers, CE will look for some keys named `compiler.ID.name` and `compiler.ID.exe` (and some others, detailed later). The `ID`
|
||||
is the identifier of the compiler being looked up. The `name` value is used as the human-readable compiler name shown to users,
|
||||
and the `exe` should be the path name of the compiler executable.
|
||||
This says there are two compilers with identifiers `gcc620` and `gcc720`, and a group of compilers called `clang`. For
|
||||
the compilers, CE will look for some keys named `compiler.ID.name` and `compiler.ID.exe` (and some others, detailed
|
||||
later). The `ID` is the identifier of the compiler being looked up. The `name` value is used as the human-readable
|
||||
compiler name shown to users, and the `exe` should be the path name of the compiler executable.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
```INI
|
||||
compiler.gcc620.name=GCC 6.2.0
|
||||
compiler.gcc620.exe=/usr/bin/gcc-6.2.0
|
||||
compiler.gcc720.name=GCC 7.2.0
|
||||
compiler.gcc720.exe=/usr/bin/gcc-7.2.0
|
||||
```
|
||||
|
||||
In addition to the `name` and `exe` per-compiler configuration keys, there are also some other options. Most of them default
|
||||
to sensible values for GCC-like compilers.
|
||||
In addition to the `name` and `exe` per-compiler configuration keys, there are also some other options. Most of them
|
||||
default to sensible values for GCC-like compilers.
|
||||
|
||||
A group is defined similar to a list of compilers, and may contain other groups. Keys for groups start with `group.ID`.
|
||||
Configuration keys applied to the group apply to all compilers in that group (unless overridden by the compiler itself). An example:
|
||||
Configuration keys applied to the group apply to all compilers in that group (unless overridden by the compiler itself).
|
||||
An example:
|
||||
|
||||
```
|
||||
```INI
|
||||
group.clang.compilers=clang4:clang5
|
||||
group.clang.intelAsm=-mllvm -x86-asm-syntax=intel
|
||||
compiler.clang4.name=Clang 4
|
||||
@@ -56,12 +57,13 @@ compiler.clang5.exe=/usr/bin/clang5
|
||||
|
||||
Note about configuration files hierarchy:
|
||||
|
||||
As mentioned previously, the live site uses `etc/config/c++.amazon.properties` to load its configuration from,
|
||||
but for properties not defined in the `amazon` file, the values present in `etc/config/c++.defaults.properties` will be used.
|
||||
As mentioned previously, the live site uses `etc/config/c++.amazon.properties` to load its configuration from, but for
|
||||
properties not defined in the `amazon` file, the values present in `etc/config/c++.defaults.properties` will be used.
|
||||
|
||||
By design, this does not however work for groups (Nor any other nested property).
|
||||
That is, if in `etc/config/c++.defaults.properties` you define the `intelAsm` property as:
|
||||
```
|
||||
By design, this does not however work for groups (Nor any other nested property). That is, if in
|
||||
`etc/config/c++.defaults.properties` you define the `intelAsm` property as:
|
||||
|
||||
```INI
|
||||
versionFlag=--version
|
||||
compilers=&clang
|
||||
group.clang.intelAsm=-mllvm -x86-asm-syntax=intel
|
||||
@@ -70,88 +72,91 @@ group.clang.groupName=Clang
|
||||
```
|
||||
|
||||
but `etc/config/c++.amazon.properties` only has:
|
||||
```
|
||||
|
||||
```INI
|
||||
compilers=&clang
|
||||
group.clang.groupName=Clang
|
||||
...
|
||||
```
|
||||
once the site runs on the Amazon environment, the `&clang` group **will not** have the `intelAsm` property set,
|
||||
but `versionFlag` will.
|
||||
|
||||
once the site runs on the Amazon environment, the `&clang` group **will not** have the `intelAsm` property set, but
|
||||
`versionFlag` will.
|
||||
|
||||
### Configuration keys
|
||||
|
||||
Key Name | Type | Description|
|
||||
---------|-------|-----|
|
||||
name | String | Human readable name of the compiler||
|
||||
exe | Path | Path to the executable|
|
||||
alias | Identifier | Another identifier for this compiler (mostly deprecated, used for backwards compatibility with very old CE URLs) |
|
||||
options | String | Additional compiler options passed to the compiler when running it |
|
||||
intelAsm | String | Flags used to select intel assembly format (if not detected automatically)|
|
||||
needsMulti | Boolean | Whether the compiler needs multi arch support (defaults to yes if the host has multiarch enabled)|
|
||||
supportsBinary | Boolean | Whether this compiler supports compiling to binary|
|
||||
supportsExecute | Boolean | Whether binary output from this compiler can be executed|
|
||||
versionFlag | String | The flag to pass to the compiler to make it emit its version|
|
||||
versionRe | RegExp | A regular expression used to capture the version from the version output|
|
||||
compilerType | String | The name of the class handling this compiler|
|
||||
interpreted | Boolean | Whether this is an interpreted language, and so the "compiler" is really an interpreter|
|
||||
executionWrapper | Path | Path to script that can execute the compiler's output (e.g. could run under `qemu` or `mpi_run` or similar)|
|
||||
| Key Name | Type | Description |
|
||||
| ---------------- | ---------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| name | String | Human readable name of the compiler |
|
||||
| exe | Path | Path to the executable |
|
||||
| alias | Identifier | Another identifier for this compiler (mostly deprecated, used for backwards compatibility with very old CE URLs) |
|
||||
| options | String | Additional compiler options passed to the compiler when running it |
|
||||
| intelAsm | String | Flags used to select intel assembly format (if not detected automatically) |
|
||||
| needsMulti | Boolean | Whether the compiler needs multi arch support (defaults to yes if the host has multiarch enabled) |
|
||||
| supportsBinary | Boolean | Whether this compiler supports compiling to binary |
|
||||
| supportsExecute | Boolean | Whether binary output from this compiler can be executed |
|
||||
| versionFlag | String | The flag to pass to the compiler to make it emit its version |
|
||||
| versionRe | RegExp | A regular expression used to capture the version from the version output |
|
||||
| compilerType | String | The name of the class handling this compiler |
|
||||
| interpreted | Boolean | Whether this is an interpreted language, and so the "compiler" is really an interpreter |
|
||||
| executionWrapper | Path | Path to script that can execute the compiler's output (e.g. could run under `qemu` or `mpi_run` or similar) |
|
||||
|
||||
The `compilerType` option is special: it refers to the Javascript class in `lib/compilers/*.js` which handles running and handling
|
||||
output for this compiler type.
|
||||
The `compilerType` option is special: it refers to the Javascript class in `lib/compilers/*.js` which handles running
|
||||
and handling output for this compiler type.
|
||||
|
||||
## Adding a new compiler locally
|
||||
|
||||
It should be pretty straightforward to add a compiler of your own. Create a `etc/config/c++.local.properties` file and override the
|
||||
`compilers` list to include your own compiler, and its configuration.
|
||||
It should be pretty straightforward to add a compiler of your own. Create a `etc/config/c++.local.properties` file and
|
||||
override the `compilers` list to include your own compiler, and its configuration.
|
||||
|
||||
Once you've done that, running `make` should pick up the configuration and during startup you should see your compiler being run
|
||||
and its version being extracted. If you don't, check for any errors, and try running with `make EXTRA_ARGS='--debug'` to see (a lot of)
|
||||
debug output.
|
||||
Once you've done that, running `make` should pick up the configuration and during startup you should see your compiler
|
||||
being run and its version being extracted. If you don't, check for any errors, and try running with
|
||||
`make EXTRA_ARGS='--debug'` to see (a lot of) debug output.
|
||||
|
||||
If you're looking to add other language compilers for another language, obviously create the `etc/config/LANG.local.properties` in
|
||||
the above steps, and run with `make EXTRA_ARGS='--language LANG'` (e.g. `etc/config/rust.local.properties` and
|
||||
`make EXTRA_ARGS='--language Rust'`).
|
||||
If you're looking to add other language compilers for another language, obviously create the
|
||||
`etc/config/LANG.local.properties` in the above steps, and run with `make EXTRA_ARGS='--language LANG'` (e.g.
|
||||
`etc/config/rust.local.properties` and `make EXTRA_ARGS='--language Rust'`).
|
||||
|
||||
Test locally, and for many compilers that's probably all you need to do. Some compilers might need a few options tweaks (like
|
||||
the intel asm setting, or the version flag). For a completely new compiler, you might need to define a whole new `compilerType`.
|
||||
Doing so is beyond this document's scope at present, but take a look inside `lib/compilers/` to get some idea what might need
|
||||
to be done.
|
||||
Test locally, and for many compilers that's probably all you need to do. Some compilers might need a few options tweaks
|
||||
(like the intel asm setting, or the version flag). For a completely new compiler, you might need to define a whole new
|
||||
`compilerType`. Doing so is beyond this document's scope at present, but take a look inside `lib/compilers/` to get some
|
||||
idea what might need to be done.
|
||||
|
||||
## Adding a new compiler running remotely to your locally built compiler explorer
|
||||
|
||||
If you would like to have both gcc and MSVC running in the "same" compiler explorer, one option would be running gcc on your local
|
||||
Linux machine and add a proxy to the MSVC compiler, which is running on a remote Window host. To achieve this, you could
|
||||
If you would like to have both gcc and MSVC running in the "same" compiler explorer, one option would be running gcc on
|
||||
your local Linux machine and add a proxy to the MSVC compiler, which is running on a remote Window host. To achieve
|
||||
this, you could
|
||||
|
||||
* Setup compiler explorer on your Linux host as usual
|
||||
* Follow [this guide](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/WindowsNative.md)
|
||||
to set up another compiler explorer instance on your Windows host
|
||||
* Add your Windows compiler explorer as a proxy to your Linux compiler explorer. You can simply modify your
|
||||
- Setup compiler explorer on your Linux host as usual
|
||||
- Follow [this guide](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/WindowsNative.md) to set up
|
||||
another compiler explorer instance on your Windows host
|
||||
- Add your Windows compiler explorer as a proxy to your Linux compiler explorer. You can simply modify your
|
||||
`etc/config/c++.local.properties` on your Linux host
|
||||
|
||||
```
|
||||
compilers=&gcc:&clang:myWindowsHost@10240
|
||||
```
|
||||
|
||||
Yes it is the `@` symbol rather than the `:` before the port number. Restart the Linux compiler explorer, and you will be able to
|
||||
see the MSVC compiler in the compiler list.
|
||||
Yes it is the `@` symbol rather than the `:` before the port number. Restart the Linux compiler explorer, and you will
|
||||
be able to see the MSVC compiler in the compiler list.
|
||||
|
||||
## Adding a new compiler to the live site
|
||||
|
||||
On the main CE website, compilers are installed into a `/opt/compiler-explorer/` directory by a set of scripts in the sister
|
||||
GitHub repo: https://github.com/compiler-explorer/infra
|
||||
On the main CE website, compilers are installed into a `/opt/compiler-explorer/` directory by a set of scripts in the
|
||||
sister GitHub repo: https://github.com/compiler-explorer/infra
|
||||
|
||||
In the `update_compilers` directory in that repository are a set of scripts that download and install binaries and compilers.
|
||||
If you wish to test locally, and can create a `/opt/compiler-explorer` directory on your machine which is readable and writable by your
|
||||
current user, then you can run the scripts directly. The binaries and the free compilers can be installed - the commercial compilers
|
||||
live in the `install_nonfree_compilers.sh` and won't work.
|
||||
In the `update_compilers` directory in that repository are a set of scripts that download and install binaries and
|
||||
compilers. If you wish to test locally, and can create a `/opt/compiler-explorer` directory on your machine which is
|
||||
readable and writable by your current user, then you can run the scripts directly. The binaries and the free compilers
|
||||
can be installed - the commercial compilers live in the `install_nonfree_compilers.sh` and won't work.
|
||||
|
||||
If your compiler fits nicely into the harness then it should be straightforward to add it there. Anything more complex: contact the CE
|
||||
authors for more help.
|
||||
If your compiler fits nicely into the harness then it should be straightforward to add it there. Anything more complex:
|
||||
contact the CE authors for more help.
|
||||
|
||||
## Putting it all together
|
||||
|
||||
Hopefully that's enough to get an idea. The ideal case of a GCC-like compiler should be a pull request to add a couple of
|
||||
lines to the `infra` repository to install the compiler, and a pull request to add a few lines to the `LANG.amazon.properties`
|
||||
file in this repository.
|
||||
Hopefully that's enough to get an idea. The ideal case of a GCC-like compiler should be a pull request to add a couple
|
||||
of lines to the `infra` repository to install the compiler, and a pull request to add a few lines to the
|
||||
`LANG.amazon.properties` file in this repository.
|
||||
|
||||
If you feel like we could improve this document in any way, please contact us. We'd love to hear from you!
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
# Adding a new formatter
|
||||
|
||||
* Add a `etc/config/compiler-explorer.local.properties` file
|
||||
- Add a `etc/config/compiler-explorer.local.properties` file
|
||||
|
||||
- Add a new formatter under the `formatters` key
|
||||
- The new formatter can have the following keys: name, exe, styles, type, explicitVersion (to override version
|
||||
parsing), version (argument to get version info), versionRe (regex to filter out the right version info)
|
||||
- Add a `lib/formatters/<formatter>.js` file using the template below, replacing `Type` and `type` as
|
||||
appropriate
|
||||
- Add a `lib/formatters/<formatter>.js` file using the template below, replacing `Type` and `type` as appropriate
|
||||
|
||||
```js
|
||||
import {BaseFormatter} from '../base-formatter';
|
||||
|
||||
export class TypeFormatter extends BaseFormatter {
|
||||
static get key() { return 'type'; }
|
||||
static get key() {
|
||||
return 'type';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- The value returned by `key` above corresponds to the `type` property you set in the compiler-explorer properties
|
||||
configuration file.
|
||||
- Tweak `format(source, options)` and `isValidStyle(style)` as necessary. See the JSDoc for `format` and the
|
||||
implementations for other formatters to get a further understanding of how to implement `format(source, options)`.
|
||||
* Add your `TypeFormatter` to `lib/formatters/_all.js` in alphabetical order
|
||||
|
||||
* You can check the output of http://localhost:10240/api/formats to be sure your formatter is there.
|
||||
- Add your `TypeFormatter` to `lib/formatters/_all.js` in alphabetical order
|
||||
|
||||
* Make an installer in the [infra](https://github.com/compiler-explorer/infra) repository. An example patch for adding
|
||||
- You can check the output of http://localhost:10240/api/formats to be sure your formatter is there.
|
||||
|
||||
- Make an installer in the [infra](https://github.com/compiler-explorer/infra) repository. An example patch for adding
|
||||
an installer can be found [here](https://github.com/compiler-explorer/infra/pull/560)
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
If you want to add a new language to the site, you should follow this steps:
|
||||
|
||||
* Add the new language to the exported `languages` variable in `lib/languages.js`:
|
||||
- Add the new language to the exported `languages` variable in `lib/languages.js`:
|
||||
|
||||
- The syntax is as follows:
|
||||
|
||||
```js
|
||||
'language-key': {
|
||||
name: YOUR_LANGUAGE_DISPLAY_NAME,
|
||||
@@ -12,25 +14,30 @@ If you want to add a new language to the site, you should follow this steps:
|
||||
alias: [], // Leave empty unless needed
|
||||
}
|
||||
```
|
||||
- If the language is supported by Monaco Editor (You can find the
|
||||
list [here](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages)), you should add it to the list of
|
||||
languages inside the `MonacoEditorWebpackPlugin` config in `webpack.config.js`
|
||||
- If not, you should implement your own language mode; see `static/modes/asm-mode.js` as an example. Don't forget
|
||||
to *require* your mode file in `static/modes/_all.ts`, in alphabetical order
|
||||
- `language-key` is how your language will be referred internally by the code. In the rest of this document,
|
||||
replace `{language-key}` by the corresponding value in the real files.
|
||||
|
||||
* Add a `lib/compilers/{language-key}.js` file using the template below:
|
||||
- If the language is supported by Monaco Editor (You can find the list
|
||||
[here](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages)), you should add it to the list of
|
||||
languages inside the `MonacoEditorWebpackPlugin` config in `webpack.config.js`
|
||||
- If not, you should implement your own language mode; see `static/modes/asm-mode.js` as an example. Don't forget to
|
||||
_require_ your mode file in `static/modes/_all.ts`, in alphabetical order
|
||||
- `language-key` is how your language will be referred internally by the code. In the rest of this document, replace
|
||||
`{language-key}` by the corresponding value in the real files.
|
||||
|
||||
- Add a `lib/compilers/{language-key}.js` file using the template below:
|
||||
|
||||
```js
|
||||
import {BaseCompiler} from '../base-compiler';
|
||||
|
||||
export class LanguageCompiler extends BaseCompiler {
|
||||
static get key() { return 'language'; }
|
||||
static get key() {
|
||||
return 'language';
|
||||
}
|
||||
}
|
||||
```
|
||||
- The value returned by `key` above corresponds to the `compilerType` value
|
||||
in `etc/config/{language-key}.defaults.properties` (Explained below). This is usually `{language-key}`, but you
|
||||
can use whatever fits best
|
||||
|
||||
- The value returned by `key` above corresponds to the `compilerType` value in
|
||||
`etc/config/{language-key}.defaults.properties` (Explained below). This is usually `{language-key}`, but you can use
|
||||
whatever fits best
|
||||
- Override the `OptionsForFilter` method from the base class
|
||||
- Comment out the line saying `fs.remove(result.dirPath);` in base-compiler.js, so the latest CE compile attempt
|
||||
remains on disk for you to review
|
||||
@@ -47,26 +54,28 @@ If you want to add a new language to the site, you should follow this steps:
|
||||
- set `execOptions.env` parameter if the compiler requires special environment variables
|
||||
- manipulate `options`, but make sure the user can still add their own arguments in CE
|
||||
|
||||
* Add your `LanguageCompiler` to `lib/compilers/_all.js`, in alphabetical order
|
||||
- Add your `LanguageCompiler` to `lib/compilers/_all.js`, in alphabetical order
|
||||
|
||||
- Add a `etc/config/{language-key}.local.properties` file:
|
||||
|
||||
* Add a `etc/config/{language-key}.local.properties` file:
|
||||
- The syntax for its basic contents is documented in [AddingACompiler.md](AddingACompiler.md)
|
||||
- This file is ignored by Git, so that you can test the config locally
|
||||
- You should add 1 compiler for the language you want to test
|
||||
- Test the command line options of the language compilers outside CE
|
||||
|
||||
* Add a new file `etc/config/{language-key}.defaults.properties`. This is where a default configuration will live.
|
||||
- Usually, this loads default compilers from their usual paths on a normal installation
|
||||
(Check `etc/config/c++.defaults.properties` for an example)
|
||||
- Add a new file `etc/config/{language-key}.defaults.properties`. This is where a default configuration will live.
|
||||
|
||||
* Of important note, for both files, is to properly define `compilerType` property in the newly added compilers. This
|
||||
- Usually, this loads default compilers from their usual paths on a normal installation (Check
|
||||
`etc/config/c++.defaults.properties` for an example)
|
||||
|
||||
- Of important note, for both files, is to properly define `compilerType` property in the newly added compilers. This
|
||||
should equal the value returned by your `LanguageCompiler.key` function
|
||||
|
||||
* Running `make dev EXTRA_ARGS="--debug --language {language-key}"` to tell CE to only load your new language
|
||||
- Running `make dev EXTRA_ARGS="--debug --language {language-key}"` to tell CE to only load your new language
|
||||
|
||||
* You can check http://127.0.0.1:10240/api/compilers to be sure your language and compilers are there
|
||||
- You can check http://127.0.0.1:10240/api/compilers to be sure your language and compilers are there
|
||||
|
||||
* Make an installer in the [infra](https://github.com/compiler-explorer/infra) repository
|
||||
- Make an installer in the [infra](https://github.com/compiler-explorer/infra) repository
|
||||
|
||||
* Add your language files (`{language-key}.*.properties` and `lib/compilers/{language-key}.js`) to the list
|
||||
in `.github/labeler.yml`
|
||||
- Add your language files (`{language-key}.*.properties` and `lib/compilers/{language-key}.js`) to the list in
|
||||
`.github/labeler.yml`
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
# Adding a new library
|
||||
|
||||
This document explains how to add a new library to Compiler Explorer ("CE" from here on), first for a local instance, and
|
||||
then how to submit PRs to get it into the main CE site.
|
||||
This document explains how to add a new library to Compiler Explorer ("CE" from here on), first for a local instance,
|
||||
and then how to submit PRs to get it into the main CE site.
|
||||
|
||||
Note that most libraries are Header-only. This is the easiest form of library to support. If the library needs to be built,
|
||||
there are some caveats, best practices and good to knows. Consult the bottom of this page for details.
|
||||
Note that most libraries are Header-only. This is the easiest form of library to support. If the library needs to be
|
||||
built, there are some caveats, best practices and good to knows. Consult the bottom of this page for details.
|
||||
|
||||
## Configuration
|
||||
|
||||
Library configurations are part of the compiler's properties, which is done through the `etc/config/c++.*.properties` files
|
||||
(for C++, other languages follow the obvious pattern). The various named configuration files are used in different contexts:
|
||||
for example `etc/config/c++.local.properties` take priority over `etc/config/c++.defaults.properties`.
|
||||
The `local` version is ignored by git, so you can make your own personalised changes there.
|
||||
The live site uses the `etc/config/c++.amazon.properties` file.
|
||||
Library configurations are part of the compiler's properties, which is done through the `etc/config/c++.*.properties`
|
||||
files (for C++, other languages follow the obvious pattern). The various named configuration files are used in different
|
||||
contexts: for example `etc/config/c++.local.properties` take priority over `etc/config/c++.defaults.properties`. The
|
||||
`local` version is ignored by git, so you can make your own personalised changes there. The live site uses the
|
||||
`etc/config/c++.amazon.properties` file.
|
||||
|
||||
Within the file, configuration is a set of key and value pairs, separated by an `=`. Whitespace is _not_ trimmed.
|
||||
Lines starting with `#` are considered comments and not parsed.
|
||||
The list of libraries is set by the `libs` key and is a list of library identifiers, separated by colons.
|
||||
The identifier itself is not important, but must be unique to that library.
|
||||
Within the file, configuration is a set of key and value pairs, separated by an `=`. Whitespace is _not_ trimmed. Lines
|
||||
starting with `#` are considered comments and not parsed. The list of libraries is set by the `libs` key and is a list
|
||||
of library identifiers, separated by colons. The identifier itself is not important, but must be unique to that library.
|
||||
|
||||
An example configuration:
|
||||
|
||||
```
|
||||
```INI
|
||||
libs=kvasir:boost:rangesv3
|
||||
```
|
||||
|
||||
This says there are three libraries with identifiers `kvasir`, `boost` and `rangesv3`. CE will look for the key named
|
||||
`libs.ID.versions`, `libs.ID.name` and the optionals `libs.ID.url` & `libs.ID.description`. The `ID` is the identifier (The one we just set) of the library being looked up.
|
||||
The `name` key expects the human-readable name of the library (Note that you can use spaces here!).
|
||||
The `versions` key expects another list, akin to the libs key itself. This time, you have to define the available versions
|
||||
for each library.
|
||||
The `url` key expects an unescaped url, where users can go to learn more about the library (This is usually the project's homepage, or in its
|
||||
absence, the GitHub repo).
|
||||
The `description` key should be use as an extremely short description of the library. Usually used to spell the library's full name in cases where the `name` key is an acronym.
|
||||
`libs.ID.versions`, `libs.ID.name` and the optionals `libs.ID.url` & `libs.ID.description`. The `ID` is the identifier
|
||||
(The one we just set) of the library being looked up. The `name` key expects the human-readable name of the library
|
||||
(Note that you can use spaces here!). The `versions` key expects another list, akin to the libs key itself. This time,
|
||||
you have to define the available versions for each library. The `url` key expects an unescaped url, where users can go
|
||||
to learn more about the library (This is usually the project's homepage, or in its absence, the GitHub repo). The
|
||||
`description` key should be use as an extremely short description of the library. Usually used to spell the library's
|
||||
full name in cases where the `name` key is an acronym.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
```INI
|
||||
libs.kvasir.name=Kvasir::mpl
|
||||
libs.kvasir.versions=trunk
|
||||
libs.kvasir.url=https://github.com/kvasir-io/Kvasir
|
||||
@@ -51,13 +50,14 @@ libs.rangesv3.versions=trunk:0110
|
||||
libs.rangesv3.url=https://github.com/ericniebler/range-v3
|
||||
```
|
||||
|
||||
Now, for each declared version, CE will look for a `version` key, a human-readable string representing the corresponding version,
|
||||
and `path`, a list consisting of the paths separated by colon `:` (or semicolon `;` on Windows) to add to the inclusion path of the library.
|
||||
Optionally, you can provide a `libpath`, a list consisting of paths to add to your linker path.
|
||||
Now, for each declared version, CE will look for a `version` key, a human-readable string representing the corresponding
|
||||
version, and `path`, a list consisting of the paths separated by colon `:` (or semicolon `;` on Windows) to add to the
|
||||
inclusion path of the library. Optionally, you can provide a `libpath`, a list consisting of paths to add to your linker
|
||||
path.
|
||||
|
||||
This would leave us with:
|
||||
|
||||
```
|
||||
```INI
|
||||
libs.boost.name=Boost
|
||||
libs.boost.versions=175:176
|
||||
libs.boost.url=http://www.boost.org/
|
||||
@@ -90,49 +90,51 @@ libs.rangesv3.versions.0110.version=0.11.0
|
||||
libs.rangesv3.versions.0110.path=/opt/compiler-explorer/libs/rangesv3/0.11.0/include
|
||||
```
|
||||
|
||||
If you're adding a new library and plan to submit a PR for it, please make sure that its identifier appears in alphabetical order
|
||||
in the `libs` property. You should also put all its related configuration in that same order when defining it.
|
||||
This helps us keep the config manageable until further automation can be implemented. Thank you!
|
||||
|
||||
If you're adding a new library and plan to submit a PR for it, please make sure that its identifier appears in
|
||||
alphabetical order in the `libs` property. You should also put all its related configuration in that same order when
|
||||
defining it. This helps us keep the config manageable until further automation can be implemented. Thank you!
|
||||
|
||||
## Setting default libraries
|
||||
|
||||
The `defaultLibs` key specifies an array of libs/versions which will be enabled by default when the user visits the site.
|
||||
The expected format is:
|
||||
```
|
||||
The `defaultLibs` key specifies an array of libs/versions which will be enabled by default when the user visits the
|
||||
site. The expected format is:
|
||||
|
||||
```INI
|
||||
defaultLibs=libKeyA.version:libKeyB.version:libKeyC.version
|
||||
```
|
||||
Where `libKey` is the key of the library to be enabled by default, and `version` is the version key to load.
|
||||
Note that the site won't complain if invalid key/version pairs are set. Repeating a lib key more than once is supported.
|
||||
|
||||
Where `libKey` is the key of the library to be enabled by default, and `version` is the version key to load. Note that
|
||||
the site won't complain if invalid key/version pairs are set. Repeating a lib key more than once is supported.
|
||||
|
||||
## Adding a new library locally
|
||||
|
||||
It should be pretty straightforward to add a library of your own. Create a `etc/config/c++.local.properties` file and override the
|
||||
`libs` list to include your own library, and its configuration.
|
||||
It should be pretty straightforward to add a library of your own. Create a `etc/config/c++.local.properties` file and
|
||||
override the `libs` list to include your own library, and its configuration.
|
||||
|
||||
Once you've done that, running `make` should pick up the configuration, and you should be able to use them from the library dropdown
|
||||
on the compiler view (The book icon)
|
||||
Once you've done that, running `make` should pick up the configuration, and you should be able to use them from the
|
||||
library dropdown on the compiler view (The book icon)
|
||||
|
||||
If you're looking to add libraries for another language, obviously create the `etc/config/LANG.local.properties` in
|
||||
the above steps, and run with `make EXTRA_ARGS='--language LANG` (e.g. `etc/config/rust.local.properties` and
|
||||
If you're looking to add libraries for another language, obviously create the `etc/config/LANG.local.properties` in the
|
||||
above steps, and run with `make EXTRA_ARGS='--language LANG` (e.g. `etc/config/rust.local.properties` and
|
||||
`make EXTRA_ARGS='--language Rust'`).
|
||||
|
||||
Test locally, and for many compilers that's probably all you need to do. Some compilers might need a few options tweaks (like
|
||||
the intel asm setting, or the version flag). For a completely new compiler, you might need to define a whole new `compilerType`.
|
||||
Doing so is beyond this document's scope at present, but take a look inside `lib/compilers/` to get some idea what might need
|
||||
to be done.
|
||||
Test locally, and for many compilers that's probably all you need to do. Some compilers might need a few options tweaks
|
||||
(like the intel asm setting, or the version flag). For a completely new compiler, you might need to define a whole new
|
||||
`compilerType`. Doing so is beyond this document's scope at present, but take a look inside `lib/compilers/` to get some
|
||||
idea what might need to be done.
|
||||
|
||||
## Adding a new library to the live site
|
||||
|
||||
On the main CE website, libraries are installed into a `/opt/compiler-explorer/` directory by a set of scripts in the sister
|
||||
GitHub repo: https://github.com/compiler-explorer/infra
|
||||
On the main CE website, libraries are installed into a `/opt/compiler-explorer/` directory by a set of scripts in the
|
||||
sister GitHub repo: https://github.com/compiler-explorer/infra
|
||||
|
||||
In the `bin/yaml` directory in that repository are a set of yaml files that configure the download, install and building of the libraries.
|
||||
If you wish to test locally, and can create a `/opt/compiler-explorer` directory on your machine which is readable and writable by your
|
||||
current user, then you can run the scripts directly.
|
||||
In the `bin/yaml` directory in that repository are a set of yaml files that configure the download, install and building
|
||||
of the libraries. If you wish to test locally, and can create a `/opt/compiler-explorer` directory on your machine which
|
||||
is readable and writable by your current user, then you can run the scripts directly.
|
||||
|
||||
Example of configuring a library that is header only:
|
||||
```
|
||||
|
||||
```yaml
|
||||
sol2:
|
||||
type: github
|
||||
method: clone_branch
|
||||
@@ -144,7 +146,8 @@ Example of configuring a library that is header only:
|
||||
```
|
||||
|
||||
Example of configuring a library that is linked against:
|
||||
```
|
||||
|
||||
```yaml
|
||||
catch2:
|
||||
type: github
|
||||
repo: catchorg/Catch2
|
||||
@@ -157,39 +160,54 @@ Example of configuring a library that is linked against:
|
||||
- 3.0.0-preview2
|
||||
```
|
||||
|
||||
If your library fits nicely into the harness then it should be straightforward to add it there. Anything more complex: contact the CE
|
||||
authors for more help.
|
||||
If your library fits nicely into the harness then it should be straightforward to add it there. Anything more complex:
|
||||
contact the CE authors for more help.
|
||||
|
||||
Remember to also add the library dependencies following the same steps. It's on you if those should also appear in the UI.
|
||||
Remember to also add the library dependencies following the same steps. It's on you if those should also appear in the
|
||||
UI.
|
||||
|
||||
## Adding compilers with limited library support
|
||||
|
||||
If you have libraries that you don't want to be shown with a compiler, you can limit the libraries per compiler. By default, all libraries are visible for all compilers.
|
||||
If you have libraries that you don't want to be shown with a compiler, you can limit the libraries per compiler. By
|
||||
default, all libraries are visible for all compilers.
|
||||
|
||||
For example if you only want all versions of fmt, and version 0.3.0 of Ranges, you can do the following:
|
||||
```
|
||||
|
||||
```ini
|
||||
compiler.mycompiler.supportedLibraries=fmt:rangesv3.030
|
||||
```
|
||||
|
||||
## Putting it all together
|
||||
|
||||
Hopefully that's enough to get an idea. The ideal case should be a pull request to add a couple of
|
||||
lines to the `infra` repository to install the library, and a pull request to add a few lines to the `LANG.amazon.properties`
|
||||
file in this repository.
|
||||
Hopefully that's enough to get an idea. The ideal case should be a pull request to add a couple of lines to the `infra`
|
||||
repository to install the library, and a pull request to add a few lines to the `LANG.amazon.properties` file in this
|
||||
repository.
|
||||
|
||||
If you feel like we could improve this document in any way, please contact us. We'd love to hear from you!
|
||||
|
||||
|
||||
# Adding a library that needs to be compiled to .a or .so binaries
|
||||
|
||||
Supporting library binaries are a complicated matter.
|
||||
|
||||
For "C" shared libraries is relatively easy, is mostly a "solved problem", and the most common way of connecting software and libraries together. OpenSSL has .so's to link against for x86-64 and x86. However, we currently do not offer any other platforms, and it gets a lot harder if we tried to support that. Not to mention we currently do not have hardware in the cloud for other platforms to actually execute your code.
|
||||
For "C" shared libraries is relatively easy, is mostly a "solved problem", and the most common way of connecting
|
||||
software and libraries together. OpenSSL has .so's to link against for x86-64 and x86. However, we currently do not
|
||||
offer any other platforms, and it gets a lot harder if we tried to support that. Not to mention we currently do not have
|
||||
hardware in the cloud for other platforms to actually execute your code.
|
||||
|
||||
For C++ libraries, static or shared, there is no standard or common way of building libraries. To be sure linking will work, we have to rebuild the libraries for every compiler we support. We try to support at least x86-64, x86 and if that's not possible - the default target of the compiler. For all llvm/clang based compilers, we also try to build the libraries for libc++, just to be sure that doesn't give any runtime issues.
|
||||
For C++ libraries, static or shared, there is no standard or common way of building libraries. To be sure linking will
|
||||
work, we have to rebuild the libraries for every compiler we support. We try to support at least x86-64, x86 and if
|
||||
that's not possible - the default target of the compiler. For all llvm/clang based compilers, we also try to build the
|
||||
libraries for libc++, just to be sure that doesn't give any runtime issues.
|
||||
|
||||
There are also some specific compiler flags that cause ABI incompatibility, but we're still looking for common cases; if you have any use-cases of flags that causes linking or runtime errors, please let us know.
|
||||
There are also some specific compiler flags that cause ABI incompatibility, but we're still looking for common cases; if
|
||||
you have any use-cases of flags that causes linking or runtime errors, please let us know.
|
||||
|
||||
For us to have the possibility of crosscompiling with multiple compilers, it's recommended to be able to build with CMake. CMake by default has support to provide different flags during compilation. Makefiles can provide ways for doing the same, but often they have variables and flags that cannot be changed. If you're a library developer, please take into account that we will need ways to set at least CC, CXX, CXXFLAGS. Be also aware that we will probably supply -Wl-rpath's and/or -L to ensure that the library knows where to find their dependencies.
|
||||
For us to have the possibility of crosscompiling with multiple compilers, it's recommended to be able to build with
|
||||
CMake. CMake by default has support to provide different flags during compilation. Makefiles can provide ways for doing
|
||||
the same, but often they have variables and flags that cannot be changed. If you're a library developer, please take
|
||||
into account that we will need ways to set at least CC, CXX, CXXFLAGS. Be also aware that we will probably supply
|
||||
-Wl-rpath's and/or -L to ensure that the library knows where to find their dependencies.
|
||||
|
||||
Because of the amount of combinations we need to produce, only the later tagged versions of most libraries have priority in providing builds for. Daily trunk/master versions are out as well, until we figure out a way to efficiently provide builds for this.
|
||||
Because of the amount of combinations we need to produce, only the later tagged versions of most libraries have priority
|
||||
in providing builds for. Daily trunk/master versions are out as well, until we figure out a way to efficiently provide
|
||||
builds for this.
|
||||
|
||||
@@ -4,7 +4,7 @@ Tools are a way to execute something on your code or the output of a compilation
|
||||
|
||||
Adding tools requires adding configuration to a properties file for a specific language:
|
||||
|
||||
```yaml
|
||||
```INI
|
||||
tools=rewritecpp
|
||||
|
||||
tools.rewritecpp.name=rewritecpp
|
||||
@@ -19,25 +19,31 @@ tools.rewritecpp.options=--a
|
||||
tools.rewritecpp.args=--b
|
||||
```
|
||||
|
||||
The `name` and `exe` are what they say they are, this is the display name for within CE and the tool executable that will be used.
|
||||
The `name` and `exe` are what they say they are, this is the display name for within CE and the tool executable that
|
||||
will be used.
|
||||
|
||||
The `type` of the tool represents the stage in which the tool will run:
|
||||
* independent - when running a tool on sourcecode
|
||||
* postcompilation - when running a tool on the assembly or a binary
|
||||
|
||||
The `exclude` property is to indicate which compilers are proven to be incompatible with the tool.
|
||||
You can supply the full id of the compiler, or a partial id (for example 'arm' to exclude all arm compilers).
|
||||
- independent - when running a tool on sourcecode
|
||||
- postcompilation - when running a tool on the assembly or a binary
|
||||
|
||||
The `class` of the tool says which javascript class is needed to run the tool and process its output. The folder _lib/tooling_ is used for these classes.
|
||||
The `exclude` property is to indicate which compilers are proven to be incompatible with the tool. You can supply the
|
||||
full id of the compiler, or a partial id (for example 'arm' to exclude all arm compilers).
|
||||
|
||||
The `class` of the tool says which javascript class is needed to run the tool and process its output. The folder
|
||||
_lib/tooling_ is used for these classes.
|
||||
|
||||
Should you want to deviate from the standard behaviour of `base-tool`, which runs the tool on the sourcecode filename,
|
||||
you should add a new class that extends from `base-tool`.
|
||||
|
||||
The `stdinHint` is there to show the user a hint as to what the stdin field is used for in the tool. To disable stdin you can use _disabled_ here.
|
||||
The `stdinHint` is there to show the user a hint as to what the stdin field is used for in the tool. To disable stdin
|
||||
you can use _disabled_ here.
|
||||
|
||||
The `monacoStdin` option makes the stdin editor a separate pane containing a monaco editor. This is useful when a tool has complex input spanning multiple lines and it's more friendly to indent it.
|
||||
The `monacoStdin` option makes the stdin editor a separate pane containing a monaco editor. This is useful when a tool
|
||||
has complex input spanning multiple lines and it's more friendly to indent it.
|
||||
|
||||
The `languageId` can be used to highlight the output of the tool according to a language known within CE. For example `cppp` will highlight c++ output. Leaving `languageId` empty will use the terminal-like output.
|
||||
The `languageId` can be used to highlight the output of the tool according to a language known within CE. For example
|
||||
`cppp` will highlight c++ output. Leaving `languageId` empty will use the terminal-like output.
|
||||
|
||||
The `options` field is useful for tools that derive `base-tool` and want to add non-user configurable options to it
|
||||
|
||||
@@ -45,7 +51,8 @@ The `args` field is shown and editable by the user in the UI, and passed automat
|
||||
|
||||
# compilationInfo
|
||||
|
||||
When writing a special class for a tool, you will probably need the `compilationInfo` parameter to pass the correct parameters to the tool.
|
||||
When writing a special class for a tool, you will probably need the `compilationInfo` parameter to pass the correct
|
||||
parameters to the tool.
|
||||
|
||||
The contents of `compilationInfo` varies slightly between the different `type`s of tools.
|
||||
|
||||
@@ -64,7 +71,8 @@ The contents of `compilationInfo` varies slightly between the different `type`s
|
||||
}
|
||||
```
|
||||
|
||||
The `filters` can be used to assert boundary conditions or adjust the tooling process based on the filters the user checked on or off.
|
||||
The `filters` can be used to assert boundary conditions or adjust the tooling process based on the filters the user
|
||||
checked on or off.
|
||||
|
||||
The `inputFilename` contains the path to the sourcecode stored on disk. The `source` contains the sourcecode as text.
|
||||
|
||||
@@ -72,7 +80,6 @@ The `dirPath` can be used to write extra files to disk which the tool might need
|
||||
|
||||
The `options` are the arguments the user gave for the compilation.
|
||||
|
||||
|
||||
## compilationInfo for postcompilation tools
|
||||
|
||||
```json
|
||||
@@ -97,7 +104,8 @@ The `options` are the arguments the user gave for the compilation.
|
||||
|
||||
`code` indicates the exitcode of the compilation. Usually, 0 means everything's ok.
|
||||
|
||||
`asm` contains the returned assembly. This is the same assembly that is shown within compiler-explorer, including extra information like for which sourcecode line the assembly was generated.
|
||||
`asm` contains the returned assembly. This is the same assembly that is shown within compiler-explorer, including extra
|
||||
information like for which sourcecode line the assembly was generated.
|
||||
|
||||
`stderr` and `stdout` contain the different outputs from the compilation process.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Adding Assembly Documentation for a new instruction set
|
||||
|
||||
This document explains how to add assembly documentation for a new instruction set to Compiler Explorer
|
||||
("CE" from here on).
|
||||
This document explains how to add assembly documentation for a new instruction set to Compiler Explorer ("CE" from here
|
||||
on).
|
||||
|
||||
If you were not already aware, CE has both quick-tip and more thorough assembly instruction documentation available for
|
||||
a couple instruction sets (currently JVM bytecode, amd64 and arm32). The feature is demonstrated in the gif below.
|
||||
@@ -12,8 +12,8 @@ To add a new assembly documentation handler, you need to perform the following s
|
||||
|
||||
## 1. Find a data source
|
||||
|
||||
First you need to find a data source to get our instruction info from. While it is possible to write down
|
||||
information about every single instruction for an instruction set, it's far from maintainable, and it is a lot of work.
|
||||
First you need to find a data source to get our instruction info from. While it is possible to write down information
|
||||
about every single instruction for an instruction set, it's far from maintainable, and it is a lot of work.
|
||||
|
||||
Existing assembly documentation handlers use some sort of established documentation. The arm32 handler uses the
|
||||
developer.arm.com website and the JVM bytecode handler uses Oracle's documentation.
|
||||
@@ -30,8 +30,8 @@ well. If you need inspiration on how to write this tool, you can look at the `do
|
||||
`/etc/scripts/docenizers` in the source control tree.
|
||||
|
||||
CE expects the tool to output the file into the `/lib/asm-docs/generated/` folder with a name following the existing
|
||||
convention. Each case in the switch should return a piece of formatted HTML to insert into the popup, a tooltip text
|
||||
for the on-hover tooltip and a URL to external documentation.
|
||||
convention. Each case in the switch should return a piece of formatted HTML to insert into the popup, a tooltip text for
|
||||
the on-hover tooltip and a URL to external documentation.
|
||||
|
||||
```js
|
||||
case "CALL":
|
||||
@@ -48,9 +48,9 @@ Once your tool has generated the JavaScript file, you want to connect it to CE.
|
||||
in the `/lib/asm-docs` directory which is adjacent to your newly generated JavaScript file.
|
||||
|
||||
First you want to add a new file named after your instruction set which exports a class extending the
|
||||
`BaseAssemblyDocumentationProvider` class. The class should implement the `getInstructionInformation` method which
|
||||
in most cases, delegates to your generated JavaScript. Instruction sets like Arm32 have use code to tweak the output
|
||||
if needed.
|
||||
`BaseAssemblyDocumentationProvider` class. The class should implement the `getInstructionInformation` method which in
|
||||
most cases, delegates to your generated JavaScript. Instruction sets like Arm32 have use code to tweak the output if
|
||||
needed.
|
||||
|
||||
This method is expected to take the instruction opcode in full uppercase and either return the associated data or null
|
||||
if not found.
|
||||
@@ -61,7 +61,9 @@ import { BaseAssemblyDocumentationProvider } from './base';
|
||||
|
||||
export class JavaDocumentationProvider extends BaseAssemblyDocumentationProvider {
|
||||
// Return the instruction set name
|
||||
public static get key() { return 'java'; }
|
||||
public static get key() {
|
||||
return 'java';
|
||||
}
|
||||
public override getInstructionInformation(instruction: string): AssemblyInstructionInfo | null {
|
||||
return getAsmOpcode(instruction) || null;
|
||||
}
|
||||
@@ -70,6 +72,7 @@ export class JavaDocumentationProvider extends BaseAssemblyDocumentationProvider
|
||||
|
||||
Finally we want to tell CE that the new documentation provider exists. This is done by re-exporting the class inside
|
||||
`/lib/asm-docs/_all.ts`. Please keep the exports here in alphabetic order.
|
||||
|
||||
## 4. Testing
|
||||
|
||||
Testing new assembly documentation providers is really easy. It is just a matter of modifying the `TEST_MATRIX` variable
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
This is an overview of what building and adding a compiler to the site looks like, using GCC as an example,
|
||||
but note that the process is similar for all other types of compilers.
|
||||
This is an overview of what building and adding a compiler to the site looks like, using GCC as an example, but note
|
||||
that the process is similar for all other types of compilers.
|
||||
|
||||
* Build GCC versions with the relevant magic.
|
||||
We build all our own GCCs using Docker from [this repo](https://github.com/compiler-explorer/gcc-builder)
|
||||
* For non-trunk builds we manually run the docker image.
|
||||
For trunk dailies we have a [cron job](https://github.com/compiler-explorer/infra/blob/main/crontab.admin#L8)
|
||||
that runs a [script](https://github.com/compiler-explorer/infra/blob/main/admin-daily-builds.sh) to build them.
|
||||
* Built tarballs are uploaded to S3,
|
||||
and installed by our [custom tool](https://github.com/compiler-explorer/infra/blob/main/bin/lib/ce_install.py)
|
||||
from a [YAML configuration file](https://github.com/compiler-explorer/infra/blob/main/bin/yaml/cpp.yaml)
|
||||
* The installation puts compilers on a shared NFS drive at `/opt/compiler-explorer/gcc-some-version/`
|
||||
* We then configure CE to look for the compiler
|
||||
- Build GCC versions with the relevant magic. We build all our own GCCs using Docker from
|
||||
[this repo](https://github.com/compiler-explorer/gcc-builder)
|
||||
- For non-trunk builds we manually run the docker image. For trunk dailies we have a
|
||||
[cron job](https://github.com/compiler-explorer/infra/blob/main/crontab.admin#L8) that runs a
|
||||
[script](https://github.com/compiler-explorer/infra/blob/main/admin-daily-builds.sh) to build them.
|
||||
- Built tarballs are uploaded to S3, and installed by our
|
||||
[custom tool](https://github.com/compiler-explorer/infra/blob/main/bin/lib/ce_install.py) from a
|
||||
[YAML configuration file](https://github.com/compiler-explorer/infra/blob/main/bin/yaml/cpp.yaml)
|
||||
- The installation puts compilers on a shared NFS drive at `/opt/compiler-explorer/gcc-some-version/`
|
||||
- We then configure CE to look for the compiler
|
||||
[here](https://github.com/compiler-explorer/compiler-explorer/blob/main/etc/config/c%2B%2B.amazon.properties#L9).
|
||||
* If we need to customise the way we execute the compiler and/or display the results,
|
||||
then we can change the "[driver](https://github.com/compiler-explorer/compiler-explorer/tree/main/lib/compilers)"
|
||||
for the compiler. Usually we can just override a few aspects of the driver,
|
||||
relying on the defaults from the [base driver](https://github.com/compiler-explorer/compiler-explorer/blob/main/lib/base-compiler.js).
|
||||
* Any UI changes are a bit more work.
|
||||
- If we need to customise the way we execute the compiler and/or display the results, then we can change the
|
||||
"[driver](https://github.com/compiler-explorer/compiler-explorer/tree/main/lib/compilers)" for the compiler. Usually
|
||||
we can just override a few aspects of the driver, relying on the defaults from the
|
||||
[base driver](https://github.com/compiler-explorer/compiler-explorer/blob/main/lib/base-compiler.js).
|
||||
- Any UI changes are a bit more work.
|
||||
|
||||
More info still in [Adding a Compiler](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/AddingACompiler.md),
|
||||
and if you can bear listening to Matt, here's [a talk](https://www.youtube.com/watch?v=kIoZDUd5DKw)
|
||||
about some behind the scenes stuff, with [slides online](https://www.youtube.com/watch?v=kIoZDUd5DKw).
|
||||
More info still in
|
||||
[Adding a Compiler](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/AddingACompiler.md), and if
|
||||
you can bear listening to Matt, here's [a talk](https://www.youtube.com/watch?v=kIoZDUd5DKw) about some behind the
|
||||
scenes stuff, with [slides online](https://www.youtube.com/watch?v=kIoZDUd5DKw).
|
||||
|
||||
@@ -1,33 +1,53 @@
|
||||
# Running EWARM compiler on windows host
|
||||
This document will show a little insight on how to get the IAR ARM compiler working with compiler explorer *(Some line highlighting is broken as EWAVR is different from EWARM)*
|
||||
|
||||
This document will show a little insight on how to get the IAR ARM compiler working with compiler explorer _(Some line
|
||||
highlighting is broken as EWAVR is different from EWARM)_
|
||||
|
||||
# Prerequisites
|
||||
|
||||
To run the IAR ARM compiler you will need:
|
||||
|
||||
- A valid installation of the IAR ARM compiler. [EWARM](https://www.iar.com/iar-embedded-workbench/#!?architecture=Arm) has a free 30-day trial on their website
|
||||
- Technically you need a license as well to run the compiler, however you can get by with the 30-day free trial, as you will be able to run the compiler for 30 days for free
|
||||
- A valid installation of the IAR ARM compiler. [EWARM](https://www.iar.com/iar-embedded-workbench/#!?architecture=Arm)
|
||||
has a free 30-day trial on their website
|
||||
- Technically you need a license as well to run the compiler, however you can get by with the 30-day free trial, as you
|
||||
will be able to run the compiler for 30 days for free
|
||||
- MinGW C++ toolchain for `c++filt` and `objdump`
|
||||
|
||||
## IAR ARM Compiler
|
||||
This compiler will be installed along with the IAR Embedded Workbench (EWARM). Default installation location is under `C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin\iccarm.exe`
|
||||
|
||||
This compiler will be installed along with the IAR Embedded Workbench (EWARM). Default installation location is under
|
||||
`C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin\iccarm.exe`
|
||||
|
||||
## MinGW C++ Toolchain
|
||||
We need to install this toolchain through [MSYS2](https://www.msys2.org/), as it contains `c++filt` and `objdump`, which are needed to demangle the assembly
|
||||
|
||||
We need to install this toolchain through [MSYS2](https://www.msys2.org/), as it contains `c++filt` and `objdump`, which
|
||||
are needed to demangle the assembly
|
||||
|
||||
- First download [MSYS2](https://www.msys2.org/)
|
||||
- Install it and run it, entering the first command `pacman -Syuu`, this command will update all the internal MSYS2 modules to their latest version. This command will also update all installed modules, such as the toolchain if it was installed.
|
||||
- When you run the command for the first time, it will exit the bash console. You have to open it again and run the same command again `pacman -Syuu`
|
||||
- After the second time, everything will be up to date. To install the MinGW toolchain, run `pacman -S mingw-w64-x86_64-toolchain`. This will install the toolchain to your MSYS2 default installation path under `C:\msys64\mingw64\bin`
|
||||
- Install it and run it, entering the first command `pacman -Syuu`, this command will update all the internal MSYS2
|
||||
modules to their latest version. This command will also update all installed modules, such as the toolchain if it was
|
||||
installed.
|
||||
- When you run the command for the first time, it will exit the bash console. You have to open it again and run the same
|
||||
command again `pacman -Syuu`
|
||||
- After the second time, everything will be up to date. To install the MinGW toolchain, run
|
||||
`pacman -S mingw-w64-x86_64-toolchain`. This will install the toolchain to your MSYS2 default installation path under
|
||||
`C:\msys64\mingw64\bin`
|
||||
- Add this path `C:\msys64\mingw64\bin` to windows global `PATH`
|
||||
- Test by running `c++filt --help` from windows command prompt, if everything is set up correctly, then you should see all the command line options for c++filt
|
||||
- Test by running `c++filt --help` from windows command prompt, if everything is set up correctly, then you should see
|
||||
all the command line options for c++filt
|
||||
|
||||
# Setup and Configuration
|
||||
|
||||
## Running compiler explorer on Windows
|
||||
Refer to the [readme](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/WindowsNative.md) on running Native on Windows for general setup of Compiler Explorer and other compilers.
|
||||
|
||||
Refer to the [readme](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/WindowsNative.md) on running
|
||||
Native on Windows for general setup of Compiler Explorer and other compilers.
|
||||
|
||||
## Setting up c++.local.properties
|
||||
The next step is to create a `c++.local.properties` file under `etc/config` folder.
|
||||
The next step is going to be different for everyone, as you can choose what compiler options you pass to the compiler and so on, but im going to paste my template here, and you can just modify, what you need
|
||||
|
||||
The next step is to create a `c++.local.properties` file under `etc/config` folder. The next step is going to be
|
||||
different for everyone, as you can choose what compiler options you pass to the compiler and so on, but im going to
|
||||
paste my template here, and you can just modify, what you need
|
||||
|
||||
```
|
||||
# Default settings for C++
|
||||
@@ -55,8 +75,11 @@ needsMulti=false
|
||||
stubRe=\bmain\b
|
||||
stubText=int main(void){return 0;/*stub provided by Compiler Explorer*/}
|
||||
```
|
||||
**It's important to note that the `compiler.iar8.32.4.compilerType` field is set to `ewarm` this will be the custom compiler key later on**
|
||||
|
||||
**It's important to note that the `compiler.iar8.32.4.compilerType` field is set to `ewarm` this will be the custom
|
||||
compiler key later on**
|
||||
|
||||
## Running Compiler Explorer
|
||||
|
||||
You should be able to just `cd` into the compiler explorer repository and run `npm start`. After that just head on to [localhost:10240](http://localhost:10240)
|
||||
You should be able to just `cd` into the compiler explorer repository and run `npm start`. After that just head on to
|
||||
[localhost:10240](http://localhost:10240)
|
||||
|
||||
@@ -3,26 +3,36 @@
|
||||
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`
|
||||
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.
|
||||
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:
|
||||
|
||||
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
|
||||
@@ -33,11 +43,13 @@ $ WINEARCH=win32 winecfg
|
||||
```
|
||||
|
||||
## Setup and Configuration
|
||||
|
||||
### Running locally on a Windows workstation or a windows server
|
||||
Refer to the readme on running [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.
|
||||
|
||||
Refer to the readme on running [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`
|
||||
@@ -45,15 +57,18 @@ The following properties are the ones that need to be set in addition to the typ
|
||||
- `supportsDemangler=false`
|
||||
|
||||
### Running on a linux server using docker
|
||||
|
||||
#### Step 1: provide configuration files, compilers, and libraries
|
||||
*If you are more experienced with docker this can be done with a volume, but I just use a local folder on my server*
|
||||
|
||||
_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.
|
||||
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 installation folders from windows un-tarred there, as you can see from the layout.
|
||||
The EWAVR directories are just the archives of the installation folders from windows un-tarred there, as you can see
|
||||
from the layout.
|
||||
|
||||
```bash
|
||||
/opt/compiler_explorer/
|
||||
@@ -90,8 +105,10 @@ The EWAVR directories are just the archives of the installation folders from win
|
||||
```
|
||||
|
||||
#### 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:
|
||||
|
||||
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
|
||||
@@ -101,9 +118,11 @@ $ echo -e "#\!/bin/bash\nwine $IAR_ROOT/avr/bin/iccavr.exe\n" > $IAR_ROOT/avr/bi
|
||||
```
|
||||
|
||||
#### 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 license needs to be run once, at system startup to register with the license server,
|
||||
so that can be seen in the docker command. If you have multiple IAR versions, only one needs to be run, and it doesn't matter which one.
|
||||
|
||||
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 license
|
||||
needs to be run once, at system startup to register with the license server, so that can be seen in 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
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
Compiler Explorer and Privacy
|
||||
-----------------------------
|
||||
## Compiler Explorer and Privacy
|
||||
|
||||
*This is a summary of our Privacy policy, not a legal document, and might be incomplete.*
|
||||
_This is a summary of our Privacy policy, not a legal document, and might be incomplete._
|
||||
|
||||
*For the full Privacy policy, see `static/policies/privacy.html`, or visit https://godbolt.org/#privacy*
|
||||
_For the full Privacy policy, see `static/policies/privacy.html`, or visit https://godbolt.org/#privacy_
|
||||
|
||||
The main Compiler Explorer site (at https://godbolt.org/) has a cookie and privacy policy, and it's expected that any
|
||||
changes to the code are in compliance with those policies. It's worth taking a look at them if you're touching any area
|
||||
@@ -20,9 +19,9 @@ the sister site www.godbolt.ms and that data is covered by
|
||||
|
||||
Users have rights over the data they create: so in theory they could ask for any data stored on them to be removed. We
|
||||
have no way of tracking data (a short link, perhaps) back to an individual user, and when I asked some experts on this
|
||||
the consensus was that we're OK not to supply this. If, however, we ever have user attribution (e.g., we start
|
||||
having accounts), we need to support the user being able to close their account, and/or delete any data they created
|
||||
(e.g., short links). All this makes perfect sense and would probably be done anyway, as it seems useful!
|
||||
the consensus was that we're OK not to supply this. If, however, we ever have user attribution (e.g., we start having
|
||||
accounts), we need to support the user being able to close their account, and/or delete any data they created (e.g.,
|
||||
short links). All this makes perfect sense and would probably be done anyway, as it seems useful!
|
||||
|
||||
We anonymise IP addresses so there's no exact mapping back to an individual using an IP. Not that it's trivial to map an
|
||||
IP to a user anyway.
|
||||
@@ -37,10 +36,10 @@ is to not use the main Compiler Explorer but instead run their own local service
|
||||
|
||||
A very small group of people have administrator rights on the public Compiler Explorer. Those individuals can:
|
||||
|
||||
* Read the logs
|
||||
* Log in to the running Compiler Explorer compilation nodes
|
||||
* Access the S3 storage where caches and stored information may be kept
|
||||
* Access and modify the EFS storage where compilers are stored
|
||||
- Read the logs
|
||||
- Log in to the running Compiler Explorer compilation nodes
|
||||
- Access the S3 storage where caches and stored information may be kept
|
||||
- Access and modify the EFS storage where compilers are stored
|
||||
|
||||
In short, administrators can see everything that goes on. It is expected that administrators keep this deep
|
||||
responsibility in mind when performing actions on Compiler Explorer, and that they keep users' privacy at the forefront
|
||||
|
||||
@@ -1,41 +1,48 @@
|
||||
# How do I ?
|
||||
|
||||
This is a how-to guide for the user-interface presented by [Compiler Explorer](https://godbolt.org).
|
||||
This doesn't cover the details of how to set up or modify Compiler Explorer for your own needs.
|
||||
For that, please check the documents which already cover topics like:
|
||||
* [Adding a language](AddingALanguage.md)
|
||||
* [Adding a compiler](AddingACompiler.md)
|
||||
* [Adding a library](AddingALibrary.md)
|
||||
* [Adding a tool](AddingATool.md)
|
||||
* and many more at [compiler-explorer/docs](https://github.com/compiler-explorer/compiler-explorer/tree/main/docs)
|
||||
This is a how-to guide for the user-interface presented by [Compiler Explorer](https://godbolt.org). This doesn't cover
|
||||
the details of how to set up or modify Compiler Explorer for your own needs. For that, please check the documents which
|
||||
already cover topics like:
|
||||
|
||||
- [Adding a language](AddingALanguage.md)
|
||||
- [Adding a compiler](AddingACompiler.md)
|
||||
- [Adding a library](AddingALibrary.md)
|
||||
- [Adding a tool](AddingATool.md)
|
||||
- and many more at [compiler-explorer/docs](https://github.com/compiler-explorer/compiler-explorer/tree/main/docs)
|
||||
|
||||
Fast links:
|
||||
|
||||
- [How do I ?](#how-do-i-)
|
||||
- [Change the assembly syntax from Intel](#change-the-assembly-syntax-from-intel)
|
||||
- [Compare the time taken by compilation and networking](#compare-the-time-taken-by-compilation-and-networking)
|
||||
- [View intermediate information provided by the compilers](#view-intermediate-information-provided-by-the-compilers)
|
||||
|
||||
## Change the assembly syntax from Intel
|
||||
|
||||

|
||||
|
||||
The option to switch assembly from Intel to AT&T syntax is present in the `Output` option of each compiler.
|
||||
If enough space is not present, the option also presents itself as the gear symbol (⚙)
|
||||
The option to switch assembly from Intel to AT&T syntax is present in the `Output` option of each compiler. If enough
|
||||
space is not present, the option also presents itself as the gear symbol (⚙)
|
||||
|
||||
## Compare the time taken by compilation and networking
|
||||
|
||||

|
||||
|
||||
This is the symbol that looks like a bar graph (📊). If your compilations are taking long, you can use this to check the time taken by:
|
||||
* Networking, JavaScript, waiting for events, etc.
|
||||
* Checking the cache and retrieving from it on a cache-hit
|
||||
* Compilation (on force compilation or cache-miss)
|
||||
* Parsing the generated assembly before presenting it
|
||||
This is the symbol that looks like a bar graph (📊). If your compilations are taking long, you can use this to check the
|
||||
time taken by:
|
||||
|
||||
- Networking, JavaScript, waiting for events, etc.
|
||||
- Checking the cache and retrieving from it on a cache-hit
|
||||
- Compilation (on force compilation or cache-miss)
|
||||
- Parsing the generated assembly before presenting it
|
||||
|
||||
## View intermediate information provided by the compilers
|
||||

|
||||

|
||||
|
||||
Though both GCC and Clang create supplementary outputs along with assembly (shown by default),
|
||||
and an executable (created if an executor has been added), the exact nature of the outputs and their formats differ between the compilers.
|
||||
 
|
||||
|
||||
GCC allows the Tree, IPA, RTL and graph outputs, while Clang allows optimization, AST, IR and graph outputs.
|
||||
Some outputs (e.g. RTL or graph) also have a rich set of options in the UI to enable focussing on a particular function or compiler stage.
|
||||
Though both GCC and Clang create supplementary outputs along with assembly (shown by default), and an executable
|
||||
(created if an executor has been added), the exact nature of the outputs and their formats differ between the compilers.
|
||||
|
||||
GCC allows the Tree, IPA, RTL and graph outputs, while Clang allows optimization, AST, IR and graph outputs. Some
|
||||
outputs (e.g. RTL or graph) also have a rich set of options in the UI to enable focussing on a particular function or
|
||||
compiler stage.
|
||||
|
||||
@@ -9,8 +9,7 @@ This document is an attempt to capture thoughts on the future direction of Compi
|
||||
A number of the open issues are to add more languages, libraries and compilers. Continuing to make it easier for others
|
||||
to submit PRs to add new compilers is very important. This has improved, but not all compilers are installed using the
|
||||
new approach. There's documentation on [adding a compiler](AddingACompiler.md),
|
||||
[adding a new language](AddingALanguage.md)
|
||||
and [adding a library](AddingALibrary.md).
|
||||
[adding a new language](AddingALanguage.md) and [adding a library](AddingALibrary.md).
|
||||
|
||||
### Multiple file support
|
||||
|
||||
@@ -29,6 +28,7 @@ improve code quality (e.g. move to transpiling from Typescript or similar to giv
|
||||
easy to support existing code.
|
||||
|
||||
## Considerations
|
||||
|
||||
### Tensions
|
||||
|
||||
There's an inherent tension between the standalone, run-it-yourself version of CE and the scalable, AWS-backed CE
|
||||
@@ -50,19 +50,18 @@ that has been relaxed slightly to allow up to three company sponsor logos visibl
|
||||
|
||||
### 2021 goals
|
||||
|
||||
* **Login support**. Support logging in to the site with GitHub, Google, etc. We will _never_ force you to log in for
|
||||
- **Login support**. Support logging in to the site with GitHub, Google, etc. We will _never_ force you to log in for
|
||||
basic features, and of course will update the Privacy Policy. I won't be selling anything to do with user info etc,
|
||||
either: Logging in will be purely used to make _your_ life easier and allow you to manage things like shared settings
|
||||
and configuration, listing short URLs you've created (and potentially being able to remove them); and _maybe_ being
|
||||
able to make user-named short URLs (e.g., "godbolt.org/u/mattgodbolt/ctad-example"). This goal is a personal pet
|
||||
project of [Matt's](http://github.com/mattgodbolt/).
|
||||
* **Multi-file support**. Multiple file compilation units to open the door to seeing LTO and maybe modules. This may
|
||||
- **Multi-file support**. Multiple file compilation units to open the door to seeing LTO and maybe modules. This may
|
||||
include being able to use a `CMake` file to build things.
|
||||
* **Modernising the codebase**. Moving the codebase to TypeScript, or something similar that will allow us to worry less
|
||||
- **Modernising the codebase**. Moving the codebase to TypeScript, or something similar that will allow us to worry less
|
||||
about differences between front-end and back-end code (old Javascript versions), and help us attract more people to
|
||||
the project.
|
||||
* **More compilers and libraries**. Plus finishing off the last stragglers of installation.
|
||||
|
||||
- **More compilers and libraries**. Plus finishing off the last stragglers of installation.
|
||||
|
||||
### Prior years' goals
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Sponsorship
|
||||
|
||||
Compiler Explorer is funded by sponsors: mostly individuals through Patreon, GitHub sponsors and PayPal one-off payments.
|
||||
There is potential for corporate sponsorship; though extremely limited due to the goal of making Compiler Explorer a mostly ad-free experience.
|
||||
Compiler Explorer is funded by sponsors: mostly individuals through Patreon, GitHub sponsors and PayPal one-off
|
||||
payments. There is potential for corporate sponsorship; though extremely limited due to the goal of making Compiler
|
||||
Explorer a mostly ad-free experience.
|
||||
|
||||
Corporate sponsorship requests should be directed to [Matt](mailto:matt@godbolt.org), who has sole discretion on what kinds of sponsorship is appropriate.
|
||||
Corporate sponsorship requests should be directed to [Matt](mailto:matt@godbolt.org), who has sole discretion on what
|
||||
kinds of sponsorship is appropriate.
|
||||
|
||||
## The sponsors.yaml format
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Using Systemd socket based activation to start Compiler Explorer
|
||||
|
||||
This document gives a short overview of how to use Systemd to automatically start Compiler Explorer when the web-interface is accessed.
|
||||
This document gives a short overview of how to use Systemd to automatically start Compiler Explorer when the
|
||||
web-interface is accessed.
|
||||
|
||||
You'll need to create two files in `/etc/systemd/system/`:
|
||||
|
||||
compiler-explorer.socket:
|
||||
|
||||
```
|
||||
[Socket]
|
||||
ListenStream=10240
|
||||
@@ -13,8 +15,8 @@ ListenStream=10240
|
||||
WantedBy=sockets.target
|
||||
```
|
||||
|
||||
|
||||
compiler-explorer.service:
|
||||
|
||||
```
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -4,35 +4,24 @@ Contact: [Nicole Mazzuca](https://github.com/ubsan)
|
||||
|
||||
## Basic Setup
|
||||
|
||||
The setup on Windows should be fairly trivial:
|
||||
the only prerequisite is node.
|
||||
If you haven't yet installed node yet, you can grab it from
|
||||
[here](https://nodejs.org/en/);
|
||||
get the Windows LTS release.
|
||||
The setup on Windows should be fairly trivial: the only prerequisite is node. If you haven't yet installed node yet, you
|
||||
can grab it from [here](https://nodejs.org/en/); get the Windows LTS release.
|
||||
|
||||
Once you've done this,
|
||||
and added `npm` to the path,
|
||||
run the following commands from any command line,
|
||||
in the directory you want the Compiler Explorer (from here on, CE)
|
||||
to live:
|
||||
Once you've done this, and added `npm` to the path, run the following commands from any command line, in the directory
|
||||
you want the Compiler Explorer (from here on, CE) to live:
|
||||
|
||||
```bat
|
||||
git clone https://github.com/compiler-explorer/compiler-explorer.git
|
||||
```
|
||||
|
||||
Then, we'll need to make a configuration file
|
||||
which points at your compilers and include directories.
|
||||
Copy [`docs\WindowsLocal.properties`](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/WindowsLocal.properties) to a new file,
|
||||
`etc\config\c++.local.properties`, and edit it,
|
||||
following the instructions in the comments.
|
||||
If you have any questions, please ping me on discord.
|
||||
|
||||
Then, we'll need to make a configuration file which points at your compilers and include directories. Copy
|
||||
[`docs\WindowsLocal.properties`](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/WindowsLocal.properties)
|
||||
to a new file, `etc\config\c++.local.properties`, and edit it, following the instructions in the comments. If you have
|
||||
any questions, please ping me on discord.
|
||||
|
||||
## Actually Running the danged thing
|
||||
|
||||
Once you've finished setting it up,
|
||||
you can `cd` into the `compiler-explorer` directory,
|
||||
then run
|
||||
Once you've finished setting it up, you can `cd` into the `compiler-explorer` directory, then run
|
||||
|
||||
```bat
|
||||
npm install
|
||||
@@ -54,13 +43,12 @@ info: =======================================
|
||||
|
||||
Now point your favorite web browser at http://localhost:10240, and you should be done!
|
||||
|
||||
You only have to run `npm install` the first time;
|
||||
every time after that, you should just be able to run `npm start`.
|
||||
You only have to run `npm install` the first time; every time after that, you should just be able to run `npm start`.
|
||||
|
||||
## Debugging using VSCode
|
||||
Similar to [WindowsSubsystemForLinux](WindowsSubsystemForLinux.md),
|
||||
the following is a `launch.json` that works for attaching to an instance of CE that was launched with `npm run-script debugger` (launches with the `--inspect` flag).
|
||||
|
||||
Similar to [WindowsSubsystemForLinux](WindowsSubsystemForLinux.md), the following is a `launch.json` that works for
|
||||
attaching to an instance of CE that was launched with `npm run-script debugger` (launches with the `--inspect` flag).
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -82,8 +70,9 @@ the following is a `launch.json` that works for attaching to an instance of CE t
|
||||
|
||||
Launch CE with `npm run-script debugger` to have node listen on port 9229.
|
||||
|
||||
Because this only attaches to the process, as opposed to launching the process, in order to debug startup code you need to attach while npm is starting up.
|
||||
The `debugger` script also enables `debug` logging level so debug print statements can be seen during the CE startup and run.
|
||||
Because this only attaches to the process, as opposed to launching the process, in order to debug startup code you need
|
||||
to attach while npm is starting up. The `debugger` script also enables `debug` logging level so debug print statements
|
||||
can be seen during the CE startup and run.
|
||||
|
||||
### Setting up binary mode and execution
|
||||
|
||||
@@ -91,36 +80,39 @@ To create executables with Visual C++, it's required to install the Windows SDK.
|
||||
|
||||
You can find the Windows 10 SDK [here](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk)
|
||||
|
||||
When you've installed the SDK, you'll need to set up the library and include paths in Compilers Explorer.
|
||||
Make sure that in the previously discussed c++.local.properties you have added at least:
|
||||
* to includePath
|
||||
- Windows Kits/10/include/*version*/ucrt
|
||||
- Windows Kits/10/include/*version*/shared
|
||||
- Windows Kits/10/include/*version*/um
|
||||
* to libPath (for the x64 compiler)
|
||||
- Windows Kits/10/Lib/*version*/um/x64
|
||||
- Windows Kits/10/Lib/*version*/ucrt/x64
|
||||
When you've installed the SDK, you'll need to set up the library and include paths in Compilers Explorer. Make sure that
|
||||
in the previously discussed c++.local.properties you have added at least:
|
||||
|
||||
- to includePath
|
||||
- Windows Kits/10/include/_version_/ucrt
|
||||
- Windows Kits/10/include/_version_/shared
|
||||
- Windows Kits/10/include/_version_/um
|
||||
- to libPath (for the x64 compiler)
|
||||
- Windows Kits/10/Lib/_version_/um/x64
|
||||
- Windows Kits/10/Lib/_version_/ucrt/x64
|
||||
- VC installation path/lib/x64
|
||||
|
||||
If needed, you can set in your properties file: ```supportsExecute=true```
|
||||
If needed, you can set in your properties file: `supportsExecute=true`
|
||||
|
||||
#### Binary mode
|
||||
|
||||
For binary mode, you will need a Windows version of Objdump. There are various
|
||||
versions of MingW available that will offer binutils including objdump.
|
||||
For binary mode, you will need a Windows version of Objdump. There are various versions of MingW available that will
|
||||
offer binutils including objdump.
|
||||
|
||||
The version of objdump that we have tested with is shipped with MingW-64,
|
||||
you can find it for download [here](https://sourceforge.net/projects/mingw-w64/)
|
||||
The version of objdump that we have tested with is shipped with MingW-64, you can find it for download
|
||||
[here](https://sourceforge.net/projects/mingw-w64/)
|
||||
|
||||
When you use the installer for MingW-64, make sure you select the right architecture during installation.
|
||||
|
||||
When you use the zipped version, after unzipping you will need to add the bin folder to your Windows PATHS environment variable.
|
||||
Be aware that this PATH needs to be added before any other folders that might contain an objdump. You cannot just point to the .exe as the objdumper without having the proper PATH set, it will not work.
|
||||
When you use the zipped version, after unzipping you will need to add the bin folder to your Windows PATHS environment
|
||||
variable. Be aware that this PATH needs to be added before any other folders that might contain an objdump. You cannot
|
||||
just point to the .exe as the objdumper without having the proper PATH set, it will not work.
|
||||
|
||||
When you have everything installed, you can add to your properties file the following:
|
||||
|
||||
```
|
||||
supportsBinary=true
|
||||
objdumper=objdump
|
||||
```
|
||||
|
||||
*Note that the 32 bit version of MingW does not support 64 bit binaries.*
|
||||
_Note that the 32 bit version of MingW does not support 64 bit binaries._
|
||||
|
||||
@@ -2,26 +2,43 @@
|
||||
|
||||
Contact: [@AndrewPardoe](https://github.com/AndrewPardoe)
|
||||
|
||||
The Compiler Explorer ("CE" from here on) runs quite well on the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/faq) ("WSL").
|
||||
Running on WSL enables Linux-based compilers to continue running natively while enabling Windows-based compilers to run in a real Windows environment.
|
||||
The Compiler Explorer ("CE" from here on) runs quite well on the
|
||||
[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/faq) ("WSL"). Running on WSL enables
|
||||
Linux-based compilers to continue running natively while enabling Windows-based compilers to run in a real Windows
|
||||
environment.
|
||||
|
||||
No special configuration is needed to run CE under WSL. Some configuration is required for hosting the Microsoft Visual C++ ("MSVC") compiler.
|
||||
Testing has mainly been done on the Ubuntu distro but any distro should work.
|
||||
No special configuration is needed to run CE under WSL. Some configuration is required for hosting the Microsoft Visual
|
||||
C++ ("MSVC") compiler. Testing has mainly been done on the Ubuntu distro but any distro should work.
|
||||
|
||||
## WSL/Windows interop and its limitations
|
||||
WSL offers rich interop with Windows processes. You can run any Windows executable, such as "`cl.exe`", from a bash shell. But this interop capability has some limitations.
|
||||
- Windows volumes: While Windows executables can be run from bash, they cannot see Linux volumes. Windows executables that need to read or write files must be run on a Windows volume. This means all MSVC compiles must be done in the Windows `%TEMP%` directory instead of in the `bash` environment's temp directory.
|
||||
- Path: The WSL path set in bash prepends the Windows path. While Linux filesystems support odd naming conventions such as spaces and parentheses, Windows' path uses these as a matter of course (e.g., `c:\Program Files (x86)`). Additionally, the Windows path delimiter is `\` instead of `/`, and it uses drive letters instead of mount points that are separated with a colon.
|
||||
- Path names: A Windows path of `c:\tmp` is normally referred to as `/mnt/c/tmp` in `bash`. However, users can customize their `drvfs` mount points. A tool is provided in newer Windows releases, `/bin/wslpath`, that will convert paths between systems. Code in CE currently does the conversion between the standard conventions using string manipulation.
|
||||
- Environment variables: While the Windows path is available in bash, Windows environment variables are not. CE uses `cmd.exe /c echo %TEMP%` to determine the Windows temporary directory.
|
||||
- Execution environment: The execution environment cannot currently be set when doing `childprocess.spawn`. This is a serious issue for the MSVC compiler, which is highly environment-dependent (e.g., `%INCLUDE%`, `%LIBPATH%`, etc.)
|
||||
|
||||
WSL offers rich interop with Windows processes. You can run any Windows executable, such as "`cl.exe`", from a bash
|
||||
shell. But this interop capability has some limitations.
|
||||
|
||||
- Windows volumes: While Windows executables can be run from bash, they cannot see Linux volumes. Windows executables
|
||||
that need to read or write files must be run on a Windows volume. This means all MSVC compiles must be done in the
|
||||
Windows `%TEMP%` directory instead of in the `bash` environment's temp directory.
|
||||
- Path: The WSL path set in bash prepends the Windows path. While Linux filesystems support odd naming conventions such
|
||||
as spaces and parentheses, Windows' path uses these as a matter of course (e.g., `c:\Program Files (x86)`).
|
||||
Additionally, the Windows path delimiter is `\` instead of `/`, and it uses drive letters instead of mount points that
|
||||
are separated with a colon.
|
||||
- Path names: A Windows path of `c:\tmp` is normally referred to as `/mnt/c/tmp` in `bash`. However, users can customize
|
||||
their `drvfs` mount points. A tool is provided in newer Windows releases, `/bin/wslpath`, that will convert paths
|
||||
between systems. Code in CE currently does the conversion between the standard conventions using string manipulation.
|
||||
- Environment variables: While the Windows path is available in bash, Windows environment variables are not. CE uses
|
||||
`cmd.exe /c echo %TEMP%` to determine the Windows temporary directory.
|
||||
- Execution environment: The execution environment cannot currently be set when doing `childprocess.spawn`. This is a
|
||||
serious issue for the MSVC compiler, which is highly environment-dependent (e.g., `%INCLUDE%`, `%LIBPATH%`, etc.)
|
||||
|
||||
## Configuration
|
||||
|
||||
This section is intended for the many WSL users who are new to Linux.
|
||||
|
||||
If you plan on debugging CE, you should clone the CE repo on a Windows volume.
|
||||
|
||||
CE is built on node.js ("node"). The easiest way to install node is using NVM, the Node Version Manager. Run the following commands from a bash shell:
|
||||
CE is built on node.js ("node"). The easiest way to install node is using NVM, the Node Version Manager. Run the
|
||||
following commands from a bash shell:
|
||||
|
||||
- `apt-get update` to make sure apt is up-to-date
|
||||
- `apt-get install build-essential libssl-dev`, though you probably have these already
|
||||
- Check https://github.com/creationix/nvm/releases for the latest NVM release, substituting it in the next command.
|
||||
@@ -30,7 +47,8 @@ CE is built on node.js ("node"). The easiest way to install node is using NVM, t
|
||||
- `nvm ls-remote --lts` to show the latest long-term supported (LTS) version of node.js
|
||||
- `nvm install 10.15.3`, substituting the latest LTS version, to install node.js
|
||||
|
||||
At this point you can change into the directory where you cloned CE and `make`. `make` will install a bunch of node packages and will finish with a message similar to this:
|
||||
At this point you can change into the directory where you cloned CE and `make`. `make` will install a bunch of node
|
||||
packages and will finish with a message similar to this:
|
||||
|
||||
```
|
||||
info: =======================================
|
||||
@@ -47,19 +65,35 @@ Now you can point your favorite web browser at http://localhost:10240 and see yo
|
||||
CE only required a few changes in order to run properly under WSL. Those changes are listed here:
|
||||
|
||||
- `app.js`:
|
||||
- `process.env.wsl` is set if CE if the string "Microsoft" in found in the output of `uname -a`. This works for all WSL distros as they all run on the base Microsoft Linux kernel.
|
||||
- If the `-tmpDir` option is specified on the command line, both `process.env.tmpDir` and `process.env.winTmp` are set to the specified value Note that if this is specified as a non-Windows volume, Windows executables will fail to run properly. Otherwise, `process.env.winTmp` is set to the value of the Windows `%TEMP%` directory.
|
||||
- `lib/exec.js`: Execute the compiler in the temporary directory. If the compiler's binary is located on a mounted volume (`startsWith("/mnt"`)) and CE is running under WSL, run the compiler in the `winTmp` directory. Otherwise, use the Linux temp directory.
|
||||
- `lib/compilers/wsl-vc.js`: See also `wine-vc.js`, the Wine version of this compiler-specific file. These files provide custom behaviors for a compiler. This file does two interesting things:
|
||||
- The `CompileCl` function translates from Linux-style directories to Windows-style directories (`/mnt/c/tmp` to `c:/tmp`) so that `CL.exe` can find its input files.
|
||||
- The `newTempDir` function creates a temporary directory in `winTmp`. CEs creates directories under the temp directory that start with `compiler-explorer-compiler` where the compiler and compiler output lives. This is similar to the function in `lib/base-compiler.js`.
|
||||
- `etc/config/c++.defaults.properties`: Add a configuration (`&cl19`) for MSVC compilers. This edits in here are currently wrong in two ways, but it doesn't affect the main CE instance as it uses `amazon` properties files, and it doesn't affect anyone running a local copy of CE because CE will just fail silently when it can't find a compiler.
|
||||
- The locations of these are hardcoded to a particular install location. See **MSVC setup** below for more information.
|
||||
- Setting of the `%INCLUDE%` path is done with the `/I` switch. This is very clunky and will fall over when command-line limits are hit, but it's the only option currently as environments aren't passed through when starting a Windows process from WSL.
|
||||
- `process.env.wsl` is set if CE if the string "Microsoft" in found in the output of `uname -a`. This works for all
|
||||
WSL distros as they all run on the base Microsoft Linux kernel.
|
||||
- If the `-tmpDir` option is specified on the command line, both `process.env.tmpDir` and `process.env.winTmp` are set
|
||||
to the specified value Note that if this is specified as a non-Windows volume, Windows executables will fail to run
|
||||
properly. Otherwise, `process.env.winTmp` is set to the value of the Windows `%TEMP%` directory.
|
||||
- `lib/exec.js`: Execute the compiler in the temporary directory. If the compiler's binary is located on a mounted
|
||||
volume (`startsWith("/mnt"`)) and CE is running under WSL, run the compiler in the `winTmp` directory. Otherwise, use
|
||||
the Linux temp directory.
|
||||
- `lib/compilers/wsl-vc.js`: See also `wine-vc.js`, the Wine version of this compiler-specific file. These files provide
|
||||
custom behaviors for a compiler. This file does two interesting things:
|
||||
- The `CompileCl` function translates from Linux-style directories to Windows-style directories (`/mnt/c/tmp` to
|
||||
`c:/tmp`) so that `CL.exe` can find its input files.
|
||||
- The `newTempDir` function creates a temporary directory in `winTmp`. CEs creates directories under the temp
|
||||
directory that start with `compiler-explorer-compiler` where the compiler and compiler output lives. This is similar
|
||||
to the function in `lib/base-compiler.js`.
|
||||
- `etc/config/c++.defaults.properties`: Add a configuration (`&cl19`) for MSVC compilers. This edits in here are
|
||||
currently wrong in two ways, but it doesn't affect the main CE instance as it uses `amazon` properties files, and it
|
||||
doesn't affect anyone running a local copy of CE because CE will just fail silently when it can't find a compiler.
|
||||
- The locations of these are hardcoded to a particular install location. See **MSVC setup** below for more
|
||||
information.
|
||||
- Setting of the `%INCLUDE%` path is done with the `/I` switch. This is very clunky and will fall over when
|
||||
command-line limits are hit, but it's the only option currently as environments aren't passed through when starting
|
||||
a Windows process from WSL.
|
||||
|
||||
## Debugging
|
||||
|
||||
The only viable option for debugging under WSL is to use [VS Code](https://code.visualstudio.com). Because VS Code doesn't currently run natively under WSL, you have to attach to a running CE instance. The following is a `launch.json` that works for attaching to an instance of CE that was launched with the `--inspect` flag.
|
||||
The only viable option for debugging under WSL is to use [VS Code](https://code.visualstudio.com). Because VS Code
|
||||
doesn't currently run natively under WSL, you have to attach to a running CE instance. The following is a `launch.json`
|
||||
that works for attaching to an instance of CE that was launched with the `--inspect` flag.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -81,14 +115,20 @@ The only viable option for debugging under WSL is to use [VS Code](https://code.
|
||||
|
||||
Launch CE with `make NODE_ARGS="--inspect"` to have node listen on port 9229.
|
||||
|
||||
Because you can only attach to the process, as opposed to launching the process, you're limited to `printf` debugging for startup code. Search the code for `logger.info` to see examples of how to `printf` debug.
|
||||
Because you can only attach to the process, as opposed to launching the process, you're limited to `printf` debugging
|
||||
for startup code. Search the code for `logger.info` to see examples of how to `printf` debug.
|
||||
|
||||
## MSVC setup
|
||||
|
||||
TODO. There's no real MSVC setup at this point because there's no good way to pass the environment to an invocation of `CL.exe`. Just point the `properties` file at your compiler binary and hack on the `/I` options until something works.
|
||||
TODO. There's no real MSVC setup at this point because there's no good way to pass the environment to an invocation of
|
||||
`CL.exe`. Just point the `properties` file at your compiler binary and hack on the `/I` options until something works.
|
||||
|
||||
When I get this working in a generalized fashion, CE's config will expect that MSVC drops match the format used by the daily NuGet compiler drops at https://visualcpp.myget/org. (NuGet packages are just renamed ZIP files plus metadata so they make an easy distribution method for compiler toolset drops.)
|
||||
When I get this working in a generalized fashion, CE's config will expect that MSVC drops match the format used by the
|
||||
daily NuGet compiler drops at https://visualcpp.myget/org. (NuGet packages are just renamed ZIP files plus metadata so
|
||||
they make an easy distribution method for compiler toolset drops.)
|
||||
|
||||
## Putting it all together
|
||||
|
||||
This should be enough information to get you started running CE under WSL. If there's information that you wish you would have had, please submit a PR to document. If there's information you're lacking to get running, please enter an Issue on the CE repo or contact me directly.
|
||||
This should be enough information to get you started running CE under WSL. If there's information that you wish you
|
||||
would have had, please submit a PR to document. If there's information you're lacking to get running, please enter an
|
||||
Issue on the CE repo or contact me directly.
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
Adding a library that is linked against:
|
||||
|
||||
- If the library is a C shared library, you should not use these instructions, use the `after_staging_script` instead to build the library during the installation
|
||||
- If the library is a C shared library, you should not use these instructions, use the `after_staging_script` instead to
|
||||
build the library during the installation
|
||||
- Check what buildsystem is used.
|
||||
- If CMake, it's going to be relatively easy.
|
||||
- If something else, it's going to be complicated.
|
||||
- If CMake
|
||||
- If the CMakeLists.txt is in the root folder, everything should be work
|
||||
- However, at least prefer to include make_targets property in the yaml to avoid any automagick confusion (it would test library name in all kinds of variants and when all fails do make all)
|
||||
- However, at least prefer to include make_targets property in the yaml to avoid any automagick confusion (it would
|
||||
test library name in all kinds of variants and when all fails do make all)
|
||||
- If there are multiple ways of generating libraries (shared/static), make a choice here
|
||||
|
||||
1. Add to bin/yaml/libraries.yaml
|
||||
|
||||
- There's a difference between nightly trunks' and versions, search for "nightly:" to find the nightlies
|
||||
- Note: the name of the library in the yaml file needs to be the same as the name in the c++.amazon.properties file
|
||||
- Add basic entry
|
||||
```
|
||||
|
||||
```yaml
|
||||
unifex:
|
||||
type: github
|
||||
method: nightlyclone
|
||||
@@ -24,28 +28,41 @@ Adding a library that is linked against:
|
||||
targets:
|
||||
- trunk
|
||||
```
|
||||
|
||||
2. Test installing
|
||||
|
||||
- `bin/ce_install --enable nightly install 'unifex'`
|
||||
|
||||
3. Test building
|
||||
|
||||
- Make sure you have a compiler installed, for example via `bin/ce_install install 'gcc 10.1.0'`
|
||||
- `bin/ce_install --enable nightly --buildfor g101 --dry build 'unifex'`
|
||||
- check one of the buildfolders that are created and see if there are .so's or .a's and otherwise check the cecmakelog.txt and cemakelog_X.txt
|
||||
- check one of the buildfolders that are created and see if there are .so's or .a's and otherwise check the
|
||||
cecmakelog.txt and cemakelog_X.txt
|
||||
- Iterate over this to make it work
|
||||
|
||||
4. If a static link file has been produced:
|
||||
- Add to the `c++.amazon.properties` in compiler-explorer in the libs properties for the new library a `libs.libraryname.staticliblink=libraryname`
|
||||
|
||||
- Add to the `c++.amazon.properties` in compiler-explorer in the libs properties for the new library a
|
||||
`libs.libraryname.staticliblink=libraryname`
|
||||
- libraryname here is without the 'lib' prefix of the .a file
|
||||
- Example unifex
|
||||
```
|
||||
|
||||
```ini
|
||||
libs.unifex.name=libunifex
|
||||
libs.unifex.versions=trunk
|
||||
libs.unifex.staticliblink=unifex
|
||||
libs.unifex.versions.trunk.version=trunk
|
||||
libs.unifex.versions.trunk.path=/opt/compiler-explorer/libs/unifex/trunk/include
|
||||
```
|
||||
5. If a config header file has been generated based on the compiler configuration, we can only maybe support this if the header does NOT include any defines about the architecture.
|
||||
|
||||
5. If a config header file has been generated based on the compiler configuration, we can only maybe support this if the
|
||||
header does NOT include any defines about the architecture.
|
||||
6. Send PR's
|
||||
7. Merge the amazon.properties to main
|
||||
8. Start library builder for the new library until no later than 00:00 UTC
|
||||
9. Await and check libraries @ https://conan.compiler-explorer.com/libraries.html and logs @ https://conan.compiler-explorer.com/failedbuilds.html
|
||||
- These new libraries won't show up on these pages until you do https://conan.compiler-explorer.com/reinitialize and then go to https://conan.compiler-explorer.com/libraries and hit refresh
|
||||
9. Await and check libraries @ https://conan.compiler-explorer.com/libraries.html and logs @
|
||||
https://conan.compiler-explorer.com/failedbuilds.html
|
||||
|
||||
- These new libraries won't show up on these pages until you do https://conan.compiler-explorer.com/reinitialize and
|
||||
then go to https://conan.compiler-explorer.com/libraries and hit refresh
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
## Brief notes on how to build a compiler
|
||||
|
||||
* log into admin node `ce admin`
|
||||
* start the builder node: `ce builder start`
|
||||
* log into builder node: `ce builder login`
|
||||
* sudo docker run --rm --name gcc.build -v/home/ubuntu/.s3cfg:/root/.s3cfg:ro -ti compilerexplorer/gcc-builder bash build.sh 8.2.0 s3://compiler-explorer/opt/
|
||||
* Remember to stop the builder node!
|
||||
* Log out of the builder node
|
||||
* `ce builder stop`
|
||||
- log into admin node `ce admin`
|
||||
- start the builder node: `ce builder start`
|
||||
- log into builder node: `ce builder login`
|
||||
- sudo docker run --rm --name gcc.build -v/home/ubuntu/.s3cfg:/root/.s3cfg:ro -ti compilerexplorer/gcc-builder bash
|
||||
build.sh 8.2.0 s3://compiler-explorer/opt/
|
||||
- Remember to stop the builder node!
|
||||
- Log out of the builder node
|
||||
- `ce builder stop`
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
# Frontend testing
|
||||
|
||||
We have a mixture of typescript in the main website's code (located in `static/tests`) and Cypress (located in `cypress/integration`) to test and report on the workings of that code.
|
||||
We have a mixture of typescript in the main website's code (located in `static/tests`) and Cypress (located in
|
||||
`cypress/integration`) to test and report on the workings of that code.
|
||||
|
||||
But there's always the possibility to use Cypress code to do UI checks and testing.
|
||||
|
||||
## Recommended
|
||||
|
||||
The recommended way of testing is to use typescript to test the inner workings of the various interfaces that are available.
|
||||
The recommended way of testing is to use typescript to test the inner workings of the various interfaces that are
|
||||
available.
|
||||
|
||||
This has the advantage of having types and being able to verify your code is consistent with the rest of the website and probably going to run correctly - without having to startup the website and Cypress.
|
||||
This has the advantage of having types and being able to verify your code is consistent with the rest of the website and
|
||||
probably going to run correctly - without having to startup the website and Cypress.
|
||||
|
||||
## Adding a test
|
||||
|
||||
Steps to add a test:
|
||||
|
||||
* Create a new file in `static/tests` (copy paste from `static/tests/hello-world.ts`)
|
||||
* Make sure to change the `description` as well as the test
|
||||
* Add the file to the imports of `static/tests/_all.js`
|
||||
* Add a `runFrontendTest()` call with the new test description to `cypress/integration/frontend-testing.js`
|
||||
- Create a new file in `static/tests` (copy paste from `static/tests/hello-world.ts`)
|
||||
- Make sure to change the `description` as well as the test
|
||||
- Add the file to the imports of `static/tests/_all.js`
|
||||
- Add a `runFrontendTest()` call with the new test description to `cypress/integration/frontend-testing.js`
|
||||
|
||||
## Starting tests locally
|
||||
|
||||
@@ -25,4 +28,5 @@ You don't need to install an entire X server to actually run cypress (just xfvb)
|
||||
|
||||
You can find a complete list at https://docs.cypress.io/guides/getting-started/installing-cypress#System-requirements
|
||||
|
||||
If you have the prerequisites installed, you should be able to run `npx cypress run` - however, you will need to start the CE website separately in another terminal before that.
|
||||
If you have the prerequisites installed, you should be able to run `npx cypress run` - however, you will need to start
|
||||
the CE website separately in another terminal before that.
|
||||
|
||||
@@ -1,52 +1,40 @@
|
||||
# This document is a Work in Progress
|
||||
|
||||
This document pretends to put everything that is important to check before doing a full site release as well as to how
|
||||
to do it, to ensure that the site fully works upon the release of a new version.
|
||||
|
||||
This document pretends to put everything that is important to check
|
||||
before doing a full site release as well as to how to do it,
|
||||
to ensure that the site fully works upon the release of a new version.
|
||||
Depending on the nature of the changes, only some sections of this list will be relevant - Feel free to focus only on
|
||||
those you deem most important.
|
||||
|
||||
Depending on the nature of the changes, only some sections
|
||||
of this list will be relevant - Feel free to focus only on those
|
||||
you deem most important.
|
||||
|
||||
If you think we are missing any important point, we greatly appreciate
|
||||
suggestions.
|
||||
If you think we are missing any important point, we greatly appreciate suggestions.
|
||||
|
||||
## Running the site
|
||||
First things first, we'll use the beta environment as it lets us run the
|
||||
site under additional checks that will automate some of the problem
|
||||
detections for us.
|
||||
|
||||
First things first, we'll use the beta environment as it lets us run the site under additional checks that will automate
|
||||
some of the problem detections for us.
|
||||
|
||||
To run the new version on the beta environment we'll use the `ce` utility:
|
||||
|
||||
Ensure that the beta environment is active by running
|
||||
`ce --env beta environment start` - You can skip this step if it's
|
||||
already running from a previous run or if you'd rather boot it once
|
||||
the current version is marked as active.
|
||||
Ensure that the beta environment is active by running `ce --env beta environment start` - You can skip this step if it's
|
||||
already running from a previous run or if you'd rather boot it once the current version is marked as active.
|
||||
|
||||
Check what `versionId` the desired commit has. This can be checked on the
|
||||
Github CI build logs as its build number for that specific commit, or
|
||||
by running `ce --env beta builds list` which shows a list of the
|
||||
most recent builds with their corresponding commit hash.
|
||||
Check what `versionId` the desired commit has. This can be checked on the Github CI build logs as its build number for
|
||||
that specific commit, or by running `ce --env beta builds list` which shows a list of the most recent builds with their
|
||||
corresponding commit hash.
|
||||
|
||||
Once you have the desired `versionId`, mark it as the current version to
|
||||
be used by running `ce --env beta builds set_current {versionId}`
|
||||
Once you have the desired `versionId`, mark it as the current version to be used by running
|
||||
`ce --env beta builds set_current {versionId}`
|
||||
|
||||
If needed, you can now restart the currently running instances
|
||||
with `ce --env beta instances restart` if needed.
|
||||
If needed, you can now restart the currently running instances with `ce --env beta instances restart` if needed.
|
||||
|
||||
Once this is finished, the `/beta` endpoint should be ready for testing.
|
||||
|
||||
- The first issue you might find is that the beta instance does not boot.
|
||||
This might be caused by the `--ensureNoIdClash` flag shutting the app down
|
||||
if it detects one or more pairs of compilers sharing the same id
|
||||
even if they belong to different languages. An error should be logged
|
||||
with the culprits for easy debugging.
|
||||
|
||||
- The first issue you might find is that the beta instance does not boot. This might be caused by the
|
||||
`--ensureNoIdClash` flag shutting the app down if it detects one or more pairs of compilers sharing the same id even
|
||||
if they belong to different languages. An error should be logged with the culprits for easy debugging.
|
||||
|
||||
## Basic general site functionality
|
||||
In-depth documentation follows below, but once the beta site is running,
|
||||
some basic checks include:
|
||||
|
||||
In-depth documentation follows below, but once the beta site is running, some basic checks include:
|
||||
|
||||
-
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
If you need to update the x86 asm documentation, just run `etc/scripts/docenizers/docenizer.py`, which requires:
|
||||
|
||||
- Python 3.x with BeautifulSoup
|
||||
|
||||
You can use some options in the script:
|
||||
|
||||
- `-o`/`--outputpath` - Final destination of the generated JavaScript file
|
||||
- `-i`/`--inputfolder` - Points to the downloaded and extracted .html files
|
||||
- `-d`/`--downloadfolder` - Points to the download folder to use in case a new version is needed
|
||||
|
||||
@@ -5,19 +5,24 @@ The library build status is accessible from https://conan.compiler-explorer.com/
|
||||
The build process of libraries (started by https://github.com/compiler-explorer/infra/blob/main/admin-daily-builds.sh)
|
||||
has a couple of safeguards to not build libraries allday everyday, namely:
|
||||
|
||||
* The compiler needs to have supportsBinary=true on in the current https://github.com/compiler-explorer/compiler-explorer/blob/main/etc/config/c%2B%2B.amazon.properties
|
||||
* If all libraries are being built, only a commit hash change will result in a new build.
|
||||
* If a particular compiler has failed to produce a valid build, it will be marked and will not build the library with this compiler anymore.
|
||||
* There are a couple of hardcoded exceptions that never attempt the build, these can be found in https://github.com/compiler-explorer/infra/blob/main/bin/lib/library_builder.py#L29
|
||||
* You can manually trigger a forced-build, by setting the `--build-for=compilerid` parameter, which can also be set by changing the 2nd parameter here -> https://github.com/compiler-explorer/infra/blob/main/admin-daily-builds.sh#L104
|
||||
* If you want to trigger all compilers to rebuild a certain library, you will need to manually delete the logging related to this library.
|
||||
|
||||
- The compiler needs to have supportsBinary=true on in the current
|
||||
https://github.com/compiler-explorer/compiler-explorer/blob/main/etc/config/c%2B%2B.amazon.properties
|
||||
- If all libraries are being built, only a commit hash change will result in a new build.
|
||||
- If a particular compiler has failed to produce a valid build, it will be marked and will not build the library with
|
||||
this compiler anymore.
|
||||
- There are a couple of hardcoded exceptions that never attempt the build, these can be found in
|
||||
https://github.com/compiler-explorer/infra/blob/main/bin/lib/library_builder.py#L29
|
||||
- You can manually trigger a forced-build, by setting the `--build-for=compilerid` parameter, which can also be set by
|
||||
changing the 2nd parameter here -> https://github.com/compiler-explorer/infra/blob/main/admin-daily-builds.sh#L104
|
||||
- If you want to trigger all compilers to rebuild a certain library, you will need to manually delete the logging
|
||||
related to this library.
|
||||
|
||||
# manually delete logging
|
||||
|
||||
You have to login to the conan instance and delete records from the sqlite database responsible for keeping the logging.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
ce conan login
|
||||
sudo -u ce sqlite3 /home/ce/.conan_server/buildslogs.db
|
||||
|
||||
@@ -27,7 +27,9 @@ import { getAsmOpcode } from './generated/asm-docs-amd64';
|
||||
|
||||
export class Amd64DocumentationProvider extends BaseAssemblyDocumentationProvider {
|
||||
private static readonly ATT_SUFFIX_REMOVER = /^([a-z]+)[blqw]$/i;
|
||||
public static get key() { return 'amd64'; }
|
||||
public static get key() {
|
||||
return 'amd64';
|
||||
}
|
||||
public override getInstructionInformation(instruction: string): AssemblyInstructionInfo | null {
|
||||
// Try both raw opcode and with AT&T suffix removed
|
||||
let info = getAsmOpcode(instruction);
|
||||
|
||||
@@ -26,7 +26,9 @@ import { AssemblyInstructionInfo, BaseAssemblyDocumentationProvider } from './ba
|
||||
import {getAsmOpcode} from './generated/asm-docs-avr';
|
||||
|
||||
export class AvrDocumentationProvider extends BaseAssemblyDocumentationProvider {
|
||||
public static get key() { return 'avr'; }
|
||||
public static get key() {
|
||||
return 'avr';
|
||||
}
|
||||
public override getInstructionInformation(instruction: string): AssemblyInstructionInfo | null {
|
||||
return getAsmOpcode(instruction) || null;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ import { AssemblyInstructionInfo, BaseAssemblyDocumentationProvider } from './ba
|
||||
import {getAsmOpcode} from './generated/asm-docs-java';
|
||||
|
||||
export class JavaDocumentationProvider extends BaseAssemblyDocumentationProvider {
|
||||
public static get key() { return 'java'; }
|
||||
public static get key() {
|
||||
return 'java';
|
||||
}
|
||||
public override getInstructionInformation(instruction: string): AssemblyInstructionInfo | null {
|
||||
return getAsmOpcode(instruction) || null;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ import { AssemblyInstructionInfo, BaseAssemblyDocumentationProvider } from './ba
|
||||
import {getAsmOpcode} from './generated/asm-docs-6502';
|
||||
|
||||
export class Mos6502DocumentationProvider extends BaseAssemblyDocumentationProvider {
|
||||
public static get key() { return '6502'; }
|
||||
public static get key() {
|
||||
return '6502';
|
||||
}
|
||||
public override getInstructionInformation(instruction: string): AssemblyInstructionInfo | null {
|
||||
return getAsmOpcode(instruction) || null;
|
||||
}
|
||||
|
||||
@@ -37,9 +37,7 @@ export class InstanceFetcher {
|
||||
|
||||
async getInstances() {
|
||||
const result = await this.ec2.describeInstances().promise();
|
||||
return result.Reservations
|
||||
.flatMap(r => r.Instances)
|
||||
.filter(reservation => {
|
||||
return result.Reservations.flatMap(r => r.Instances).filter(reservation => {
|
||||
if (reservation.State.Name !== 'running') return false;
|
||||
return reservation.Tags.some(t => t.Key === this.tagKey && t.Value === this.tagValue);
|
||||
});
|
||||
@@ -76,7 +74,6 @@ export async function initConfig(properties) {
|
||||
}
|
||||
|
||||
export function getConfig(name) {
|
||||
if (!awsConfigInit)
|
||||
throw new Error("Reading AWS config before it's loaded");
|
||||
if (!awsConfigInit) throw new Error("Reading AWS config before it's loaded");
|
||||
return awsConfig[name] || awsProps(name);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ export class BuildEnvSetupBase {
|
||||
}
|
||||
} else if (this.compilerTypeOrGCC === 'gcc') {
|
||||
if (this.compiler.exe.includes('/icpx')) {
|
||||
result = (arch === 'x86') || (arch === 'x86_64');
|
||||
result = arch === 'x86' || arch === 'x86_64';
|
||||
} else {
|
||||
result = await execCompilerCached(this.compiler.exe, ['--target-help']);
|
||||
}
|
||||
@@ -89,13 +89,12 @@ export class BuildEnvSetupBase {
|
||||
}
|
||||
|
||||
getCompilerArch() {
|
||||
let arch = _.find(this.compilerOptionsArr, (option) => {
|
||||
let arch = _.find(this.compilerOptionsArr, option => {
|
||||
return option.startsWith('-march=');
|
||||
});
|
||||
|
||||
let target = _.find(this.compilerOptionsArr, (option) => {
|
||||
option.startsWith('-target=') ||
|
||||
option.startsWith('--target=');
|
||||
let target = _.find(this.compilerOptionsArr, option => {
|
||||
option.startsWith('-target=') || option.startsWith('--target=');
|
||||
});
|
||||
|
||||
if (target) {
|
||||
@@ -130,7 +129,7 @@ export class BuildEnvSetupBase {
|
||||
if (match) {
|
||||
return match[1];
|
||||
} else {
|
||||
const stdlibOption = _.find(key.options, (option) => {
|
||||
const stdlibOption = _.find(key.options, option => {
|
||||
return option.startsWith('-stdlib=');
|
||||
});
|
||||
|
||||
@@ -149,7 +148,7 @@ export class BuildEnvSetupBase {
|
||||
if (key.options.includes('-m32')) {
|
||||
return 'x86';
|
||||
} else {
|
||||
let target = _.find(key.options, (option) => {
|
||||
let target = _.find(key.options, option => {
|
||||
return option.startsWith('-target=') || option.startsWith('--target=');
|
||||
});
|
||||
|
||||
|
||||
@@ -53,11 +53,11 @@ export class BuildEnvSetupCliConan extends BuildEnvSetupBase {
|
||||
}
|
||||
|
||||
hasBinariesToLink(details) {
|
||||
return (details.libpath.length === 0) && (details.staticliblink.length > 0);
|
||||
return details.libpath.length === 0 && details.staticliblink.length > 0;
|
||||
}
|
||||
|
||||
hasAtLeastOneBinaryToLink(libraryDetails) {
|
||||
return _.some(libraryDetails, (details) => this.hasBinariesToLink(details));
|
||||
return _.some(libraryDetails, details => this.hasBinariesToLink(details));
|
||||
}
|
||||
|
||||
async prepareConanRequest(libraryDetails, dirPath) {
|
||||
@@ -69,6 +69,7 @@ export class BuildEnvSetupCliConan extends BuildEnvSetupBase {
|
||||
}
|
||||
});
|
||||
|
||||
// prettier-ignore
|
||||
data +=
|
||||
'[imports]\n' +
|
||||
'lib, *.a -> .\n' +
|
||||
@@ -85,6 +86,7 @@ export class BuildEnvSetupCliConan extends BuildEnvSetupBase {
|
||||
|
||||
const args = ['install', '.'];
|
||||
if (this.remote) args.push('-r', this.remote);
|
||||
// prettier-ignore
|
||||
args.push(
|
||||
'-s', 'os=Linux',
|
||||
'-s', 'build_type=Debug',
|
||||
@@ -93,7 +95,8 @@ export class BuildEnvSetupCliConan extends BuildEnvSetupBase {
|
||||
'-s', `compiler.libcxx=${libcxx}`,
|
||||
'-s', `arch=${arch}`,
|
||||
'-s', `stdver=${stdver}`,
|
||||
'-s', `flagcollection=${flagcollection}`);
|
||||
'-s', `flagcollection=${flagcollection}`,
|
||||
);
|
||||
|
||||
logger.info('Conan install: ', args);
|
||||
return exec.execute(this.exe, args, {customCwd: dirPath});
|
||||
|
||||
47
lib/cfg.js
47
lib/cfg.js
@@ -72,10 +72,7 @@ const gcc = {
|
||||
filterData: asmArr => {
|
||||
const jmpLabelRegex = /\.L\d+:/;
|
||||
const isCode = x => x && x.text && (x.source !== null || jmpLabelRegex.test(x.text) || isFunctionName(x));
|
||||
return _.chain(filterTextSection(asmArr))
|
||||
.map(_.clone)
|
||||
.filter(isCode)
|
||||
.value();
|
||||
return _.chain(filterTextSection(asmArr)).map(_.clone).filter(isCode).value();
|
||||
},
|
||||
isFunctionEnd: x => x[0] !== ' ' && x[0] !== '.' && x.includes(':'),
|
||||
|
||||
@@ -101,18 +98,12 @@ const clang = {
|
||||
const removeComments = x => {
|
||||
const pos_x86 = x.text.indexOf('# ');
|
||||
const pos_arm = x.text.indexOf('// ');
|
||||
if (pos_x86 !== -1)
|
||||
x.text = utils.trimRight(x.text.substring(0, pos_x86));
|
||||
if (pos_arm !== -1)
|
||||
x.text = utils.trimRight(x.text.substring(0, pos_arm));
|
||||
if (pos_x86 !== -1) x.text = utils.trimRight(x.text.substring(0, pos_x86));
|
||||
if (pos_arm !== -1) x.text = utils.trimRight(x.text.substring(0, pos_arm));
|
||||
return x;
|
||||
};
|
||||
|
||||
return _.chain(filterTextSection(asmArr))
|
||||
.map(_.clone)
|
||||
.filter(isCode)
|
||||
.map(removeComments)
|
||||
.value();
|
||||
return _.chain(filterTextSection(asmArr)).map(_.clone).filter(isCode).map(removeComments).value();
|
||||
},
|
||||
isFunctionEnd: x => x[0] !== ' ' && x[0] !== '.' && x.includes(':'),
|
||||
|
||||
@@ -190,11 +181,13 @@ function splitToCanonicalBasicBlock(basicBlock) {
|
||||
}
|
||||
|
||||
if (actPosSz === 0)
|
||||
return [{
|
||||
return [
|
||||
{
|
||||
nameId: basicBlock.nameId,
|
||||
start: basicBlock.start,
|
||||
end: basicBlock.end,
|
||||
}];
|
||||
},
|
||||
];
|
||||
else if (actPosSz === 1)
|
||||
return [
|
||||
{nameId: basicBlock.nameId, start: basicBlock.start, end: actionPos[0] + 1},
|
||||
@@ -219,7 +212,6 @@ function splitToCanonicalBasicBlock(basicBlock) {
|
||||
result.push(_.clone(tmp));
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,8 +252,7 @@ function makeEdges(asmArr, arrOfCanonicalBasicBlock, rules) {
|
||||
|
||||
const generateName = function (name, suffix) {
|
||||
const pos = name.indexOf('@');
|
||||
if (pos === -1)
|
||||
return name + '@' + suffix;
|
||||
if (pos === -1) return name + '@' + suffix;
|
||||
|
||||
return name.substring(0, pos + 1) + suffix;
|
||||
};
|
||||
@@ -312,12 +303,14 @@ function makeEdges(asmArr, arrOfCanonicalBasicBlock, rules) {
|
||||
}
|
||||
|
||||
function isLLVMBased(compilerType, version) {
|
||||
return version.includes('clang') ||
|
||||
return (
|
||||
version.includes('clang') ||
|
||||
version.includes('LLVM') ||
|
||||
version.includes('rustc') ||
|
||||
compilerType === 'swift' ||
|
||||
compilerType === 'zig' ||
|
||||
compilerType === 'ispc';
|
||||
compilerType === 'ispc'
|
||||
);
|
||||
}
|
||||
|
||||
export function generateStructure(compilerType, version, asmArr) {
|
||||
@@ -328,19 +321,25 @@ export function generateStructure(compilerType, version, asmArr) {
|
||||
return funcs;
|
||||
}
|
||||
const result = {};
|
||||
_.each(funcs, _.bind(function (rng) {
|
||||
_.each(
|
||||
funcs,
|
||||
_.bind(function (rng) {
|
||||
const basicBlocks = splitToBasicBlocks(code, rng, rules.isBasicBlockEnd, rules.isJmpInstruction);
|
||||
let arrOfCanonicalBasicBlock = [];
|
||||
_.each(basicBlocks, _.bind(function (elm) {
|
||||
_.each(
|
||||
basicBlocks,
|
||||
_.bind(function (elm) {
|
||||
const tmp = splitToCanonicalBasicBlock(elm);
|
||||
arrOfCanonicalBasicBlock = arrOfCanonicalBasicBlock.concat(tmp);
|
||||
}, this));
|
||||
}, this),
|
||||
);
|
||||
|
||||
result[code[rng.start].text] = {
|
||||
nodes: makeNodes(code, arrOfCanonicalBasicBlock),
|
||||
edges: makeEdges(code, arrOfCanonicalBasicBlock, rules),
|
||||
};
|
||||
}, this));
|
||||
}, this),
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -118,20 +118,14 @@ export class ClientStateExecutor {
|
||||
}
|
||||
|
||||
fromJsonData(jsondata) {
|
||||
if (typeof jsondata.compilerVisible !== 'undefined')
|
||||
this.compilerVisible = jsondata.compilerVisible;
|
||||
if (typeof jsondata.compilerVisible !== 'undefined') this.compilerVisible = jsondata.compilerVisible;
|
||||
if (typeof jsondata.compilerOutputVisible !== 'undefined')
|
||||
this.compilerOutputVisible = jsondata.compilerOutputVisible;
|
||||
if (typeof jsondata.arguments !== 'undefined')
|
||||
this.arguments = jsondata.arguments;
|
||||
if (typeof jsondata.argumentsVisible !== 'undefined')
|
||||
this.argumentsVisible = jsondata.argumentsVisible;
|
||||
if (typeof jsondata.stdin !== 'undefined')
|
||||
this.stdin = jsondata.stdin;
|
||||
if (typeof jsondata.stdinVisible !== 'undefined')
|
||||
this.stdinVisible = jsondata.stdinVisible;
|
||||
if (typeof jsondata.wrap !== 'undefined')
|
||||
this.wrap = jsondata.wrap;
|
||||
if (typeof jsondata.arguments !== 'undefined') this.arguments = jsondata.arguments;
|
||||
if (typeof jsondata.argumentsVisible !== 'undefined') this.argumentsVisible = jsondata.argumentsVisible;
|
||||
if (typeof jsondata.stdin !== 'undefined') this.stdin = jsondata.stdin;
|
||||
if (typeof jsondata.stdinVisible !== 'undefined') this.stdinVisible = jsondata.stdinVisible;
|
||||
if (typeof jsondata.wrap !== 'undefined') this.wrap = jsondata.wrap;
|
||||
|
||||
this.compiler = new ClientStateCompiler(jsondata.compiler);
|
||||
}
|
||||
|
||||
@@ -37,21 +37,17 @@ export class CompilationQueue {
|
||||
}
|
||||
|
||||
static fromProps(ceProps) {
|
||||
return new CompilationQueue(
|
||||
ceProps('maxConcurrentCompiles', 1),
|
||||
ceProps('compilationEnvTimeoutMs'));
|
||||
return new CompilationQueue(ceProps('maxConcurrentCompiles', 1), ceProps('compilationEnvTimeoutMs'));
|
||||
}
|
||||
|
||||
enqueue(job) {
|
||||
const enqueueAsyncId = executionAsyncId();
|
||||
// If we're asked to enqueue a job when we're already in a async queued job context, just run it.
|
||||
// This prevents a deadlock.
|
||||
if (this._running.has(enqueueAsyncId))
|
||||
return job();
|
||||
if (this._running.has(enqueueAsyncId)) return job();
|
||||
return this._queue.add(() => {
|
||||
const jobAsyncId = executionAsyncId();
|
||||
if (this._running.has(jobAsyncId))
|
||||
throw new Error('somehow we entered the context twice');
|
||||
if (this._running.has(jobAsyncId)) throw new Error('somehow we entered the context twice');
|
||||
try {
|
||||
this._running.add(jobAsyncId);
|
||||
return job();
|
||||
|
||||
@@ -26,12 +26,13 @@ import { BaseCompiler } from '../base-compiler';
|
||||
|
||||
// Plain compiler, which just runs the tool and returns whatever the output was
|
||||
export class AnalysisTool extends BaseCompiler {
|
||||
static get key() { return 'analysis-tool'; }
|
||||
static get key() {
|
||||
return 'analysis-tool';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
// Default is to disable all "cosmetic" filters
|
||||
if (!info.disabledFilters)
|
||||
info.disabledFilters = ['labels', 'directives', 'commentOnly', 'trim'];
|
||||
if (!info.disabledFilters) info.disabledFilters = ['labels', 'directives', 'commentOnly', 'trim'];
|
||||
super(info, env);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ import * as utils from '../utils';
|
||||
import {BaseParser} from './argument-parsers';
|
||||
|
||||
export class AssemblyCompiler extends BaseCompiler {
|
||||
static get key() { return 'assembly'; }
|
||||
static get key() {
|
||||
return 'assembly';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -73,13 +75,18 @@ export class AssemblyCompiler extends BaseCompiler {
|
||||
async runReadelf(fullResult, objectFilename) {
|
||||
let execOptions = this.getDefaultExecOptions();
|
||||
execOptions.customCwd = path.dirname(objectFilename);
|
||||
return await this.doBuildstepAndAddToResult(fullResult, 'readelf', this.env.ceProps('readelf'),
|
||||
['-h', objectFilename], execOptions);
|
||||
return await this.doBuildstepAndAddToResult(
|
||||
fullResult,
|
||||
'readelf',
|
||||
this.env.ceProps('readelf'),
|
||||
['-h', objectFilename],
|
||||
execOptions,
|
||||
);
|
||||
}
|
||||
|
||||
async getArchitecture(fullResult, objectFilename) {
|
||||
const result = await this.runReadelf(fullResult, objectFilename);
|
||||
const output = result.stdout.map((line) => line.text).join('\n');
|
||||
const output = result.stdout.map(line => line.text).join('\n');
|
||||
if (output.includes('ELF32') && output.includes('80386')) {
|
||||
return 'x86';
|
||||
} else if (output.includes('ELF64') && output.includes('X86-64')) {
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
import {BaseCompiler} from '../base-compiler';
|
||||
|
||||
export class Cc65Compiler extends BaseCompiler {
|
||||
static get key() { return 'cc65'; }
|
||||
static get key() {
|
||||
return 'cc65';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
return ['-g', '-o', this.filename(outputFilename)];
|
||||
|
||||
@@ -27,7 +27,9 @@ import path from 'path';
|
||||
import {BaseCompiler} from '../base-compiler';
|
||||
|
||||
export class CircleCompiler extends BaseCompiler {
|
||||
static get key() { return 'circle'; }
|
||||
static get key() {
|
||||
return 'circle';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
let options = [`-o=${this.filename(outputFilename)}`];
|
||||
|
||||
@@ -32,7 +32,9 @@ import { CrystalAsmParser } from '../parsers/asm-parser-crystal';
|
||||
import {CrystalParser} from './argument-parsers';
|
||||
|
||||
export class CrystalCompiler extends BaseCompiler {
|
||||
static get key() { return 'crystal'; }
|
||||
static get key() {
|
||||
return 'crystal';
|
||||
}
|
||||
|
||||
constructor(compiler, env) {
|
||||
super(compiler, env);
|
||||
|
||||
@@ -36,7 +36,9 @@ export class DartCompiler extends BaseCompiler {
|
||||
this.asm = new DartAsmParser();
|
||||
}
|
||||
|
||||
static get key() { return 'dart'; }
|
||||
static get key() {
|
||||
return 'dart';
|
||||
}
|
||||
|
||||
prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) {
|
||||
let options = this.optionsForFilter(filters, outputFilename, userOptions);
|
||||
@@ -61,15 +63,9 @@ export class DartCompiler extends BaseCompiler {
|
||||
|
||||
const dartCompileIntroduction = '2.10.0';
|
||||
if (Semver.lt(utils.asSafeVer(this.compiler.semver), dartCompileIntroduction, true)) {
|
||||
return [
|
||||
'-k', 'aot',
|
||||
'-o', this.filename(outputFilename),
|
||||
];
|
||||
return ['-k', 'aot', '-o', this.filename(outputFilename)];
|
||||
} else {
|
||||
return [
|
||||
'compile', 'aot-snapshot',
|
||||
'-o', this.filename(outputFilename),
|
||||
];
|
||||
return ['compile', 'aot-snapshot', '-o', this.filename(outputFilename)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,5 +25,7 @@
|
||||
import {BaseCompiler} from '../base-compiler';
|
||||
|
||||
export class DefaultCompiler extends BaseCompiler {
|
||||
static get key() { return 'default'; }
|
||||
static get key() {
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {ClangParser} from './argument-parsers';
|
||||
|
||||
export class DMDCompiler extends BaseCompiler {
|
||||
static get key() { return 'dmd'; }
|
||||
static get key() {
|
||||
return 'dmd';
|
||||
}
|
||||
|
||||
constructor(compiler, env) {
|
||||
super(compiler, env);
|
||||
@@ -49,7 +51,8 @@ export class DMDCompiler extends BaseCompiler {
|
||||
const lPath = path.basename(outputFilename);
|
||||
return this.handlePostProcessResult(
|
||||
result,
|
||||
await this.exec(postProcesses[0], ['-l', lPath], {customCwd: dirPath, maxOutput: maxSize}));
|
||||
await this.exec(postProcesses[0], ['-l', lPath], {customCwd: dirPath, maxOutput: maxSize}),
|
||||
);
|
||||
}
|
||||
|
||||
getOutputFilename(dirPath, outputFilebase) {
|
||||
@@ -57,7 +60,7 @@ export class DMDCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
buildExecutable(compiler, options, inputFilename, execOptions) {
|
||||
options = options.filter((param) => param !== '-c');
|
||||
options = options.filter(param => param !== '-c');
|
||||
|
||||
return this.runCompiler(compiler, options, inputFilename, execOptions);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
import {ClangCompiler} from './clang';
|
||||
|
||||
export class EllccCompiler extends ClangCompiler {
|
||||
static get key() { return 'ellcc'; }
|
||||
static get key() {
|
||||
return 'ellcc';
|
||||
}
|
||||
|
||||
getSharedLibraryPathsAsArguments() {
|
||||
const pathFlag = this.compiler.rpathFlag || '-Wl,-rpath,';
|
||||
|
||||
@@ -28,7 +28,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {AsmEWAVRParser} from '../parsers/asm-parser-ewavr';
|
||||
|
||||
export class EWARMCompiler extends BaseCompiler {
|
||||
static get key() { return 'ewarm'; }
|
||||
static get key() {
|
||||
return 'ewarm';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -38,10 +40,8 @@ export class EWARMCompiler extends BaseCompiler {
|
||||
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);
|
||||
if (err) reject(`Unable to open temp file: ${err}`);
|
||||
else resolve(dirPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -51,9 +51,6 @@ export class EWARMCompiler extends BaseCompiler {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'-lB', this.filename(outputFilename),
|
||||
'-o', this.filename(outputFilename + '.obj'),
|
||||
];
|
||||
return ['-lB', this.filename(outputFilename), '-o', this.filename(outputFilename + '.obj')];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {AsmEWAVRParser} from '../parsers/asm-parser-ewavr';
|
||||
|
||||
export class EWAVRCompiler extends BaseCompiler {
|
||||
static get key() { return 'ewavr'; }
|
||||
static get key() {
|
||||
return 'ewavr';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
info.supportsDemangle = false;
|
||||
@@ -40,10 +42,8 @@ export class EWAVRCompiler extends BaseCompiler {
|
||||
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);
|
||||
if (err) reject(`Unable to open temp file: ${err}`);
|
||||
else resolve(dirPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -53,9 +53,6 @@ export class EWAVRCompiler extends BaseCompiler {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'-lB', this.filename(outputFilename),
|
||||
'-o', this.filename(outputFilename + '.obj'),
|
||||
];
|
||||
return ['-lB', this.filename(outputFilename), '-o', this.filename(outputFilename + '.obj')];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,14 @@ export class FakeCompiler {
|
||||
}
|
||||
|
||||
constructor(info) {
|
||||
this.compiler = Object.assign({
|
||||
this.compiler = Object.assign(
|
||||
{
|
||||
id: 'fake-for-test',
|
||||
lang: 'fake-lang',
|
||||
options: '',
|
||||
}, info);
|
||||
},
|
||||
info,
|
||||
);
|
||||
this.lang = {id: this.compiler.lang, name: `Language ${this.compiler.lang}`};
|
||||
this.info = info;
|
||||
}
|
||||
@@ -67,12 +70,14 @@ export class FakeCompiler {
|
||||
}
|
||||
|
||||
cmake(files, options) {
|
||||
return Promise.resolve(_.extend(this.info.fakeResult || {}, {
|
||||
return Promise.resolve(
|
||||
_.extend(this.info.fakeResult || {}, {
|
||||
input: {
|
||||
files: files,
|
||||
options: options,
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
initalize() {
|
||||
|
||||
@@ -28,7 +28,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import * as utils from '../utils';
|
||||
|
||||
export class FortranCompiler extends BaseCompiler {
|
||||
static get key() { return 'fortran'; }
|
||||
static get key() {
|
||||
return 'fortran';
|
||||
}
|
||||
|
||||
async runCompiler(compiler, options, inputFilename, execOptions) {
|
||||
if (!execOptions) {
|
||||
|
||||
@@ -25,5 +25,7 @@
|
||||
import {BaseCompiler} from '../base-compiler';
|
||||
|
||||
export class GCCCompiler extends BaseCompiler {
|
||||
static get key() { return 'gcc'; }
|
||||
static get key() {
|
||||
return 'gcc';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,5 +25,7 @@
|
||||
import {GCCCompiler} from './gcc';
|
||||
|
||||
export class GCCRSCompiler extends GCCCompiler {
|
||||
static get key() { return 'gccrs'; }
|
||||
static get key() {
|
||||
return 'gccrs';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,8 @@ export class GolangCompiler extends BaseCompiler {
|
||||
extractLogging(stdout) {
|
||||
let filepath = `./${this.compileFilename}`;
|
||||
const reLogging = /^[^:]+:\d+:(\d+:)?\s.*/;
|
||||
return stdout.filter(obj => obj.text.match(reLogging))
|
||||
return stdout
|
||||
.filter(obj => obj.text.match(reLogging))
|
||||
.map(obj => obj.text.replace(filepath, '<source>'))
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {ISPCParser} from './argument-parsers';
|
||||
|
||||
export class ISPCCompiler extends BaseCompiler {
|
||||
static get key() { return 'ispc'; }
|
||||
static get key() {
|
||||
return 'ispc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
|
||||
@@ -50,8 +50,9 @@ export class KotlinCompiler extends JavaCompiler {
|
||||
|
||||
filterUserOptions(userOptions) {
|
||||
// filter options without extra arguments
|
||||
userOptions = (userOptions || []).filter(option =>
|
||||
option !== '-script' && option !== '-progressive' && !option.startsWith('-Xjavac'));
|
||||
userOptions = (userOptions || []).filter(
|
||||
option => option !== '-script' && option !== '-progressive' && !option.startsWith('-Xjavac'),
|
||||
);
|
||||
|
||||
const oneArgForbiddenList = new Set([
|
||||
// -jdk-home path
|
||||
@@ -72,9 +73,7 @@ export class KotlinCompiler extends JavaCompiler {
|
||||
// Forcibly enable javap
|
||||
filters.binary = true;
|
||||
|
||||
return [
|
||||
'-Xjavac-arguments="-Xlint:all"',
|
||||
];
|
||||
return ['-Xjavac-arguments="-Xlint:all"'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,9 @@ import { logger } from '../logger';
|
||||
import {ClangParser} from './argument-parsers';
|
||||
|
||||
export class LDCCompiler extends BaseCompiler {
|
||||
static get key() { return 'ldc'; }
|
||||
static get key() {
|
||||
return 'ldc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -76,7 +78,8 @@ export class LDCCompiler extends BaseCompiler {
|
||||
const newOptions = options.concat('-vcg-ast');
|
||||
const execOptions = this.getDefaultExecOptions();
|
||||
return this.loadASTOutput(
|
||||
await this.runCompiler(this.compiler.exe, newOptions, this.filename(inputFilename), execOptions));
|
||||
await this.runCompiler(this.compiler.exe, newOptions, this.filename(inputFilename), execOptions),
|
||||
);
|
||||
}
|
||||
|
||||
async loadASTOutput(output) {
|
||||
@@ -99,7 +102,6 @@ export class LDCCompiler extends BaseCompiler {
|
||||
|
||||
// Override the IR file name method for LDC because the output file is different from clang.
|
||||
getIrOutputFilename(inputFilename) {
|
||||
return this.getOutputFilename(path.dirname(inputFilename), this.outputFilebase)
|
||||
.replace('.s', '.ll');
|
||||
return this.getOutputFilename(path.dirname(inputFilename), this.outputFilebase).replace('.s', '.ll');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {ClangParser} from './argument-parsers';
|
||||
|
||||
export class LLCCompiler extends BaseCompiler {
|
||||
static get key() { return 'llc'; }
|
||||
static get key() {
|
||||
return 'llc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
|
||||
@@ -27,9 +27,13 @@ import { ClangParser } from './argument-parsers';
|
||||
|
||||
// Plain compiler, which just runs the tool and returns whatever the output was
|
||||
export class LLVMmcaTool extends AnalysisTool {
|
||||
static get key() { return 'llvm-mca'; }
|
||||
static get key() {
|
||||
return 'llvm-mca';
|
||||
}
|
||||
|
||||
supportsObjdump() { return false; }
|
||||
supportsObjdump() {
|
||||
return false;
|
||||
}
|
||||
|
||||
getOutputFilenameArgs(filename) {
|
||||
// TODO: Some tools might require an argument of the form -arg=filename
|
||||
|
||||
@@ -29,19 +29,29 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {MrustcParser} from './argument-parsers';
|
||||
|
||||
export class MrustcCompiler extends BaseCompiler {
|
||||
static get key() { return 'mrustc'; }
|
||||
static get key() {
|
||||
return 'mrustc';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
// mrustc always dumps the C code for <baseout> target in the <baseout>.c file.
|
||||
// In our case, the actual file in -o is not even created because we are
|
||||
// faking the last step (C compilation).
|
||||
// Craft the 'outname' to have the intermediate .c file writen in outputFilename.
|
||||
let outname = path.join(path.dirname(this.filename(outputFilename)),
|
||||
path.basename(this.filename(outputFilename), '.c'));
|
||||
let outname = path.join(
|
||||
path.dirname(this.filename(outputFilename)),
|
||||
path.basename(this.filename(outputFilename), '.c'),
|
||||
);
|
||||
|
||||
// Currently always targets a rlib, no binary support at the moment.
|
||||
return ['--crate-type', 'rlib',
|
||||
'-o', outname, '-L', path.join(path.dirname(this.compiler.exe), '..', 'output')];
|
||||
return [
|
||||
'--crate-type',
|
||||
'rlib',
|
||||
'-o',
|
||||
outname,
|
||||
'-L',
|
||||
path.join(path.dirname(this.compiler.exe), '..', 'output'),
|
||||
];
|
||||
}
|
||||
|
||||
async runCompiler(compiler, options, inputFilename, execOptions) {
|
||||
@@ -59,5 +69,4 @@ export class MrustcCompiler extends BaseCompiler {
|
||||
getArgumentParser() {
|
||||
return MrustcParser;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,11 +29,19 @@ import * as utils from '../utils';
|
||||
import {AssemblyCompiler} from './assembly';
|
||||
|
||||
export class NasmCompiler extends AssemblyCompiler {
|
||||
static get key() { return 'nasm'; }
|
||||
static get key() {
|
||||
return 'nasm';
|
||||
}
|
||||
|
||||
prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) {
|
||||
let options = super.prepareArguments(userOptions, filters, backendOptions, inputFilename,
|
||||
outputFilename, libraries);
|
||||
let options = super.prepareArguments(
|
||||
userOptions,
|
||||
filters,
|
||||
backendOptions,
|
||||
inputFilename,
|
||||
outputFilename,
|
||||
libraries,
|
||||
);
|
||||
|
||||
let fmode;
|
||||
if (options.includes('-felf')) {
|
||||
|
||||
@@ -30,7 +30,9 @@ import { SassAsmParser } from '../parsers/asm-parser-sass';
|
||||
import {ClangParser} from './argument-parsers';
|
||||
|
||||
export class NvccCompiler extends BaseCompiler {
|
||||
static get key() { return 'nvcc'; }
|
||||
static get key() {
|
||||
return 'nvcc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
|
||||
@@ -27,7 +27,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {PascalParser} from './argument-parsers';
|
||||
|
||||
export class OCamlCompiler extends BaseCompiler {
|
||||
static get key() { return 'ocaml'; }
|
||||
static get key() {
|
||||
return 'ocaml';
|
||||
}
|
||||
|
||||
constructor(compilerInfo, env) {
|
||||
super(compilerInfo, env);
|
||||
|
||||
@@ -27,7 +27,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {ClangParser} from './argument-parsers';
|
||||
|
||||
export class OptCompiler extends BaseCompiler {
|
||||
static get key() { return 'opt'; }
|
||||
static get key() {
|
||||
return 'opt';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
return ['-o', this.filename(outputFilename), '-S'];
|
||||
|
||||
@@ -27,9 +27,13 @@ import { BaseParser } from './argument-parsers';
|
||||
|
||||
// Plain compiler, which just runs the tool and returns whatever the output was
|
||||
export class OSACATool extends AnalysisTool {
|
||||
static get key() { return 'osaca'; }
|
||||
static get key() {
|
||||
return 'osaca';
|
||||
}
|
||||
|
||||
supportsObjdump() { return false; }
|
||||
supportsObjdump() {
|
||||
return false;
|
||||
}
|
||||
|
||||
getOutputFilenameArgs(filename) {
|
||||
return ['-o', filename];
|
||||
|
||||
@@ -34,7 +34,9 @@ import * as utils from '../utils';
|
||||
import {PascalUtils} from './pascal-utils';
|
||||
|
||||
export class PascalWinCompiler extends BaseCompiler {
|
||||
static get key() { return 'pascal-win'; }
|
||||
static get key() {
|
||||
return 'pascal-win';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -91,8 +93,7 @@ export class PascalWinCompiler extends BaseCompiler {
|
||||
|
||||
let args = ['-d', outputFilename];
|
||||
if (intelAsm) args = args.concat(['-M', 'intel']);
|
||||
return this.exec(this.compiler.objdumper, args, {maxOutput: 1024 * 1024 * 1024})
|
||||
.then((objResult) => {
|
||||
return this.exec(this.compiler.objdumper, args, {maxOutput: 1024 * 1024 * 1024}).then(objResult => {
|
||||
if (objResult.code !== 0) {
|
||||
result.asm = '<No output: objdump returned ' + objResult.code + '>';
|
||||
} else {
|
||||
@@ -104,11 +105,14 @@ export class PascalWinCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
async saveDummyProjectFile(filename, unitName, unitPath) {
|
||||
await fs.writeFile(filename,
|
||||
await fs.writeFile(
|
||||
filename,
|
||||
// prettier-ignore
|
||||
'program prog;\n' +
|
||||
'uses ' + unitName + ' in \'' + unitPath + '\';\n' +
|
||||
'begin\n' +
|
||||
'end.\n');
|
||||
'end.\n',
|
||||
);
|
||||
}
|
||||
|
||||
async writeAllFiles(dirPath, source, files, filters) {
|
||||
@@ -159,19 +163,12 @@ export class PascalWinCompiler extends BaseCompiler {
|
||||
|
||||
options.pop();
|
||||
|
||||
options.unshift(
|
||||
'-CC',
|
||||
'-W',
|
||||
'-H',
|
||||
'-GD',
|
||||
'-$D+',
|
||||
'-V',
|
||||
'-B');
|
||||
options.unshift('-CC', '-W', '-H', '-GD', '-$D+', '-V', '-B');
|
||||
|
||||
options.push(projectFile);
|
||||
execOptions.customCwd = tempPath;
|
||||
|
||||
return this.exec(compiler, options, execOptions).then((result) => {
|
||||
return this.exec(compiler, options, execOptions).then(result => {
|
||||
result.inputFilename = inputFilename;
|
||||
result.stdout = utils.parseOutput(result.stdout, inputFilename);
|
||||
result.stderr = utils.parseOutput(result.stderr, inputFilename);
|
||||
@@ -182,7 +179,7 @@ export class PascalWinCompiler extends BaseCompiler {
|
||||
optionsForFilter(filters) {
|
||||
filters.binary = true;
|
||||
filters.dontMaskFilenames = true;
|
||||
filters.preProcessBinaryAsmLines = (asmLines) => {
|
||||
filters.preProcessBinaryAsmLines = asmLines => {
|
||||
const mapFileReader = new MapFileReaderDelphi(this.mapFilename);
|
||||
const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader, false);
|
||||
reconstructor.run('output');
|
||||
|
||||
@@ -113,12 +113,9 @@ export class FPCCompiler extends BaseCompiler {
|
||||
const lastLinefeedBeforeStart = input.lastIndexOf('\n', relevantAsmStartsAt);
|
||||
if (lastLinefeedBeforeStart !== -1) {
|
||||
input =
|
||||
input.substr(0, input.indexOf('00000000004')) + '\n' +
|
||||
input.substr(lastLinefeedBeforeStart + 1);
|
||||
input.substr(0, input.indexOf('00000000004')) + '\n' + input.substr(lastLinefeedBeforeStart + 1);
|
||||
} else {
|
||||
input =
|
||||
input.substr(0, input.indexOf('00000000004')) + '\n' +
|
||||
input.substr(relevantAsmStartsAt);
|
||||
input = input.substr(0, input.indexOf('00000000004')) + '\n' + input.substr(relevantAsmStartsAt);
|
||||
}
|
||||
}
|
||||
return input;
|
||||
@@ -129,11 +126,14 @@ export class FPCCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
async saveDummyProjectFile(filename, unitName, unitPath) {
|
||||
await fs.writeFile(filename,
|
||||
await fs.writeFile(
|
||||
filename,
|
||||
// prettier-ignore
|
||||
'program prog;\n' +
|
||||
'uses ' + unitName + ' in \'' + unitPath + '\';\n' +
|
||||
'begin\n' +
|
||||
'end.\n');
|
||||
'end.\n',
|
||||
);
|
||||
}
|
||||
|
||||
async writeAllFiles(dirPath, source, files, filters) {
|
||||
|
||||
@@ -26,17 +26,15 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import * as exec from '../exec';
|
||||
import {logger} from '../logger';
|
||||
|
||||
const forbiddenOptions = new Set([
|
||||
'--report',
|
||||
'--text-report',
|
||||
'--html-report',
|
||||
]);
|
||||
const forbiddenOptions = new Set(['--report', '--text-report', '--html-report']);
|
||||
|
||||
export class PPCICompiler extends BaseCompiler {
|
||||
static get key() { return 'ppci'; }
|
||||
static get key() {
|
||||
return 'ppci';
|
||||
}
|
||||
|
||||
filterUserOptions(args) {
|
||||
return args.filter((item) => {
|
||||
return args.filter(item => {
|
||||
if (typeof item !== 'string') return true;
|
||||
|
||||
return !forbiddenOptions.has(item.toLowerCase());
|
||||
|
||||
@@ -111,8 +111,7 @@ export class PtxAssembler extends BaseCompiler {
|
||||
async objdump(outputFilename, result, maxSize) {
|
||||
const dirPath = path.dirname(outputFilename);
|
||||
let args = ['-c', '-g', '-hex', outputFilename];
|
||||
const objResult = await this.exec(
|
||||
this.compiler.objdumper, args, {maxOutput: maxSize, customCwd: dirPath});
|
||||
const objResult = await this.exec(this.compiler.objdumper, args, {maxOutput: maxSize, customCwd: dirPath});
|
||||
result.asm = objResult.stdout;
|
||||
if (objResult.code !== 0) {
|
||||
result.asm = '<No output: objdump returned ' + objResult.code + '>';
|
||||
|
||||
@@ -28,7 +28,9 @@ import { resolvePathFromAppRoot } from '../utils';
|
||||
import {BaseParser} from './argument-parsers';
|
||||
|
||||
export class PythonCompiler extends BaseCompiler {
|
||||
static get key() { return 'python'; }
|
||||
static get key() {
|
||||
return 'python';
|
||||
}
|
||||
|
||||
constructor(compilerInfo, env) {
|
||||
super(compilerInfo, env);
|
||||
@@ -69,11 +71,7 @@ export class PythonCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
return ['-I',
|
||||
this.disasmScriptPath,
|
||||
'--outputfile',
|
||||
outputFilename,
|
||||
'--inputfile'];
|
||||
return ['-I', this.disasmScriptPath, '--outputfile', outputFilename, '--inputfile'];
|
||||
}
|
||||
|
||||
getArgumentParser() {
|
||||
|
||||
@@ -30,7 +30,9 @@ import { resolvePathFromAppRoot } from '../utils';
|
||||
import {BaseParser} from './argument-parsers';
|
||||
|
||||
export class RubyCompiler extends BaseCompiler {
|
||||
static get key() { return 'ruby'; }
|
||||
static get key() {
|
||||
return 'ruby';
|
||||
}
|
||||
|
||||
constructor(compilerInfo, env) {
|
||||
super(compilerInfo, env);
|
||||
@@ -82,7 +84,8 @@ export class RubyCompiler extends BaseCompiler {
|
||||
outputFilename,
|
||||
'--fname',
|
||||
path.basename(this.compileFilename),
|
||||
'--inputfile'];
|
||||
'--inputfile',
|
||||
];
|
||||
}
|
||||
|
||||
getArgumentParser() {
|
||||
|
||||
@@ -32,7 +32,9 @@ import { parseRustOutput } from '../utils';
|
||||
import {RustParser} from './argument-parsers';
|
||||
|
||||
export class RustCompiler extends BaseCompiler {
|
||||
static get key() { return 'rust'; }
|
||||
static get key() {
|
||||
return 'rust';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -87,8 +89,7 @@ export class RustCompiler extends BaseCompiler {
|
||||
|
||||
// Override the IR file name method for rustc because the output file is different from clang.
|
||||
getIrOutputFilename(inputFilename) {
|
||||
return this.getOutputFilename(path.dirname(inputFilename), this.outputFilebase)
|
||||
.replace('.s', '.ll');
|
||||
return this.getOutputFilename(path.dirname(inputFilename), this.outputFilebase).replace('.s', '.ll');
|
||||
}
|
||||
|
||||
getArgumentParser() {
|
||||
|
||||
@@ -27,7 +27,9 @@ import path from 'path';
|
||||
import {RustCompiler} from './rust';
|
||||
|
||||
export class RustcCgGCCCompiler extends RustCompiler {
|
||||
static get key() { return 'rustc-cg-gcc'; }
|
||||
static get key() {
|
||||
return 'rustc-cg-gcc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -54,13 +56,20 @@ export class RustcCgGCCCompiler extends RustCompiler {
|
||||
// See https://github.com/antoyo/rustc_codegen_gcc
|
||||
let toolroot = path.resolve(path.dirname(this.compiler.exe), '..');
|
||||
|
||||
let options = ['-C', 'panic=abort',
|
||||
'-Z', 'codegen-backend=librustc_codegen_gcc.so',
|
||||
'--sysroot', toolroot + '/sysroot' ];
|
||||
let options = [
|
||||
'-C',
|
||||
'panic=abort',
|
||||
'-Z',
|
||||
'codegen-backend=librustc_codegen_gcc.so',
|
||||
'--sysroot',
|
||||
toolroot + '/sysroot',
|
||||
];
|
||||
|
||||
// rust.js makes the asumption that LLVM is used. This may go away when cranelift is available.
|
||||
// Until this is the case and the super() class is refactored, simply ditch -Cllvm arg.
|
||||
let super_options = super.optionsForFilter(filters, outputFilename, userOptions).filter(arg => !/-Cllvm.*/.test(arg));
|
||||
let super_options = super
|
||||
.optionsForFilter(filters, outputFilename, userOptions)
|
||||
.filter(arg => !/-Cllvm.*/.test(arg));
|
||||
options = options.concat(super_options);
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ export class ScalaCompiler extends JavaCompiler {
|
||||
|
||||
filterUserOptions(userOptions) {
|
||||
// filter options without extra arguments
|
||||
userOptions = userOptions.filter(option =>
|
||||
option !== '-Xscript');
|
||||
userOptions = userOptions.filter(option => option !== '-Xscript');
|
||||
|
||||
const oneArgForbiddenList = new Set([
|
||||
// -d directory
|
||||
@@ -67,13 +66,9 @@ export class ScalaCompiler extends JavaCompiler {
|
||||
// Forcibly enable javap
|
||||
filters.binary = true;
|
||||
|
||||
const scala2Opts = [
|
||||
'-Xlint:_',
|
||||
];
|
||||
const scala2Opts = ['-Xlint:_'];
|
||||
|
||||
const scala3Opts = [
|
||||
'-deprecation',
|
||||
];
|
||||
const scala3Opts = ['-deprecation'];
|
||||
|
||||
return Semver.gte(asSafeVer(this.compiler.semver), '3.0.0', true) ? scala3Opts : scala2Opts;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
import {GCCCompiler} from './gcc';
|
||||
|
||||
export class SdccCompiler extends GCCCompiler {
|
||||
static get key() { return 'sdcc'; }
|
||||
static get key() {
|
||||
return 'sdcc';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
let options = ['-o', this.filename(outputFilename)];
|
||||
|
||||
@@ -31,7 +31,9 @@ import { logger } from '../logger';
|
||||
import * as utils from '../utils';
|
||||
|
||||
export class SPIRVCompiler extends BaseCompiler {
|
||||
static get key() { return 'spirv'; }
|
||||
static get key() {
|
||||
return 'spirv';
|
||||
}
|
||||
|
||||
constructor(compilerInfo, env) {
|
||||
super(compilerInfo, env);
|
||||
@@ -45,8 +47,10 @@ export class SPIRVCompiler extends BaseCompiler {
|
||||
backendOptions = backendOptions || {};
|
||||
|
||||
if (this.compiler.options) {
|
||||
let compilerOptions = _.filter(utils.splitArguments(this.compiler.options), option =>
|
||||
option !== '-fno-crash-diagnostics');
|
||||
let compilerOptions = _.filter(
|
||||
utils.splitArguments(this.compiler.options),
|
||||
option => option !== '-fno-crash-diagnostics',
|
||||
);
|
||||
|
||||
options = options.concat(compilerOptions);
|
||||
}
|
||||
@@ -68,20 +72,21 @@ export class SPIRVCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
userOptions = this.filterUserOptions(userOptions) || [];
|
||||
return options.concat(libIncludes, libOptions, libPaths, libLinks, userOptions,
|
||||
[this.filename(inputFilename)], staticLibLinks);
|
||||
return options.concat(
|
||||
libIncludes,
|
||||
libOptions,
|
||||
libPaths,
|
||||
libLinks,
|
||||
userOptions,
|
||||
[this.filename(inputFilename)],
|
||||
staticLibLinks,
|
||||
);
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
const sourceDir = path.dirname(outputFilename);
|
||||
const bitcodeFilename = path.join(sourceDir, this.outputFilebase + '.bc');
|
||||
return [
|
||||
'-cc1',
|
||||
'-debug-info-kind=limited',
|
||||
'-dwarf-version=5',
|
||||
'-debugger-tuning=gdb',
|
||||
'-o', bitcodeFilename,
|
||||
];
|
||||
return ['-cc1', '-debug-info-kind=limited', '-dwarf-version=5', '-debugger-tuning=gdb', '-o', bitcodeFilename];
|
||||
}
|
||||
|
||||
getPrimaryOutputFilename(dirPath, outputFilebase) {
|
||||
@@ -160,25 +165,28 @@ export class SPIRVCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
async generateAST(inputFilename, options) {
|
||||
const newOptions = _.filter(options, option => option !== '-fcolor-diagnostics')
|
||||
.concat(['-ast-dump']);
|
||||
const newOptions = _.filter(options, option => option !== '-fcolor-diagnostics').concat(['-ast-dump']);
|
||||
|
||||
const execOptions = this.getDefaultExecOptions();
|
||||
execOptions.maxOutput = 1024 * 1024 * 1024;
|
||||
|
||||
return this.llvmAst.processAst(
|
||||
await this.runCompilerForASTOrIR(this.compiler.exe, newOptions, this.filename(inputFilename), execOptions));
|
||||
await this.runCompilerForASTOrIR(this.compiler.exe, newOptions, this.filename(inputFilename), execOptions),
|
||||
);
|
||||
}
|
||||
|
||||
async generateIR(inputFilename, options, filters) {
|
||||
const newOptions = _.filter(options, option => option !== '-fcolor-diagnostics')
|
||||
.concat('-emit-llvm');
|
||||
const newOptions = _.filter(options, option => option !== '-fcolor-diagnostics').concat('-emit-llvm');
|
||||
|
||||
const execOptions = this.getDefaultExecOptions();
|
||||
execOptions.maxOutput = 1024 * 1024 * 1024;
|
||||
|
||||
const output = await this.runCompilerForASTOrIR(
|
||||
this.compiler.exe, newOptions, this.filename(inputFilename), execOptions);
|
||||
this.compiler.exe,
|
||||
newOptions,
|
||||
this.filename(inputFilename),
|
||||
execOptions,
|
||||
);
|
||||
if (output.code !== 0) {
|
||||
logger.error('Failed to run compiler to get IR code');
|
||||
return output.stderr;
|
||||
|
||||
@@ -27,7 +27,9 @@ import { BaseCompiler } from '../base-compiler';
|
||||
import {ClangParser} from './argument-parsers';
|
||||
|
||||
export class SwiftCompiler extends BaseCompiler {
|
||||
static get key() { return 'swift'; }
|
||||
static get key() {
|
||||
return 'swift';
|
||||
}
|
||||
|
||||
getSharedLibraryPathsAsArguments() {
|
||||
return [];
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
import {GCCCompiler} from './gcc';
|
||||
|
||||
export class TenDRACompiler extends GCCCompiler {
|
||||
static get key() { return 'tendra'; }
|
||||
static get key() {
|
||||
return 'tendra';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
let options = ['-o', this.filename(outputFilename)];
|
||||
|
||||
@@ -27,13 +27,15 @@ import _ from 'underscore';
|
||||
import {BaseCompiler} from '../base-compiler';
|
||||
|
||||
export class TinyCCompiler extends BaseCompiler {
|
||||
static get key() { return 'tinyc'; }
|
||||
static get key() {
|
||||
return 'tinyc';
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename, userOptions) {
|
||||
if (_.some(userOptions, (opt) => opt === '--help' || opt === '-h' || opt === '-hh')) {
|
||||
if (_.some(userOptions, opt => opt === '--help' || opt === '-h' || opt === '-hh')) {
|
||||
return [];
|
||||
} else {
|
||||
if (!_.some(userOptions, (opt) => opt === '-E')) {
|
||||
if (!_.some(userOptions, opt => opt === '-E')) {
|
||||
filters.binary = true;
|
||||
}
|
||||
return ['-g', '-o', this.filename(outputFilename)];
|
||||
@@ -41,6 +43,6 @@ export class TinyCCompiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
filterUserOptions(userOptions) {
|
||||
return _.filter(userOptions, (opt) => opt !== '-run');
|
||||
return _.filter(userOptions, opt => opt !== '-run');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,17 +37,18 @@ export class TypeScriptCompiler extends BaseCompiler {
|
||||
|
||||
async runCompiler(compiler, options, inputFilename, execOptions) {
|
||||
// These options make Clang produce an IR
|
||||
const newOptions = [
|
||||
'--emit=mlir-llvm',
|
||||
inputFilename,
|
||||
];
|
||||
const newOptions = ['--emit=mlir-llvm', inputFilename];
|
||||
|
||||
if (!this.tscSharedLib) {
|
||||
newOptions.push('-nogc');
|
||||
}
|
||||
|
||||
const output = await this.runCompilerRawOutput(
|
||||
this.tscJit, newOptions, this.filename(inputFilename), execOptions);
|
||||
this.tscJit,
|
||||
newOptions,
|
||||
this.filename(inputFilename),
|
||||
execOptions,
|
||||
);
|
||||
if (output.code !== 0) {
|
||||
return [{text: 'Failed to run compiler to get MLIR code'}];
|
||||
}
|
||||
@@ -57,10 +58,7 @@ export class TypeScriptCompiler extends BaseCompiler {
|
||||
|
||||
async generateIR(inputFilename, options, filters) {
|
||||
// These options make Clang produce an IR
|
||||
const newOptions = [
|
||||
'--emit=llvm',
|
||||
inputFilename,
|
||||
];
|
||||
const newOptions = ['--emit=llvm', inputFilename];
|
||||
|
||||
if (!this.tscSharedLib) {
|
||||
newOptions.push('-nogc');
|
||||
@@ -71,7 +69,11 @@ export class TypeScriptCompiler extends BaseCompiler {
|
||||
execOptions.maxOutput = 1024 * 1024 * 1024;
|
||||
|
||||
const output = await this.runCompilerRawOutput(
|
||||
this.tscJit, newOptions, this.filename(inputFilename), execOptions);
|
||||
this.tscJit,
|
||||
newOptions,
|
||||
this.filename(inputFilename),
|
||||
execOptions,
|
||||
);
|
||||
if (output.code !== 0) {
|
||||
return [{text: 'Failed to run compiler to get IR code'}];
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ import { VCParser } from './argument-parsers';
|
||||
import {Win32Compiler} from './win32';
|
||||
|
||||
export class Win32VcCompiler extends Win32Compiler {
|
||||
static get key() { return 'win32-vc'; }
|
||||
static get key() {
|
||||
return 'win32-vc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
|
||||
@@ -28,7 +28,9 @@ import { VCParser } from './argument-parsers';
|
||||
import {Win32Compiler} from './win32';
|
||||
|
||||
export class Win32Vc6Compiler extends Win32Compiler {
|
||||
static get key() { return 'win32-vc6'; }
|
||||
static get key() {
|
||||
return 'win32-vc6';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
|
||||
@@ -34,7 +34,9 @@ import { PELabelReconstructor } from '../pe32-support';
|
||||
import * as utils from '../utils';
|
||||
|
||||
export class Win32Compiler extends BaseCompiler {
|
||||
static get key() { return 'win32'; }
|
||||
static get key() {
|
||||
return 'win32';
|
||||
}
|
||||
|
||||
constructor(compilerInfo, env) {
|
||||
super(compilerInfo, env);
|
||||
@@ -45,10 +47,8 @@ export class Win32Compiler extends BaseCompiler {
|
||||
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);
|
||||
if (err) reject(`Unable to open temp file: ${err}`);
|
||||
else resolve(dirPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -68,22 +68,24 @@ export class Win32Compiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
getSharedLibraryLinks(libraries) {
|
||||
return _.flatten(_.map(libraries, (selectedLib) => {
|
||||
return _.flatten(
|
||||
_.map(libraries, selectedLib => {
|
||||
const foundVersion = this.findLibVersion(selectedLib);
|
||||
if (!foundVersion) return false;
|
||||
|
||||
return _.map(foundVersion.liblink, (lib) => {
|
||||
return _.map(foundVersion.liblink, lib => {
|
||||
if (lib) {
|
||||
return '"' + lib + '.lib"';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
getStaticLibraryLinks(libraries) {
|
||||
return _.map(super.getSortedStaticLibraries(libraries), (lib) => {
|
||||
return _.map(super.getSortedStaticLibraries(libraries), lib => {
|
||||
return '"' + lib + '.lib"';
|
||||
});
|
||||
}
|
||||
@@ -115,8 +117,16 @@ export class Win32Compiler extends BaseCompiler {
|
||||
}
|
||||
|
||||
userOptions = this.filterUserOptions(userOptions) || [];
|
||||
return options.concat(libIncludes, libOptions, userOptions, [this.filename(inputFilename)], preLink, libPaths,
|
||||
libLinks, staticlibLinks);
|
||||
return options.concat(
|
||||
libIncludes,
|
||||
libOptions,
|
||||
userOptions,
|
||||
[this.filename(inputFilename)],
|
||||
preLink,
|
||||
libPaths,
|
||||
libLinks,
|
||||
staticlibLinks,
|
||||
);
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
@@ -124,7 +134,7 @@ export class Win32Compiler extends BaseCompiler {
|
||||
const mapFilename = outputFilename + '.map';
|
||||
const mapFileReader = new MapFileReaderVS(mapFilename);
|
||||
|
||||
filters.preProcessBinaryAsmLines = (asmLines) => {
|
||||
filters.preProcessBinaryAsmLines = asmLines => {
|
||||
const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader);
|
||||
reconstructor.run('output.s.obj');
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ import { PELabelReconstructor } from '../pe32-support';
|
||||
import {VCParser} from './argument-parsers';
|
||||
|
||||
export class WineVcCompiler extends BaseCompiler {
|
||||
static get key() { return 'wine-vc'; }
|
||||
static get key() {
|
||||
return 'wine-vc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
info.supportsFiltersInBinary = true;
|
||||
@@ -75,7 +77,7 @@ export class WineVcCompiler extends BaseCompiler {
|
||||
const mapFilename = outputFilename + '.map';
|
||||
const mapFileReader = new MapFileReaderVS(mapFilename);
|
||||
|
||||
filters.preProcessBinaryAsmLines = (asmLines) => {
|
||||
filters.preProcessBinaryAsmLines = asmLines => {
|
||||
const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader);
|
||||
reconstructor.run('output.s.obj');
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ import { VcAsmParser } from '../parsers/asm-parser-vc';
|
||||
import {Win32VcCompiler} from './win32-vc';
|
||||
|
||||
export class WslVcCompiler extends Win32VcCompiler {
|
||||
static get key() { return 'wsl-vc'; }
|
||||
static get key() {
|
||||
return 'wsl-vc';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
@@ -56,10 +58,8 @@ export class WslVcCompiler extends Win32VcCompiler {
|
||||
newTempDir() {
|
||||
return new Promise((resolve, reject) => {
|
||||
temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.winTmp}, (err, dirPath) => {
|
||||
if (err)
|
||||
reject(`Unable to open temp file: ${err}`);
|
||||
else
|
||||
resolve(dirPath);
|
||||
if (err) reject(`Unable to open temp file: ${err}`);
|
||||
else resolve(dirPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
85
lib/csp.js
85
lib/csp.js
@@ -26,26 +26,73 @@ import _ from 'underscore';
|
||||
|
||||
export const data = {
|
||||
'default-src': ["'self'", 'https://*.godbolt.org', 'localhost:*', 'https://*.compiler-explorer.com'],
|
||||
'style-src': ["'self'", "'unsafe-inline'", 'https://*.godbolt.org', 'localhost:*',
|
||||
'https://*.compiler-explorer.com'],
|
||||
'script-src': ["'self'", "'unsafe-inline'", 'data:', 'https://*.godbolt.org', 'localhost:*',
|
||||
'style-src': [
|
||||
"'self'",
|
||||
"'unsafe-inline'",
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
'https://*.twitter.com', 'https://www.google-analytics.com',
|
||||
'https://apis.google.com', 'https://ssl.google-analytics.com', 'https://sentry.io/'],
|
||||
'img-src': ["'self'", 'https://*.godbolt.org', 'localhost:*',
|
||||
'https://*.compiler-explorer.com', 'data:', 'https://www.google-analytics.com/',
|
||||
'https://syndication.twitter.com', 'https://ssl.google-analytics.com', 'https://csi.gstatic.com'],
|
||||
'font-src': ["'self'", 'data:', 'https://*.godbolt.org', 'localhost:*',
|
||||
'https://*.compiler-explorer.com', 'https://fonts.gstatic.com',
|
||||
'https://themes.googleusercontent.com'],
|
||||
'frame-src': ["'self'", 'https://*.godbolt.org', 'localhost:*',
|
||||
'https://*.compiler-explorer.com', 'https://www.google-analytics.com',
|
||||
'https://accounts.google.com/', 'https://content.googleapis.com/',
|
||||
'https://sentry.io', 'https://platform.twitter.com/', 'https://syndication.twitter.com/'],
|
||||
'connect-src': ["'self'", '*', 'https://*.godbolt.org', 'localhost:*',
|
||||
'https://*.compiler-explorer.com', 'https://api.github.com'],
|
||||
'media-src': ["'self'", 'https://ssl.gstatic.com', 'https://*.godbolt.org', 'localhost:*',
|
||||
'https://*.compiler-explorer.com'],
|
||||
],
|
||||
'script-src': [
|
||||
"'self'",
|
||||
"'unsafe-inline'",
|
||||
'data:',
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
'https://*.twitter.com',
|
||||
'https://www.google-analytics.com',
|
||||
'https://apis.google.com',
|
||||
'https://ssl.google-analytics.com',
|
||||
'https://sentry.io/',
|
||||
],
|
||||
'img-src': [
|
||||
"'self'",
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
'data:',
|
||||
'https://www.google-analytics.com/',
|
||||
'https://syndication.twitter.com',
|
||||
'https://ssl.google-analytics.com',
|
||||
'https://csi.gstatic.com',
|
||||
],
|
||||
'font-src': [
|
||||
"'self'",
|
||||
'data:',
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
'https://fonts.gstatic.com',
|
||||
'https://themes.googleusercontent.com',
|
||||
],
|
||||
'frame-src': [
|
||||
"'self'",
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
'https://www.google-analytics.com',
|
||||
'https://accounts.google.com/',
|
||||
'https://content.googleapis.com/',
|
||||
'https://sentry.io',
|
||||
'https://platform.twitter.com/',
|
||||
'https://syndication.twitter.com/',
|
||||
],
|
||||
'connect-src': [
|
||||
"'self'",
|
||||
'*',
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
'https://api.github.com',
|
||||
],
|
||||
'media-src': [
|
||||
"'self'",
|
||||
'https://ssl.gstatic.com',
|
||||
'https://*.godbolt.org',
|
||||
'localhost:*',
|
||||
'https://*.compiler-explorer.com',
|
||||
],
|
||||
};
|
||||
|
||||
export const policy = _.map(data, (value, policyKey) => `${policyKey} ${value.join(' ')}`).join(';');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user