Units & Program Organization
21.1 Unit structure
Using it (main.pas, in the same folder):
unit Geometry;
{$mode objfpc}{$H+}
interface // public part: what other units see
type
TPoint2D = record
X, Y: Double;
end;
function Distance(const A, B: TPoint2D): Double;
function CallCount: Integer;
implementation // private part: bodies and hidden helpers
uses
Math; // used only by the implementation
var
FCalls: Integer; // unit-private global
function Distance(const A, B: TPoint2D): Double;
begin
Inc(FCalls);
Result := Hypot(A.X - B.X, A.Y - B.Y);
end;
function CallCount: Integer;
begin
Result := FCalls;
end;
initialization // runs once at program start (in dependency order)
FCalls := 0;
finalization // runs once at program exit (reverse order)
// release unit-level resources here
end.program Main;
{$mode objfpc}{$H+}
uses
Geometry;
var
A, B: TPoint2D;
begin
A.X := 0; A.Y := 0;
B.X := 3; B.Y := 4;
Writeln(Distance(A, B):0:1); // 5.0
Writeln(CallCount); // 1
end.21.2 Sections
must match the file name (geometry.pas; FPC on Linux prefers lowercase file names) public types, constants, variables, routine headings, class declarations routine and method bodies, private declarations uses (interface) units whose declarations the interface needs uses (implementation) units needed only by the implementation — prefer this; it also resolves circular references startup code (alternative: begin... end. at the end of the unit) cleanup code, runs only if initialization ran
21.3 Circular references
Two units cannot use each other in their interface sections. Solutions:
Move one uses to the implementation section.
Extract shared types into a third unit.
Use interfaces or abstract base classes to decouple.
21.4 Unit scope names and namespaces
Delphi organizes RTL/VCL units into dotted namespaces: System.SysUtils, System.Classes, Vcl.Forms, FMX.Forms, Data.DB. A project setting ("Unit scope names") lets you write SysUtils instead of System.SysUtils. FPC 3.2 uses the short names (SysUtils, Classes); recent FPC versions add dotted aliases. For code shared between both compilers, use the short names and add the unit scope names in Delphi.
21.5 Include files
Include files are used for shared compiler directives, platform-specific code fragments, and generated code. Prefer units for anything that declares types or routines.
{$I settings.inc} // textual inclusion (same as {$INCLUDE settings.inc})21.6 Compilation model
FPC compiles each unit to a .ppu (interface information) and .o (object code); Delphi produces .dcu files.
The compiler recompiles a unit only if its source or the interface of a unit it depends on changed — which is why Pascal builds are very fast.
Libraries: FPC library projects produce .dll/.so/.dylib; Delphi library and packages (.bpl) for design-time components and run-time modules.
21.7 A shared library
library MathLib;
{$mode objfpc}{$H+}
function AddInts(A, B: Integer): Integer; cdecl;
begin
Result := A + B;
end;
exports
AddInts;
end.