mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 09:23:52 -05:00
enables binary+execution for ADA (#1971)
* enables binary+execution for ADA * generic bandaid for missing executables * -eS commands are not errors * support error annotations * restore original default but add exec example * re-enable rpath * add tools
This commit is contained in:
@@ -4,8 +4,8 @@ defaultCompiler=gnat82
|
||||
demangler=/opt/compiler-explorer/gcc-9.1.0/bin/c++filt
|
||||
objdumper=/opt/compiler-explorer/gcc-9.1.0/bin/objdump
|
||||
versionFlag=--version
|
||||
supportsBinary=false
|
||||
supportsExecute=false
|
||||
supportsBinary=true
|
||||
supportsExecute=true
|
||||
intelAsm=-masm=intel
|
||||
compilerType=ada
|
||||
|
||||
@@ -27,3 +27,21 @@ compiler.gnatsnapshot.semver=(trunk)
|
||||
#################################
|
||||
# Installed libs (See c++.amazon.properties for a scheme of libs group)
|
||||
libs=
|
||||
|
||||
#################################
|
||||
# Tools
|
||||
tools=readelf:ldd
|
||||
|
||||
tools.readelf.name=readelf (trunk)
|
||||
tools.readelf.exe=/opt/compiler-explorer/gcc-snapshot/bin/readelf
|
||||
tools.readelf.type=postcompilation
|
||||
tools.readelf.class=readelf-tool
|
||||
tools.readelf.exclude=djggp
|
||||
tools.readelf.stdinHint=disabled
|
||||
|
||||
tools.ldd.name=ldd
|
||||
tools.ldd.exe=/usr/bin/ldd
|
||||
tools.ldd.type=postcompilation
|
||||
tools.ldd.class=readelf-tool
|
||||
tools.ldd.exclude=djggp
|
||||
tools.ldd.stdinHint=disabled
|
||||
|
||||
30
examples/ada/Square_Executable.adb
Normal file
30
examples/ada/Square_Executable.adb
Normal file
@@ -0,0 +1,30 @@
|
||||
with Ada.Command_Line;
|
||||
with Ada.Text_IO;
|
||||
|
||||
function Example return Integer is
|
||||
|
||||
function Square(num : Integer) return Integer is
|
||||
begin
|
||||
return num**2;
|
||||
end Square;
|
||||
|
||||
function ReadCmdArgumentOrDefault(default: Integer) return Integer is
|
||||
begin
|
||||
if Ada.Command_Line.Argument_Count > 0 then
|
||||
return Integer'Value(Ada.Command_Line.Argument(1));
|
||||
else
|
||||
return Default;
|
||||
end if;
|
||||
end ReadCmdArgumentOrDefault;
|
||||
|
||||
NumberToSquare: Integer;
|
||||
Answer: Integer;
|
||||
begin
|
||||
NumberToSquare := ReadCmdArgumentOrDefault(4);
|
||||
Ada.Text_IO.Put_Line("Number to square: " & NumberToSquare'Image);
|
||||
|
||||
Answer := Square(NumberToSquare);
|
||||
Ada.Text_IO.Put_Line("Square answer: " & Answer'Image);
|
||||
|
||||
return Answer;
|
||||
end Example;
|
||||
@@ -1,17 +1,17 @@
|
||||
-- This pragma will remove the warning produced by the default
|
||||
-- CE filename and the procedure name differing,
|
||||
-- see : https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gnat_rm/Pragma-Source_005fFile_005fName.html#Pragma-Source_005fFile_005fName
|
||||
pragma Source_File_Name (Square, Body_File_Name => "example.adb");
|
||||
|
||||
-- Type your code here, or load an example.
|
||||
function Square(num : Integer) return Integer is
|
||||
begin
|
||||
return num**2;
|
||||
end Square;
|
||||
|
||||
-- Ada 2012 also provides Expression Functions
|
||||
-- (http://www.ada-auth.org/standards/12rm/html/RM-6-8.html)
|
||||
-- as a short hand for functions whose body consists of a
|
||||
-- single return statement. However they cannot be used as a
|
||||
-- complication unit.
|
||||
-- function Square(num : Integer) return Integer is (num**2);
|
||||
-- This pragma will remove the warning produced by the default
|
||||
-- CE filename and the procedure name differing,
|
||||
-- see : https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gnat_rm/Pragma-Source_005fFile_005fName.html#Pragma-Source_005fFile_005fName
|
||||
pragma Source_File_Name (Square, Body_File_Name => "example.adb");
|
||||
|
||||
-- Type your code here, or load an example.
|
||||
function Square(num : Integer) return Integer is
|
||||
begin
|
||||
return num**2;
|
||||
end Square;
|
||||
|
||||
-- Ada 2012 also provides Expression Functions
|
||||
-- (http://www.ada-auth.org/standards/12rm/html/RM-6-8.html)
|
||||
-- as a short hand for functions whose body consists of a
|
||||
-- single return statement. However they cannot be used as a
|
||||
-- complication unit.
|
||||
-- function Square(num : Integer) return Integer is (num**2);
|
||||
|
||||
@@ -592,13 +592,28 @@ class BaseCompiler {
|
||||
const buildResult = await this.getOrBuildExecutable(key);
|
||||
if (buildResult.code !== 0) {
|
||||
return {
|
||||
code: 0,
|
||||
code: -1,
|
||||
didExecute: false,
|
||||
buildResult,
|
||||
stderr: [],
|
||||
stdout: []
|
||||
};
|
||||
} else {
|
||||
if (!fs.existsSync(buildResult.executableFilename)) {
|
||||
const verboseResult = {
|
||||
code: -1,
|
||||
didExecute: false,
|
||||
buildResult,
|
||||
stderr: [],
|
||||
stdout: []
|
||||
};
|
||||
|
||||
verboseResult.buildResult.stderr.push({text:"Compiler did not produce an executable"});
|
||||
|
||||
return verboseResult;
|
||||
}
|
||||
}
|
||||
|
||||
executeParameters.ldPath = this.getSharedLibraryPathsAsLdLibraryPaths(key.libraries);
|
||||
const result = await this.runExecutable(buildResult.executableFilename, executeParameters);
|
||||
result.didExecute = true;
|
||||
|
||||
@@ -33,32 +33,45 @@ class AdaCompiler extends BaseCompiler {
|
||||
this.compiler.supportsIntel = true;
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
let options = ['compile',
|
||||
'-g', // enable debugging
|
||||
'-c', // Compile only
|
||||
'-S', // Generate ASM
|
||||
'-fdiagnostics-color=always',
|
||||
'-fverbose-asm', // Geneate verbose ASM showing variables
|
||||
'-cargs', // Compiler Switches for gcc.
|
||||
'-o', // Set the output executable name
|
||||
outputFilename
|
||||
];
|
||||
if (this.compiler.intelAsm && filters.intel && !filters.binary) {
|
||||
options = options.concat(this.compiler.intelAsm.split(" "));
|
||||
}
|
||||
return options;
|
||||
getExecutableFilename(dirPath) {
|
||||
return path.join(dirPath, "example");
|
||||
}
|
||||
|
||||
// I have left the overloaded preProcess method in case there is a
|
||||
// need to any actual pre-processing of the input.
|
||||
// As Ada expects the outermost function name to match the source file name.
|
||||
// The initial solution was to wrap any input in a dummy example procedure,
|
||||
// this however restricts users from including standard library packages, as
|
||||
// Ada mandates that 'with' clauses are placed in the context clause,
|
||||
// which in the case of a single subprogram is outside of its declaration and body.
|
||||
preProcess(source) {
|
||||
return source;
|
||||
getOutputFilename(dirPath) {
|
||||
return path.join(dirPath, "example.o");
|
||||
}
|
||||
|
||||
optionsForFilter(filters, outputFilename) {
|
||||
let options = [];
|
||||
|
||||
if (!filters.binary) {
|
||||
options.push(
|
||||
'compile',
|
||||
'-g', // enable debugging
|
||||
'-S', // Generate ASM
|
||||
'-fdiagnostics-color=always',
|
||||
'-fverbose-asm', // Geneate verbose ASM showing variables
|
||||
'-c', // Compile only
|
||||
'-eS', // commands are not errors
|
||||
'-cargs', // Compiler Switches for gcc.
|
||||
'-o',
|
||||
outputFilename,
|
||||
);
|
||||
|
||||
if (this.compiler.intelAsm && filters.intel) {
|
||||
options = options.concat(this.compiler.intelAsm.split(" "));
|
||||
}
|
||||
} else {
|
||||
options.push(
|
||||
'make',
|
||||
'-eS',
|
||||
'-g',
|
||||
'example',
|
||||
'-cargs'
|
||||
);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
async runCompiler(compiler, options, inputFilename, execOptions) {
|
||||
@@ -67,6 +80,7 @@ class AdaCompiler extends BaseCompiler {
|
||||
}
|
||||
// Set the working directory to be the temp directory that has been created
|
||||
execOptions.customCwd = path.dirname(inputFilename);
|
||||
|
||||
// As the file name is always appended to the end of the options array we need to
|
||||
// find where the '-cargs' flag is in options. This is to allow us to set the
|
||||
// output as 'output.s' and not end up with 'example.s'. If the output is left
|
||||
@@ -78,10 +92,13 @@ class AdaCompiler extends BaseCompiler {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await this.exec(compiler, options, execOptions);
|
||||
result.inputFilename = inputFilename;
|
||||
result.stdout = utils.parseOutput(result.stdout, inputFilename);
|
||||
result.stderr = utils.parseOutput(result.stderr, inputFilename);
|
||||
|
||||
const baseFilename = path.basename(inputFileName);
|
||||
result.stdout = utils.parseOutput(result.stdout, baseFilename, execOptions.customCwd);
|
||||
result.stderr = utils.parseOutput(result.stderr, baseFilename, execOptions.customCwd);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user