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

Nils Kattenbeck nilskemail at gmail.com
Mon Feb 17 13:12:09 UTC 2025


Thanks, v22 works. I was checking with jextract 21 as that is the JDK
version I have running. With v22 everything seems to work, both when
specifying one or two header files. There are still a few warnings but
those seem unrelated:

sd-daemon.h:26:1: warning: Skipping
_sd_useless_struct_to_allow_trailing_semicolon_ (type
Declared(_sd_useless_struct_to_allow_trailing_semicolon_) is not supported)


Cheers, Nils

On Mon, Feb 17, 2025 at 2:04 PM Jorn Vernee <jorn.vernee at oracle.com> wrote:

> 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/39c779e8/attachment-0001.htm>


More information about the jextract-dev mailing list