[fpc-devel] Packages, Generics

Sven Barth pascaldragon at googlemail.com
Mon Sep 13 15:03:10 CEST 2010

Am 13.09.2010 14:46, schrieb Dimitri Smits:
> ----- "Sven Barth"<pascaldragon at googlemail.com>  schreef:
>> Am 13.09.2010 11:44, schrieb Willibald Krenn:
>>> But enough about generics, back to packages: I'll start doing an
>> implementation for the non-generic part first. Let's see how this
>> goes. Since I need to read into fpc source (and do this in my spare
>> time), don't expect any spectacular results soon. In case there are
>> more people interested in implementing this, some branch in the repo
>> would be needed - if I am the only one, I will do this locally on my
>> disk.
>> You might want to start compiler/pmodules.pp. There is already some
>> code
>> to parse "package" projects and some code that allows all symbols to
>> be
>> exported (this code also appears in ppumove, but only for Linux and
>> DOS).
>> I've stumpled upon this code last week and tested it on a Linux
>> system.
>> Compiling a simple package with a single unit works if I use Win32 as
>> target. A .dll (wrong file extension) is generated which exports all
>> functions/procedures that are in the interface of my unit or the RTL
>> units, but no variables are exported although the Win32 target
>> supports
>> this (tested before the package). Using Linux as a target results in
>> an
>> internal error and I've not yet found the time to investigate this.
>> Also "requires" sections aren't parsed yet.
> how about "contains" sections?

"contains" works, because that is the only section besides "requires" 
that a package might contain (no "uses" allowed there).

>> In theory(!) it should be "rather" simple to implement shared cross
>> platform packages (those that are loaded on app startup by the OS and
>> not dynamically during the run).
> that would require a change in sysinit, sysutils&  system units as well, all types of linked-target modules (executable, shared lib, package) should "register" their moduleinfo ('hinstance' of the module, list of contained units' table entries =>  init, finit pointers) in startupcode for the module. shutdown code for the module should deregister that moduleinfo.
> for somewhat of a breakdown, look at TLibModule, LoadPackage, UnloadPackage and related functions for inspiration:
> http://docwiki.embarcadero.com/VCL/en/System.TLibModule
> http://docwiki.embarcadero.com/VCL/en/System.LibModuleList
> http://docwiki.embarcadero.com/VCL/en/System.RegisterModule
> http://docwiki.embarcadero.com/VCL/en/System.UnregisterModule
> http://docwiki.embarcadero.com/VCL/en/SysUtils.LoadPackage
> http://docwiki.embarcadero.com/VCL/en/SysUtils.UnloadPackage
> and related
> http://docwiki.embarcadero.com/VCL/XE/en/System.TModuleUnloadProc
> http://docwiki.embarcadero.com/VCL/XE/en/System.AddModuleUnloadProc
> http://docwiki.embarcadero.com/VCL/en/System.RemoveModuleUnloadProc
> http://docwiki.embarcadero.com/VCL/en/System.EnumModules
> http://docwiki.embarcadero.com/VCL/en/System.EnumResourceModules
> http://docwiki.embarcadero.com/VCL/en/SysUtils.InitializePackage
> http://docwiki.embarcadero.com/VCL/en/System.PackageInfoTable
> http://docwiki.embarcadero.com/VCL/en/System.UnitEntryTable
> http://docwiki.embarcadero.com/VCL/en/System.PackageUnitEntry
> sysinit, system, sysutils:
> the initialization of an executable/package/library needs to be completed with filling in the libmodule structure (needs to be generated as well) with the moduleid (portably!) and the pointer needs to be given to registermodule. In delphi a check occurs somewhere on all the "included" units of a package/dll/exe to see if there is a duplicate unit loaded.
> loadpackage does nothing more than dlopen() of a file, and then the resulting recently added libmodules that were added are then initialized by init-ing their unittable entries.
> conversely, unloadpackage finit's all those units and dlclose().
> finalization of an executable/package/library unhooks the libmodule
> addmoduleunloadproc/removemoduleunloadproc are invoked either by unloadpackage or by unregistermodule.

That's why I emphasized "in theory" and "rather" ^^

> as said before, inspiration can be had from how they do it, but that doesn't mean fpc should do it that way. Especially in a crossplatform context, and more so cross-architecture, it is not a one-size fits all per se.

Basically the package system needs the following:

- The ability to import/export functions, procedures AND variables from 
binaries (although export from shared library only should be 
sufficient). This works on Windows, but on Linux I had problems.
- The ability to declare init and finit procedures for shared images. 
This works on Windows with the entry point and on Linux with special 
symbols. I don't know about the other platforms.
- The ability to add the init/finit entries (which call the unit 
initialization/finalization sections) uniquely to the shared RTL and 
execute them. This is of yet a todo as it means a bit of work in the RTL.

The first two points must be provided by the platform/OS while the third 
one is defined by us (at best as the same for all platforms).

What would you do different/better then the Delphi developers when 
implementing such a package system in a crossplatform way?
I can't imagine currently what should be done additonally, but that 
might be because I don't use every feature that FPC provides. So please 
share your ideas. :)


More information about the fpc-devel mailing list