Difference between revisions of "System unit"

From Lazarus wiki
Jump to navigationJump to search
(→‎mandatory tasks of system unit: add note about internal procedures)
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
{{System_unit}}
 +
 
In [[FPC]] the <syntaxhighlight lang="pascal" enclose="none">system</syntaxhighlight> unit is the unit that is [[Uses|included]] by ''every'' [[Program|program]].
 
In [[FPC]] the <syntaxhighlight lang="pascal" enclose="none">system</syntaxhighlight> unit is the unit that is [[Uses|included]] by ''every'' [[Program|program]].
FPC's [[RTL|run-time library]] comes with a <syntaxhighlight lang="pascal" enclose="none">system</syntaxhighlight> unit where most, if not all of its functionalities work on on ''every'' available [[Platform list|platform]].
+
FPC's [[RTL|run-time library]] comes with a <syntaxhighlight lang="pascal" enclose="none">system</syntaxhighlight> unit where most, if not all of its functionalities work on ''every'' available [[Platform list|platform]].
  
 
== compilation of system units ==
 
== compilation of system units ==
 
To compile a system unit one calls FPC with the <syntaxhighlight lang="bash" enclose="none">-Us</syntaxhighlight> flag.
 
To compile a system unit one calls FPC with the <syntaxhighlight lang="bash" enclose="none">-Us</syntaxhighlight> flag.
This will tell the compiler that only basic type definitions are being done.
+
This will tell the compiler that only basic type definitions are being made, and including a system unit is skipped.
 
Types such as [[Integer|<syntaxhighlight lang="pascal" enclose="none">integer</syntaxhighlight>]] won't be available.
 
Types such as [[Integer|<syntaxhighlight lang="pascal" enclose="none">integer</syntaxhighlight>]] won't be available.
  
Line 22: Line 24:
 
The identifier <syntaxhighlight lang="pascal" enclose="none">operatingsystem_result</syntaxhighlight> has to be declared.
 
The identifier <syntaxhighlight lang="pascal" enclose="none">operatingsystem_result</syntaxhighlight> has to be declared.
 
The data stored at that position are communicated to the operating system as return value.
 
The data stored at that position are communicated to the operating system as return value.
 +
Whether <syntaxhighlight lang="pascal" enclose="none">hresult</syntaxhighlight> and <syntaxhighlight lang="pascal" enclose="none">operatingsystem_result</syntaxhighlight> are defined in the <syntaxhighlight lang="pascal" enclose="none">interface</syntaxhighlight> section is irrelevant.
 +
However, it is very plausible to put those into the <syntaxhighlight lang="pascal" enclose="none">interface</syntaxhighlight> section, so programs using this <syntaxhighlight lang="pascal" enclose="none">system</syntaxhighlight> unit can manipulate those.
 
<syntaxhighlight lang="pascal" line start="8">
 
<syntaxhighlight lang="pascal" line start="8">
 
var
 
var
Line 60: Line 64:
 
All functionality that can't be “implemented” by the compiler is gone.
 
All functionality that can't be “implemented” by the compiler is gone.
 
For example {{Doc|package=RTL|unit=system|identifier=addr|text=<syntaxhighlight lang="pascal" enclose="none">addr</syntaxhighlight>}} or {{Doc|package=RTL|unit=system|identifier=ord|text=<syntaxhighlight lang="pascal" enclose="none">ord</syntaxhighlight>}} still work, while {{Doc|package=RTL|unit=system|identifier=sin|text=<syntaxhighlight lang="pascal" enclose="none">sin</syntaxhighlight>}} or {{Doc|package=RTL|unit=system|identifier=random|text=<syntaxhighlight lang="pascal" enclose="none">random</syntaxhighlight>}} are not available.
 
