jextract fails to work on sd-daemon.h due to wrong handling of __INCLUDE_LEVEL__
Nils Kattenbeck
nilskemail at gmail.com
Sat Feb 15 16:46:31 UTC 2025
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/20250215/06e1cf0b/attachment.htm>
More information about the jextract-dev
mailing list