Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifications needed to complile Firebird.pas under FPC [CORE6207] #6452

Closed
firebird-automations opened this issue Dec 12, 2019 · 19 comments
Closed

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Tony Whyman (twhyman)

This bug report is intended to record the changes to Firebird.pas needed for it to successfully compile under FPC 3.0.4. This is the result of preparation work for upgrading IBX for Lazarus to use new Firebird 4 features.

1. The reserved word "record" is used as a parameter name and needs to be escaped i.e. to "&record".

2. Unknown Types:

Replace:
isc_tr_handle = ^integer32;
isc_stmt_handle = ^integer32;

with

isc\_tr\_handle = ^FixedInt;
isc\_stmt\_handle = ^FixedInt;

3. Missing Types:

ISC_USHORT = word; { 16 bit unsigned }

ISC_TIME_TZ = record
utc_time: ISC_TIME;
time_zone: ISC_USHORT;
end;

ISC_TIMESTAMP = record
timestamp_date: ISC_DATE;
timestamp_time: ISC_TIME;
end;

ISC_TIMESTAMP_TZ = record
utc_timestamp: ISC_TIMESTAMP;
time_zone: ISC_USHORT;
end;

4. Remove or comment out:

function fb_get_master_interface : IMaster; cdecl; external 'fbclient';

This is not an appropriate external function declaration for a dynamic link library and only applies to a static library.

When testing with FPC, if this line was not commented out, a linker error occurs when trying to link with the debug heap
manager (needed for testing for memory leaks).

Commits: 35e1b28

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

> This is not an appropriate external function declaration for a dynamic link library and only applies to a static library.

Does Delphi agree?

Why it has " external 'fbclient'" then? For nothing?

How FPC uses dynamic libraries (without LoadLibrary/dlopen)?

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

The IBX code that loads the Firebird Library and the master interface is common to both FPC and Delphi and is tested for both Windows and Linux.

1. The Firebird Client library is loaded. For Linux it uses "dlopen". Under Windows it uses "LoadLibrary" - and has to look in various locations to find it.

2. IBX defines a type:

Tfb_get_master_interface = function: IMaster;
{$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}

and then a variable

var fb_get_master_interface: Tfb_get_master_interface;

3. GetProcAddress is then used to get a function pointer to the master interface (dlsym under Linux)

i.e.
fb_get_master_interface := GetProcAddress(FBLibraryHandle, 'fb_get_master_interface');

4. This is used to get (e.g.) IUtil

FUtil := fb_get_master_interface.getUtilInterface.

Exactly the same scheme is used for the legacy interface except that each API call has to be separately loaded by a call to GetProcAddress. Indeed, IBX determines whether the new or legacy interface is present by attempting to load fb_get_master_interface and, if GetProcAddress fails, assumes use of the legacy interface.

According to the FPC Manual:

"The external modifier can be used to declare a function that resides in an external object file. It allows to use the function in some code, and at linking time, the object file containing the implementation of the function or procedure must be linked in."

Basically, it is for statically linked libraries and not dynamically linked libraries. I believe that this the same for Delphi.

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

FPS works different than Delphi in this regard?

FPC could not load dynamic libraries with that info registered in PE (EXE) / ELF symbol tables?

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

Delphi and FPC are probably not that different. The FPC documentation can be found here:

https://www.freepascal.org/docs-html/current/prog/progse56.html#x266-28200012.3

There are two problems with using the "external" directive:

1. There is probably an FPC bug in this area as trying to link to libfblient with this syntax gives a linker error with the heap debugger.

2. IBX has to work, out of the box, over multiple platforms and with different versions (and names) for the Firebird library. The original Borland IBX dynamically loaded the firebird library and used GetProcAddress for each API Call and I have never seen a good reason to change that.

* Prior to Firebird 3, the library name was different for the embedded version and the remote client library. IBX had to try each name in turn. The "external" directive hard codes the library name in the source code.

* Users want to place the Firebird library wherever they want and this includes those that have multiple versions on the same system and want to specify the one they use at run time.

* On Windows there are several locations in which the firebird library can be located and the default Windows search path cannot be relied on to find them.

* IBX needs to be able default back to the legacy API when the OO API is not supported and this requires dynamically testing the API exported by the library.

* IBX will still attempt to load gds32.dll if all else fails - increasingly pointless, but there still maybe some users out there who use it.

IBPP also appears to have followed the same approach as IBX and dynamically loads the Interbase/Firebird library trying first fbclient and then gds32, while allowing the user to specify the search path.

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

I understand the points on dynamic discover and load.

Let me also know: if fb_get_master_interface is not even called, the link problem happens?

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

I've applied most of suggested changes (except commenting out fb_get_master_interface) in FB4.

What about fb_get_master_interface - suggestion is pretty wrong. I suppose mentioned docs saying that 'object file containing the implementation of the function or procedure must be linked in' is slightly imprecise. Or may be automatic loading of dynamic library which was referenced in 'external' statement is also linking time? At least our single .pas sample works fine with external fbclient.

Tony, I suppose you should start with renaming
var fb_get_master_interface: Tfb_get_master_interface;
to something like
var F_fb_get_master_interface: Tfb_get_master_interface;
or anything else on your choice. IMO that's not a problem of firebird.pas.

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

I have tried out the latest version of Firebird,pas after checking out the latest source code from GIT.

Most of the above issues have been resolved. However, there are new undeclared types results from the extended time zone type. These are:

ISC_TIMESTAMP_TZ_EX
ISC_SHORT
ISC_TIME_TZ_EX

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Tony, please suggest - how to describe ISC_SHORT better? For ISC_USHORT the following is used:

ISC\_USHORT = word; \{ 16 bit unsigned \}

ISC_SHORT should be 16-bit signed.

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

assignee: Alexander Peshkov [ alexpeshkoff ]

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

SmallInt is the FPC 16-bit signed integer type i.e.

type ISC_SHORT = SmallInt;

See

https://www.freepascal.org/docs-html/ref/refsu4.html

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Will it be ok for Delphi too?

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

Yes. Delphi has the same type. See

http://docwiki.embarcadero.com/RADStudio/Rio/en/Simple_Types_(Delphi)

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Done
Tony please report - did it help?
I want to close an item after it.

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

I pulled the most recent changes from GIT and on a visual inspection, the changes to src/misc/pascal/Pascal.interface.pas look good. Now rebuilding to make it all goes together OK.

@firebird-automations
Copy link
Collaborator Author

Commented by: Tony Whyman (twhyman)

Rebuilt and Firebird.pas compiles without need for modification!

For the future, it may be worth adding a sanity check if "fpc" is available on the build system.

The command

fpc ./src/include/gen/Firebird.pas

will complie the unit and tell you if the unit compiles OK. The usual return codes apply.

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

It's missing on most of build systems but I will try that check at my local box when needed (like getting ready to release beta2).

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Fixed [ 1 ]

Fix Version: 4.0 Beta 2 [ 10888 ]

@firebird-automations
Copy link
Collaborator Author

Modified by: @pavel-zotov

status: Resolved [ 5 ] => Resolved [ 5 ]

QA Status: No test => Cannot be tested

@firebird-automations
Copy link
Collaborator Author

Modified by: @pavel-zotov

status: Resolved [ 5 ] => Closed [ 6 ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants