[lazarus] Package System

Mattias Gaertner nc-gaertnma at netcologne.de
Sat Feb 1 16:26:43 EST 2003

Hi all,

This mail should start the discussion how to implement the package system
for lazarus. Everyone is invited to join the discussion and comment it. 

What is a package:
- Delphi: a package is a specially compiled library used by applications,
the IDE or both. Delphi packages require compiler magic, which fpc is not
capable of at the moment and of course this magic is not OS independent.
- a lazarus package is a collection of units and components, containing
information how they can be compiled and how they can be used by projects or
other packages or the IDE. In contrary to Delphi, packages are not limited
to libraries and they can be OS independent.

A package contains:
- name (valid pascal identifier)
- title, author, description
- version: major + minor + release + build
- filenames plus file type (unit, text)
- icon file
- information how to compile/update the package:
  - compiler options to compile the package
  - codetools defines
  - package dependencies (= required packages)
- information how to be used in projects, other packages, IDE:
  - compiler options (e.g. path additions and linker options)
- flag 'auto update'. Automatically compile package, when one of its
required packages have changed.
- this information is stored in an xml file and will have the ending .lpk
for Lazarus PacKage.

To compile a lcl package there will be compiler options to add the lcl paths
and to put the .ppu/.ppw files into the output directory. Delphi defines one
output directory for all packages. Let's call the macro $(PkgDir). I think,
we should also support subdirectories. For instance, Tony can specify for
his package the output directory $(PkgDir)/tony. The IDE will auto create
this directory before package compilation. The package directory can be set
in the environment options.


- package dependencies:
When a project/package is to be compiled, the IDE should automatically check
if a required package has changed and should auto compile till it gets a
consistent state. For example: Project A depends on package B, B depends on
C, C was recompiled and A should be compiled. Then the IDE should ask the
user if package B should be recompiled (unless the auto update flag for
package B is set). To accelerate this step the IDE will save information,
when each package was compiled.   


Here are some ideas about the registration:

For Delphi compatibility we should support the 'register' procedure. That
means the user adds a 'procedure register;' into the interface section of a
unit, which register components, component editors, property editors, ... .
Delphi packages automatically call these procedures via compiler magic. fpc
can't do this magic for us, so we do lazarus magic:

When a package is compiled, the IDE automaticaly creates/updates the package
unit. This package unit looks somewhat like this:

{ automatically created by lazarus - do not edit }
unit LPK_packagename;

{$mode objfpc}{$H+}


  // all units in the package
  ComponentUnit1, ComponentUnit2, Unit3, Unit4,
  // the lazarus package registration unit


procedure Register;
  // all units with 'register'

  LazPkgSystem.RegisterPackage('packagename', at Register);


This package unit is only useful for the IDE and is not needed by
applications unless they need the package registration.

I suggest to create a <lazarusdir>/package sub directory and put all units
of the package system and also the LazPkgReg unit there.


Installing a package:
Because fpc does not fully support libs, we can't add/remove components at
runtime. We have
to restart the IDE. Gladly lazarus starts a lot quicker than Delphi. The
installation itself is done internally by adding the package unit to a uses
section. The IDE will have dialogs and will handle most of this
automatically just like Delphi.
For example:
To install a package the following five steps are needed: 
Open a package file, compile it, install it, compile IDE and restart. 
Normally a user will simply open the package file and click 'install'. The
IDE will automatically compile the package, then ask the user if the IDE
should be recompiled. After that the IDE gives a note, that the user can now
restart the IDE. 

Projects will get 'package dependencies'. This is simply a list of package
names plus minimum versions.

Missing points:
- design time / run time packages. Do we need this distinction?
- component icons: The current solution is to add a lazarus 
  resource with the classname. 
  Sufficient? Or is the risk of redefinition too big?
- Naming. For example: Maybe 'package dependencies' is not as
  readable as 'package requirements' or 'required packages'.
- IDE front end
- other things ...

I hope I did not forget too much,

More information about the Lazarus mailing list