Overview of the Lazarus Package System
What is a lazarus package?
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 contrast to Delphi, packages are not limited to libraries and they can be OS independent. (Delphi Packages are specially compiled libraries used by applications, the IDE or both. Delphi packages require in-compiler support, which FPC is not capable of at the moment and of course this magic is OS dependent.)
Currently the Free Pascal compiler only supports static packages. Therefore you must compile and restart the IDE, each time a package is installed or uninstalled.
A lazarus package is identified/distinguished by the name and its version.
Q: Do I need to install a package?
A: You only need to install a package, if it contains designtime items, like components for the IDE component palette. If you don't use those items, you don't need to install the package. If you only want to use a package in your project, don't install it.
Q: I installed a package, but the IDE does not find the units
A: Installing a package means, the package is integrated into the IDE, not your project. These are separate things. To use a package in your project, use Project -> Project Inspector -> Add -> New Requirement. And uninstall the package, if it does not contain any IDE goodies.
To see the packagesystem in action and to get used to it, do the following:
Creating a new package:
- File->New... -> Package -> Standard Package
- A package editor opens
- Use the Save button at top left.
- Depending on your 'naming' setting in the 'environment options', the IDE will ask you to save the file lowercase. Say yes.
Congratulations: You have just created your first package!
Adding a new component:
- Use the Add button -> New component
- Choose a component in the ancestor type combobox. For instance: TBevel.
- Click Ok
- The file will be added to the package and opened in the editor
- Install the package by clicking the 'install' button in the top of the package editor.
- Lazarus will save the package and ask you, if the IDE should be rebuilt. Say yes.
- The packages are statically linked, so a restart of the IDE is needed.
- Restart Lazarus and see your new component in the component palette (For example: A TBevel1 will be on the 'Additional' page).
- If you do not see your new component in the component palette, it is most likely that you are not running the re-compiled version of Lazarus. You can set where Lazarus builds to in: Environment -> Environment options -> Files -> Lazarus directory. Instead of calling lazarus directly, you also can use startlazarus, which starts the newly created lazarus, for example the lazarus executable in the ~/.lazarus directory, if you don't have write access to the directory lazarus was installed into.
Congratulations: You have just installed your first package with your first package component.
- File->New... -> Package -> Standard Package
Creates a new package.
- Project -> Project Inspector
Here you can see, what packages are required by the currently open project. You can add new dependencies and remove unneeded ones.
- Run -> Compiler options -> Inherited
Here you can see what compiler options are inherited from which package.
- 'Open package' A dialog shows all open packages with their state. - 'Open package file' Open a .lpk file
- 'Open package of current unit' Open the .lpk file, that belongs to the file in the source editor - 'Open recent package' Open a recently open package file (lpk file)
- 'Add active unit to a package' Adds the unit in the source editor to a package - 'Package Graph' The package graph shows all open packages and their dependencies.
- 'Configure installed packages' Edit the list of packages installed in the IDE. Install or uninstall several packages at once.
Project -> Project Inspector
Here you can see and edit all packages used by the project.
Each Lazarus package has a .lpk file. A package is identified by its name and its version. The name must correspond to the lpk filename. For example:
Name: Package1, Version: 1.0, Filename: /home/.../package1.lpk.
- The IDE automatically creates the main source file (package1.pas). See below. The lpk file contains information about the required packages, the files it uses, how to compile them, and what is needed to use the package by other packages/projects. The directory where the lpk file is, is called the "package directory".
- The IDE maintains a list of all package files (<config directory>/packagelinks.xml). Everytime a package is opened in the IDE it will be added to this list. When a package is opened, the IDE automatically opens all required packages via this list.
- There are three base packages: FCL, LCL and SynEdit. These are parts of the IDE and so they are autocreated, readonly and have no lpk file.
- Normally a package has a source directory with some pascal units. And normally the lpk file will be there too. A package has also an output directory. Default is the subdirectory 'lib/$(TargetCPU)-$(TargetOS)/' in the package directory.
- Before a package is compiled the IDE checks all required packages and if they need update and have the auto update flag, they are compiled first. Then the IDE creates the package main source file. If the lpk file was package1.lpk, then the main source file is package1.pas. This file contains all units in the uses section plus a 'Register' procedure, which is called in the intialization section.
This file was automatically created by Lazarus. Do not edit! This source is only used to compile and install the package GTKOpenGL 1.0.
unit GTKOpenGL; interface uses GTKGLArea, GTKGLArea_Int, NVGL, NVGLX, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('GTKGLArea', @GTKGLArea.Register); end; initialization RegisterPackage('GTKOpenGL', @Register) end.
- Then the compiler is called and the package is compiled to the output directory.
- After successful compilation the state file is created. The state file is put into the output directory. It has the name <packagename>.compiled and contains the information, how the package was compiled. This state file is used by the IDE to check if update is needed.
For example: gtkopengl.compiled:
<?xml version="1.0"?> <CONFIG> <Compiler Value="/usr/bin/ppc386" Date="781388725"/> <Params Value=" -Rintel -S2cgi -CD -Ch8000000 -OG1p1 -Tlinux -gl -vewnhi -l -Fu../../../lcl/units -Fu../../../lcl/units/gtk -Fu../../../packager/units -Fu. -FElib/ gtkopengl.pas"/> </CONFIG>
- The IDE opens all needed packages automatically. This means, it opens all installed packages, all packages marked for installation (auto install), all packages with an open Editor, all packages required by the project and all packages required by one of the other packages. Unneeded packages are automatically unloaded, when the IDE becomes idle.
- The IDE never opens two packages with the same name at the same time. When the user opens another package file with the same name as an already opened package the IDE will ask to replace the old one.
- The IDE maintains two extra sets of packages: The 'installed' packages and the 'auto install' packages. The auto install packages will be linked into the IDE on next compile. It creates two new files in the config directory: staticpackages.inc and idemake.cfg. Then it calls 'make ide OPT=@/path/to/your/config/idemake.cfg' to compile itself.
Hints and Tips
Please add any hints, tips or gotchas here.
- To rename a package, use 'save as'.
I will use the tiOPF framework as an example The tiOPF has the following directory layout, due to the fact that it compiles for FPC, Delphi 5-7, D2005 and D2006. Source <= full path \Programming\3rdParty\tiOPF\Source \Compilers \Delphi7 <= Delphi 7 package files live here \D2005 \FPC <= the tiOPF.lpk lived here \Core <= core unit files \Options <= optional unit file for extra features \GUI Using this example, I included in the "Options - Usage - Units" editbox the following paths: "$(PkgOutDir);..\..\Core;..\..\Options;..\..\GUI" which will be added to whatever project uses this package.
Contributors and Comments
This page has been converted from the epikwiki version.