On 27/07/26 15:01, Bruno Haible wrote:
> Adhemerval Zanella Netto wrote:
>> This approach saves us to export an additional symbol
>
> Yes, this is the advantage of that "redirect through the header file"
> approach. But there are several drawbacks, both relating to the ecosystem
> outside glibc:
>
>> I did not foresee that
>> such configure checks would fail, since they bypass the C headers and
>> deliberately
>> redeclares the function with a bogus prototype.
>
> The first drawback is with Autoconf and configure checks of the form
> AC_CHECK_FUNCS.
>
> The second drawback is with packages that provide bindings to glibc
> for a higher-level language (such as a scripting language).
> There are two approaches for such bindings:
>
> (C) One is to use the C compiler with #include <...> statements.
> This is what SWIG [1] does, and what Python's CFFI does in "API mode"
> [2].
>
> (L) The other one is to interface at the linker level. This makes
> use of the symbols seen by "nm -D", and uses libffi or GNU libffcall
> for the actual function invocations.
> This is what Python's CFFI does in "ABI mode" [2].
>
> People typically prefer approach (C) for C++ libraries (because the name
> mangling and the massive inlining in C++ leave no other choice). The drawback
> of this approach is the huge size of the bindings, due to the many wrapper
> functions.
>
> People therefore typically prefer approach (L) for C libraries, as can be
> seen through the widespread use of libffi in the Free Software ecosystem.
But this is not strictly correct and even for some interface we do not fully
support it. For instance, for LFS or 64 time-t support configure will
potentially
check the wrong symbol used during binary linking, which is surprising at least.
It also does not work for dlopen, which is another break symmetry break, but
I think is a different issue.
>
> If a symbol that is expected to be bindable is defined through an inline
> function or a redirection in the header file, the approach (L) does not
> work any more, and its developers must find a workaround on a case-by-case
> basis. In the worst case, they would have to switch from approach (L) to
> approach (C).
I tend to agree with Andreas here that our exported interfaces are tied to
the exported headers and trying to used them separately is UB and adds an
extra constraint for development and testing.
It means now that ideally we would need to test not only the header interface
checks, but also adds linking checks for every interface to assure that they
work in this (L) approach.
>
> I once made this experience with GNU libintl: In version 0.22, I implemented
> a redirection from the symbol 'gettext' to 'libintl_gettext' at the header
> level. I thought this was OK, because I only thought of users who #include
> <libintl.h>. But it actually broke Python, because Python uses approach (L)
> in its binding. [3]
Right, but I think for this case this ship has already sailed. We can fixed
for 2.45, but our current policy is to not introduce new symbols on release
branches. It would be doable, but I really want to avoid it.
>
>> This will add the additional constraint on exporting all extensions that are
>> ratified by POSIX as extra symbols, not ideal but doable.
>
> Yes, these exported symbols will be necessary to allow the binding with glibc
> to be easy. There are *many* packages that bind glibc to scripting languages,
> and many of them use approach (L).
>
> Bruno
>
> [1] https://swig.org/
> [2] https://cffi.readthedocs.io/en/stable/overview.html
> [3] https://lists.gnu.org/archive/html/bug-gettext/2023-07/msg00005.html
>
>
>