Friday, February 12, 2010

Work on 0.9.30: changes in resource handling

One of the big changes we have in the svn trunk (you'll get it with the 0.9.30 release) is the modified resource subsystem. Since the first time I tried Lazarus I felt a big displeasure regards the resource handling. I believe you had similar feeling too if you are an old Delphi developer. The main problem was that each lfm stream (Lazarus form) must be duplicated in a .lrs file which is included in unit initialization section. What is bad in this?
  • First of all lrs needs to be stored with your project and therefore eats the free space.
  • The second bad thing is initialization section - a special routine which is called on your program start. Thus your application will run 200 routines at the start if you have 200 forms. Not very nice if you care about the speed.
  • And the last is the amount of memory required for resources and how this memory is allocated. Lrs resources are stored both in the code of your executable (which loads on start) and a TList. Thus each resource is stored twice. Moreover when you add a new resource TList code needs to reallocate the memory used for all resources it has (look at TList.Grow).
All these problems are perfectly solved by the native resource support which is finally implemented by FPC 2.4.0 Starting from 2.4.0 release of FPC it is possible to include a form resource using the {$R *.lfm} (or {$R *.dfm} if you want to include a Delphi form resource) directive. Of course we don't need to store lrs file anymore, we don't initialization section and each resource is stored once in some section of your executable.

Since this way of resource handling is more effective we decided to use it by default in Lazarus. Of course we don't deprecate or remove in anyway lrs support. You are able to choose how to store the form resources in the project options dialog.

Warning: FPC 2.4.0 has 2 small bugs which are already fixed in the svn trunk (revisions 14805 and 14824). It opens all the resource files during linking and if you have small ulimit value you may see a linker error. To workaround the problem set ulimit to a bigger value. The second problem is that your project can't contain special symbols (like spaces) in the path.

Another rework we've made regards resources are the xp manifest, version info and project icon handling. Previously we created up to 5 files to add those resources to an executable: lrs file with an icon resource, rc file which included in turn manifest, version info and project icon files. So you had a whole zoo in the project directory. Now you have only a res and an icon files. We are building the res files ourself using the new FP package fcl-res. This mean also that we don't need finally to use windres. Res file is now used for all platforms while previosly rc was used for windows only and lrs for other platforms.

Warning: you need to remove {$ifdef windows}{$R you_project.rc}{$endif} from your lpr file manually (if you have it there). Maybe we'll implement a way to detect and remove that automatically before the release.

I want to summarize what advantages we have with the new resource support:
  1. Less garbage in the project directory and smaller size.
  2. Smaller and faster executables (because of no initialization sections).
  3. Less memory usage.
  4. Unified resource handling on all platforms.
As as special bonus for component developers I can note a possibility to use one form resource for both Delphi and Lazarus which can be included by {$R *.dfm} :)

This is a resource handling revolution, isn't it?