jextract fails to work on sd-daemon.h due to wrong handling of __INCLUDE_LEVEL__

Jorn Vernee jorn.vernee at oracle.com
Mon Feb 17 13:03:53 UTC 2025


Looking at the code, we already unconditionally generate an intermediate 
header file [1]. So this should already work on the latest version of 
jextract.

Jorn

[1]: 
https://github.com/openjdk/jextract/blob/7ed79ecdf678db804f40b3494b6f1dafa760c808/src/main/java/org/openjdk/jextract/JextractTool.java#L110

On 17-2-2025 14:00, Maurizio Cimadamore wrote:
>
> I wonder how this interacts with the fact that jextract now also 
> accepts multiple headers and, in that case, it will generate an 
> intermediate header that includes the specified headers.
>
> Can you try passing jextract _two_ headers, both  sd-daemon.h and 
> something else, and see what happens? My feeling is that things should 
> work in that case.
>
> Which, if true, would advocate for jextract to handle both cases in 
> the same way: with an intermediate header including the specified 
> header file(s).
>
> Maurizio
>
>
>
> On 15/02/2025 16:46, Nils Kattenbeck wrote:
>> Hi Jorn,
>>
>> Your assessment seems to be correct. In C the main.c would be level 0 
>> which libclang sidesteps in this case. Creating a dummy header file 
>> which simply includes the sd-daemon.h file seems to fix the problem.
>>
>> That being said I think it would still make sense for jextract to 
>> work around this issue. Given that the resulting Java classes would 
>> be similar to the main translation unit in C it would make sense for 
>> jextract to emulate this behaviour and read the header files as if 
>> they already were at level 1. This could e.g. be done creating such a 
>> dummy header file automatically (like I now did manually). This would 
>> better match expectations, resolve the issue in this specific 
>> instance with systemd but more importantly would prevent hard to 
>> troubleshoot issues in the future.
>>
>> Cheers, Nils
>>
>> On Fri, Feb 14, 2025 at 11:46 PM Jorn Vernee <jorn.vernee at oracle.com> 
>> wrote:
>>
>>     Hey Nils,
>>
>>     Jextract uses clang under the hood to do the parsing, so it is
>>     clang that is managing the __INCLUDE_LEVEL__ value, and I'm
>>     assuming it does that correctly.
>>
>>     I think the issue here is that, normally, you would write a
>>     program that includes sd-daemon.h, so the include level of that
>>     file starts out at 1, with the main program translation unit
>>     being level 0. But, since jextract uses clang to parse the
>>     sd-daemon.h file directly, it has include level 0 instead, and
>>     this implementation header seems to end up with include level 1,
>>     failing the check. You should see the same error if you directly
>>     pass sd-daemon.h to clang (or gcc).
>>
>>     I think another way to work around this would be to create a
>>     wrapper header file in which you #include sd-deamon.h, and then
>>     pass that wrapper header file to jextract.
>>
>>     Jorn
>>
>>     On 13-2-2025 17:51, Nils Kattenbeck wrote:
>>>     Dear all,
>>>
>>>     Today I tried to use jextract on sd-daemon.h (from systemd) to
>>>     access the sd_notify* class of functions. To my surprise this
>>>     did not work and returned in the following error message:
>>>
>>>     ../jextract-21/bin/jextract --source -t foo.bar
>>>     /usr/include/systemd/sd-daemon.h
>>>     WARNING: A restricted method in java.lang.foreign.AddressLayout
>>>     has been called
>>>     WARNING: java.lang.foreign.AddressLayout::withTargetLayout has
>>>     been called by module org.openjdk.jextract
>>>     WARNING: Use --enable-native-access=org.openjdk.jextract to
>>>     avoid a warning for this module
>>>
>>>     /usr/include/systemd/_sd-common.h:23:4: error: "Do not include
>>>     _sd-common.h directly; it is a private header."
>>>
>>>     which comes down to the following preprocessor code in
>>>     _sd-common.h (which is included by sd-daemon.h):
>>>
>>>     #if defined(__INCLUDE_LEVEL__) && __INCLUDE_LEVEL__ <= 1 &&
>>>     !defined(__COVERITY__)
>>>     #  error "Do not include _sd-common.h directly; it is a private
>>>     header."
>>>     #endif
>>>
>>>     It seems like jextract does not increase the __INCLUDE_LEVEL__
>>>     resulting in this error. However, it does seem to define it
>>>     which makes this more curious.
>>>     The fix would be to either a) not set it at all or b) correctly
>>>     increment it when parsing files from an #include statement.
>>>
>>>     For now I have been able to circumvent this by telling jextract
>>>     to also define __COVERITY__though this is only a very dirty hack
>>>     and will not work in every instance.
>>>
>>>     Cheers,
>>>     Nils
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jextract-dev/attachments/20250217/a45d9e72/attachment.htm>


More information about the jextract-dev mailing list