FPC compatibility

PXX targets full FPC-language compatibility — the Object Pascal language as Free Pascal accepts it. It does not aim at parity with the rest of FPC's world: the FPC RTL and package ecosystem, the object-file format, and the command-line interface are out of scope by design.

What usually ports well

Small Pascal programs using ordinary declarations, routines, records, arrays, classes, basic generics, exceptions, and simple units are the best fit.

{$mode objfpc} and -Mobjfpc are accepted as compatibility markers, as are fpc, tp, delphiunicode and pxx — PXX has one dialect and they all map onto it. {$mode delphi} is the one marker that changes behavior (two deltas, listed under modes).

Pascal dialects outside the FPC/Delphi family are not compiled as if they were inside it: {$mode iso} and {$mode extendedpascal} warn, {$mode macpas} is an error, and an unrecognised mode name is an error. Support for those is deferred rather than refused — see modes for why MacPas is the one that errors.

Porting checklist

Start with a small, direct compile:

./pxx program.pas program

If the program uses local units, add their directories explicitly:

./pxx -Fusrc -Fusrc/common program.pas program

For code that probes FPC identity symbols or expects FPC-style conditional branches, try the curated compatibility define set:

./pxx --mimic-fpc -Fuvendor/lib program.pas program

--mimic-fpc is opt-in. It is meant for FPC-oriented library code that chooses implementation branches by compiler identity. Do not use it as a blanket default for every PXX project, and do not use it to decide whether code is running under real Free Pascal.

Identity symbols

Symbol Meaning
PXX Defined by PXX.
FPC Not defined by PXX. Reserved for actual Free Pascal builds.

Use this pattern for compiler-specific code:

{$ifdef PXX}
  { PXX-specific path }
{$endif}

{$ifdef FPC}
  { Free Pascal-specific path }
{$endif}

Important differences

Hint directives

FPC hint modifiers on const, type, and routine declarations are accepted, and deprecated may carry a message string:

const OldLimit = 100 deprecated;
type  TLegacy = Integer platform;
procedure OldWay; deprecated 'use NewWay';
procedure Probe; experimental;

deprecated, platform, experimental, unimplemented, and library parse on those declarations. They are accepted for source compatibility; PXX does not yet emit a usage warning for them, and they are not accepted on var declarations.

These are one group among several. Which routine directives are inert, which change what is compiled, and which are rejected outright is tabulated under routine directivesvarargs in particular does not parse at all and needs removing when porting. Every calling-convention spelling now parses in every position, stdcall included, and so do the inert FPC directives noreturn, nostackframe, noinline, far, near and local.

Common fixes

Prefer these changes when moving small FPC examples to PXX:

Next