OK, it seems FPC is reasonably safe in Debian now.
[...]
So, how about Lazarus ? [...] I quote:
"Version 4.4+dfsg-4 of lazarus is marked for autoremoval from testing on Fri 13 Mar 2026-...]"
Davo
as i raised in one of the other threads:
[...] btw - is it technically possible for a GUI application to be built such that it can detect the available widget sets and just use whatever one is available? ie, dynamically load the necessary libraries at run-time using dlopen/etc.
and Fred vS confirmed as possible:
[...] Yes, of course, it's possible (I've done it for X11 libraries), but it requires a bit of effort to convert the Pascal headers using "external" methods with the variable returned by `DynLibs.GetProcedureAddress()`.
Then, at init of the app, check which widget sets is installed using `DynLibs.LoadLibrary()`.
i have previously played around with adding a unit into a project1.lpr to run code prior to GTK's startup:
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads, // UNIX + CThreads
{$ENDIF}
start, // UNIX only, startup code before GTK is initialized (test)
{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, Unit1;
{$R *.res}
begin
RequireDerivedFormResource:=True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run
end.
for my testing the
start unit just printed out a greeting message to the console, which was sufficient to confirm that the greeting message was displayed
before GTK started complaining about spurious initialization errors - as it is inclined to do on occasion!
(as Fred vS says) a
start unit could detect the available widget set(s), and for whichever one is used (qt6 as 1st choice, fallback to qt5 as 2nd choice, fallback to GTK2 as final choice) build a table of entry points that can be made globally available. then someone would just need to go through all the source code for the Lazarus IDE and edit every
external statement to instead create function pointer variables (or whatever the term is!) using the entry point table created by the
start unit.
for accessing the ALSA sound system in one of my projects, a year or so back i converted code that previously used
EXTERNAL statements as follows:
// OLD VERSION, using external:
// function snd_pcm_open(pcm: PPsnd_pcm_t; name: PChar;
// stream: snd_pcm_stream_t; mode: cint): cint; cdecl; external libasound;
// [...]
// have now switched to "Dynamic Loading" on use, the following variables will hold the dynamically loaded ALSA methods
var snd_pcm_open:function(pcm: PPsnd_pcm_t; Name: PChar; stream: snd_pcm_stream_t; mode: cint): cint; cdecl;
[...]
ALSAhandle:TLibHandle={dynlibs.}NilHandle; // this will hold our handle for the ALSA library
procedure ALSAstartup;
var ALSAname:string='libasound.so.2';
begin
ALSAhandle:={DynLibs.}SafeLoadLibrary(ALSAname); // obtain the handle we want
if ALSAhandle<>{DynLibs.}NilHandle then // handle was obtained OK
begin // tie functions to the VARs from above
Pointer(snd_pcm_open):={DynLibs.}GetProcedureAddress(ALSAhandle, PChar('snd_pcm_open'));
[...]
end
end;
procedure ALSAshutdown;
begin
if ALSAhandle<>{DynLibs.}NilHandle then
begin
{DynLibs.}UnloadLibrary(ALSAhandle);
ALSAhandle:={DynLibs.}NilHandle
end
end;
(credit to Fred vS for showing me how to do the above)in principal it seems that the above approach could be applied to the whole of the Lazarus IDE - it would be a large task, but on the whole mostly an 'automated' conversion for the programmer doing the work.
once the concept is proven, it could then be streamlined for others to use going forward with their own Lazarus/FPC projects for widget set auto-selection. (see addendum below, just adding in the
start unit to project1.lpr would suffice)
cheers,
rob :-)
addendum 1: in the above i forgot to include one more step - merging what are (presumably) conditional compile blocks for each widget set, into case statements (or similar) to select which set of code for which widget set. to some (yet to be determined) extent this would grow the size of generated ELF files, but these days folks don't seem to worry so much about this!
addendum 2: it is actually even easier. the
start unit just needs to set a single global variable that indicates the widget set that should be used. then every
external statement replaced with calls to
SafeLoadLibrary and
GetProcedureAddress, it looks like it
may ok to call
SafeLoadLibrary multiple times to get the same handle returned each time. conditional compile blocks (selecting for different widget sets) then replaced with "
if widget_set = GTK2/Qt5/Qt6 then ..." blocks.