For example {{Doc|package=RTL|unit=system|identifier=addr|text=<syntaxhighlight lang="pascal" enclose="none">addr</syntaxhighlight>}} or {{Doc|package=RTL|unit=system|identifier=ord|text=<syntaxhighlight lang="pascal" enclose="none">ord</syntaxhighlight>}} still work, while {{Doc|package=RTL|unit=system|identifier=sin|text=<syntaxhighlight lang="pascal" enclose="none">sin</syntaxhighlight>}} or {{Doc|package=RTL|unit=system|identifier=random|text=<syntaxhighlight lang="pascal" enclose="none">random</syntaxhighlight>}} are not available.
 +
Confer the procedure <syntaxhighlight lang="pascal" enclose="none">create_intern_symbols</syntaxhighlight> in <tt>compiler/psystem.pas</tt>.
  
{{Note|Depending on what your program uses, there might ''other'' mandatory tasks, too.}}
+
{{Note|Depending on what your program uses, there might ''other'' mandatory tasks, too.
 +
Especially OOP won't work without a functional <syntaxhighlight lang="pascal" enclose="none">objpas</syntaxhighlight> unit.}}
  
 
=== initialization and finalization of units ===
 
=== initialization and finalization of units ===
Line 78: Line 84:
 
         .quad  FINALIZE$_$SOMEUNIT
 
         .quad  FINALIZE$_$SOMEUNIT
 
</syntaxhighlight>
 
</syntaxhighlight>
For further investigations a look into an actual implementation helps:
+
For further investigations have a glimpse at an actual implementation helps:
 
[https://svn.freepascal.org/cgi-bin/viewvc.cgi/tags/release_3_0_4/rtl/inc/system.inc?view=markup#l862 <tt>rtl/inc/system.inc</tt>].
 
[https://svn.freepascal.org/cgi-bin/viewvc.cgi/tags/release_3_0_4/rtl/inc/system.inc?view=markup#l862 <tt>rtl/inc/system.inc</tt>].
  
Line 85: Line 91:
 
There is “smartlinking” if [[Size Matters|size matters]].
 
There is “smartlinking” if [[Size Matters|size matters]].
 
<!-- Help by [[Creating A Patch|creating a patch]] instead. -->}}
 
<!-- Help by [[Creating A Patch|creating a patch]] instead. -->}}
 +
 +
== comparative remarks ==
 +
Other compilers such as [[GNU Pascal|GPC]] or [[Delphi]] use similar constructs, but to varying extent, and the system unit is not necessarily named <syntaxhighlight lang="bash" enclose="none">system.pp</syntaxhighlight>.
  
 
== see also ==
 
== see also ==
Line 92: Line 101:
 
* [[RTL development articles]]
 
* [[RTL development articles]]
  
[[Category:Code]]
+
[[Category: Code]]
[[Category:FPC internals]]
 

Revision as of 21:33, 31 May 2020

English (en) français (fr)

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 every available platform.

compilation of system units

To compile a system unit one calls FPC with the -Us flag. This will tell the compiler that only basic type definitions are being made, and including a system unit is skipped. 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 hresult.

5type
6	hresult = longint;

The identifier operatingsystem_result has to be declared. The data stored at that position are communicated to the operating system as return value. Whether hresult and operatingsystem_result are defined in the interface section is irrelevant. However, it is very plausible to put those into the interface section, so programs using this system unit can manipulate those.

 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 initialization routines. 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 fpintres.pas:

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. For example addr or ord still work, while sin or random are not available. Confer the procedure create_intern_symbols in compiler/psystem.pas.

Light bulb  Note: Depending on what your program uses, there might other mandatory tasks, too.

Especially OOP won't work without a functional objpas unit.

initialization and finalization of units

For those who are curious, how to implement FPC_INITIALIZEUNITS: FPC puts into every program's data section a INITFINAL table. 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 have a glimpse at an actual implementation helps: rtl/inc/system.inc.

Light bulb  Note: In general, implementing an “own” system unit is a stupid idea. There is “smartlinking” if size matters.

comparative remarks

Other compilers such as GPC or Delphi use similar constructs, but to varying extent, and the system unit is not necessarily named system.pp.

see also