FPC compatibility
pxx targets full FPC language compatibility — the Object Pascal language, not FPC's RTL, packages, object-file format, or CLI. The frontend stays lax by default, and FPC-style strictness and identity are opt-in, so you turn them on only for code that needs them. This page covers the knobs; the reference doc below goes deeper. (For the live pass/skip numbers, see FPC conformance under Status.)
The knobs
| Flag / directive | Effect |
|---|---|
-Mobjfpc · {$mode objfpc} |
Accepted as Object Pascal compatibility markers (e.g. 32-bit Integer). |
-Fu<dir> |
Add unit search roots so a library's own units resolve. |
-dNAME · -uNAME |
Define / undefine a conditional symbol. |
--mimic-fpc · {$MIMIC FPC} |
Make pxx look and behave like FPC — see below. |
Granular strictness
pxx stays lax by default and lets you dial in FPC-style rigor one rule at a time, each with a matching opposite:
| Flag | Effect |
|---|---|
--strict |
Umbrella — turns on FPC-parity strictness (starting with forward-declaration ordering). |
--require-forward · --lax-decl-order |
Require a routine be declared above its use / relax that. |
--strict-overload · --permissive-overload |
Require an explicit overload; on overloaded routines / allow it implicit. |
--strict-visibility |
Enforce private / protected member access. |
--strict-case |
Enforce case rules. |
--strict-operator |
Enforce operator rules. |
--strict-ir · --no-strict-ir |
Toggle strict IR validation. |
--mimic-fpc bundles the FPC-appropriate subset of these on for you. This is not
the complete switch set — see the compiler modes
and directives references for the full
strict/lax/mimic model, and the CLI reference for
every flag.
Cheating FPC identity — --mimic-fpc
Plenty of real-world libraries branch on compiler identity rather than
capability: jedi.inc, Synapse and friends assume the compiler is either FPC or
Delphi, and without a hint they take a Delphi/Kylix path that pxx doesn't want.
--mimic-fpc installs the curated FPC 3.2.2 (x86-64 Linux) identity define
set — FPC, UNIX, ENDIAN_LITTLE, VER3 / VER3_2 / VER3_2_2,
FPC_FULLVERSION = 30202, … — so those identity probes select their FPC branch.
It also flips pxx into FPC-strict behaviour to match:
- forward-declaration ordering is required,
{$I+}I/O checking is on,- member visibility (
private/protected) is enforced.
{$MIMIC FPC} pins the exact same thing in-source, so a unit that needs it
carries its own switch.
Caveats
- It's opt-in, not a blanket default —
--mimic-fpcliterally definesFPCto fool identity probes, so never use{$ifdef FPC}to answer "am I real Free Pascal?"; it isn't. - It never applies during pxx's own self-build — there
{$ifdef FPC}genuinely means real FPC. - Delphi:
{$MIMIC DELPHI}is reserved but not yet implemented — only FPC mimicry exists today.
The full reference below is pulled from the documentation.
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. PXX does
not currently implement multiple Pascal semantic modes.
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
- The FPC RTL and package ecosystem are not bundled as compatible units.
- The CLI is PXX-specific; it does not emulate the full FPC command line.
- Unit/object/package binary compatibility with FPC is not provided.
- Some FPC directives are accepted only as comments or compatibility markers.
- Overflow (
{$Q+}), range ({$R+}), and IO ({$I+}) checking are implemented but opt-in per region and off in the lax default; several other compile-switch states are still inert markers. - Only tested project units and examples should be treated as supported.
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 directives — stdcall and varargs
in particular do not parse on a plain routine and need removing when porting.
Common fixes
Prefer these changes when moving small FPC examples to PXX:
- Replace implicit package assumptions with explicit
usesclauses and-Fusearch roots. - Keep compiler-specific branches under
{$ifdef PXX}or{$ifdef FPC}. - Avoid depending on FPC's full RTL surface unless the needed unit exists in
lib/rtl. - Build C-header or imported-library experiments separately from the first Pascal port; get the Pascal-only slice compiling first.