In FPC the
system unit is the unit that is included by every program.
FPC's run-time library comes with a
system unit where most, if not all of its functionalities work on on every available platform.
compilation of system units
To compile a system unit one calls FPC with the
This will tell the compiler that only basic type definitions are being done.
Types such as
integer won't be available.
mandatory tasks of system unit
If you attempt to create your own system unit, you'll incrementally notice what the compiler needs or what the generated code expects. On a Linux target, the minimal system unit has to contain:
1unit system; 2 3interface
The type definition of
5type 6 hresult = longint;
operatingsystem_result has to be declared.
The data stored at that position are communicated to the operating system as return value.
8var 9 exitCode: hresult = 0; export name 'operatingsystem_result'; 10 11implementation
Here comes to light what the system responsibilities are:
It has to initialize (or should) initialize units, that means call every unit's
For that the label
FPC_INITIALIZEUNITS has to be defined.
13procedure initializeUnits; alias: 'FPC_INITIALIZEUNITS'; 14begin 15end;
Also the label
FPC_DO_EXIT has to be defined.
Here, system unit programmers have the chance to finalize units.
17procedure doExit; alias: 'FPC_DO_EXIT'; 18begin 19end; 20 21end.
Furthermore FPC will possibly complain the unit
fpintres.pp were missing.
So create a file
1unit FPIntRes; 2interface 3implementation 4end.
After doing so, you can compile your system unit with
fpc -Us system.pas, or directly create an empty program and compile it to examine the impact on the binary's size.
On a x86-64 Linux target the executable had a size of 2744 bytes.
The big trade-off is no convenience.
All functionality that can't be “implemented” by the compiler is gone.
ord still work, while
random are not available.
initialization and finalization of units
For those who are curious, how to implement
FPC puts into every program's data section a
Compiling a program with the
-al flag will retain the assembler file.
Examining it you will encounter something like:
33.section .data.n_INITFINAL 34 .balign 8 35.globl INITFINAL 36 .type INITFINAL,@object 37INITFINAL: 38 .quad 1,0 39 .quad INIT$_$SOMEUNIT 40 .quad FINALIZE$_$SOMEUNIT
For further investigations a look into an actual implementation helps: rtl/inc/system.inc.