feat(native): default to internal assembler and linker

The native backend now uses --assembler internal and --linker internal
by default when the user does not explicitly pass these flags. This
eliminates the dependency on external tools (gcc/as/ld) for native
backend compilation.

Also fixes a linker bug where writing to a currently-executing binary
on Linux would fail with EStreamError — the linker now calls
DeleteFile before creating the output file.
This commit is contained in:
Graeme Geldenhuys 2026-06-19 14:32:58 +01:00
parent dc19f39620
commit cf274eeb89
3 changed files with 13 additions and 2 deletions

View file

@ -81,10 +81,12 @@ type
OPDFEnabled: Boolean; { OPDF code shaping }
OPDFAsmFile: string; { OPDF sidecar path, if any }
UseInternalAsm: Boolean; { --assembler internal (native backend) }
AssemblerExplicit: Boolean; { True when user passed --assembler }
AssemblerChoiceBad: Boolean; { a --assembler value was given that is
neither 'internal' nor 'external'; the
native driver's ValidateOptions rejects it }
UseInternalLinker: Boolean; { --linker internal (native backend) }
LinkerExplicit: Boolean; { True when user passed --linker }
LinkerChoiceBad: Boolean; { --linker value not 'internal' or 'external' }
end;

View file

@ -291,6 +291,7 @@ begin
if AFlag = '--assembler' then
begin
AOpts.UseInternalAsm := (ANextArg = 'internal');
AOpts.AssemblerExplicit := True;
AOpts.AssemblerChoiceBad :=
(ANextArg <> 'internal') and (ANextArg <> 'external');
Result := oaConsumedValue;
@ -298,6 +299,7 @@ begin
else if AFlag = '--linker' then
begin
AOpts.UseInternalLinker := (ANextArg = 'internal');
AOpts.LinkerExplicit := True;
AOpts.LinkerChoiceBad :=
(ANextArg <> 'internal') and (ANextArg <> 'external');
Result := oaConsumedValue;
@ -309,9 +311,9 @@ end;
procedure TNativeBackendDriver.DescribeOptions(ALines: TStringList);
begin
ALines.Add(FormatFlagLine('--assembler <id>',
'internal | external (default: external)'));
'internal | external (default: internal)'));
ALines.Add(FormatFlagLine('--linker <id>',
'internal | external (default: external)'));
'internal | external (default: internal)'));
end;
function TNativeBackendDriver.ValidateOptions(AOpts: TBackendOpts): string;
@ -321,6 +323,11 @@ begin
Result := '--assembler must be ''internal'' or ''external'''
else if AOpts.LinkerChoiceBad then
Result := '--linker must be ''internal'' or ''external''';
if not AOpts.AssemblerExplicit then
AOpts.UseInternalAsm := True;
if not AOpts.LinkerExplicit then
AOpts.UseInternalLinker := True;
end;
initialization

View file

@ -2369,6 +2369,8 @@ var
FOut: TFileOutputStream;
begin
Bytes := Self.LinkToBytes(AEntryName);
if FileExists(AOutputPath) then
DeleteFile(AOutputPath);
FOut := TFileOutputStream.Create(AOutputPath);
try
FOut.Write(PChar(Bytes), Length(Bytes));