Skip to content

[ci] Add abi compatibility check for libhl#904

Open
tobil4sk wants to merge 10 commits intoHaxeFoundation:masterfrom
tobil4sk:feature/abi-diff
Open

[ci] Add abi compatibility check for libhl#904
tobil4sk wants to merge 10 commits intoHaxeFoundation:masterfrom
tobil4sk:feature/abi-diff

Conversation

@tobil4sk
Copy link
Member

@tobil4sk tobil4sk commented Mar 6, 2026

This PR adds a check to ci to ensure that the abi compatibility doesn't get broken (also relevant to: #698).

Unfortunately, due to an abi breaking change in 1.15 (1e3e016) we cannot completely restore compatibility with 1.14 or older, but I would like to still try to fix as much as possible. For now I have restored compatibility with libhl 1.15. I haven't yet dealt with hdlls.

These were the main changes that broke ABI since 1.15 (e.g. in #863):

It is worth noting that there were some advantages with the non-struct version. With a raw struct, any change to hl_setup, like adding a new field to the end, can be a breaking ABI change if sizeof(hl_setup) increases. E.g.

bin/main: Symbol `hl_setup' has different size in shared object, consider re-linking

Some symbols were missing explicit exports so they disappeared with #887. I have added HL_PRIM to fix those. #901 is another example of that. Other symbols used to be exported also due to the old default, but weren't part of hl.h (e.g. pcre symbols or internal functions like hl_cache_init). These are excluded from the check.

Here are some practical benefits to abi stability:

  • Third party hdlls can be shipped as binaries without having to recompile for every new hashlink release.
  • You can update the libhl used by a hlc program to apply patches without having to recompile hlc.

tobil4sk added 10 commits March 6, 2026 11:47
Without this, the symbol may be hidden with some compilers and therefore
cannot be loaded.
These were never meant to be part of the public api, but were exported
by mistake due to default symbol visibility.
This was never part of hl.h, so its removal is safe.
This was also never exposed in a header, and not exported explicitly
This way we do not see errors related to opaque pointers, which are
opaque so that it is safe to change them.
This is what the symbols were in 1.13 and older
@skial skial mentioned this pull request Mar 8, 2026
1 task
@ncannasse
Copy link
Member

I have cleanup the setup functions so they are all in a single struct. It is an ABI breaking change but I don't really want to revert it for the sake of backward compatibility, as I prefer clean code and breaking changes than maintaining legacy messy code all over the place.

I'm curious however about the sizeof link warning. Could you tell me when does it occur ? is it at runtime ?

@tobil4sk
Copy link
Member Author

The sizeof link warning happens if you link an hlc program against one version of libhl.so, but at load time it loads newer version where sizeof(hl_setup) is different. This is why in general it is better to keep structs like this private and expose only functions to modify the values, as you can freely reorganise internal memory layout or add fields without breaking ABI. It is similar to how it is better to provide getters/setters instead of direct member access in classes.

I think it is helpful to provide a fully stable ABI, but if this is not feasible in general, then maybe it is possible to compromise to still improve things. The main benefit of ABI stability which would be useful is so that third-party hdlls are compatible between different versions of hashlink, because currently this is a problem when using hdlls that aren't part of the hashlink distribution.

Maybe to solve this problem without restricting things too much, it might be possible to have an .h file that exposes only a subset of the ABI used by hdlls, which is the only part that is treated as stable. That way, the abi between hl.exe and libhl.so can be considered "private" and can change as needed, but the ABI relied on by hdlls can be considered public so it is easier to provide a custom hdll.

Is there any chance of something like that?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants