2009-11-30 16:37:21

by Ulrich Drepper

[permalink] [raw]
Subject: using kernel headers in libc headers

The kernel headers nowadays are cleaned up to separate in-kernel
definitions from those that are exported. That's of course good but
it's unfortunately not sufficient to use (most of) the headers in
glibc.

Take <linux/sched.h> for instance. The <sched.h> header is defined in
POSIX and therefore the specify which symbols can be defined in which
configuration. The <linux/sched.h> defines all kinds of symbols,
though, unconditionally. If you compare it with the glibc header
you'd see that all the CLONE_* symbols and some of the SCHED_* symbols
are only defined in certain configurations (non-POSIX configurations).

It's likely in everybody's interest to get the kernel headers used.
But for this mode #ifdefs are needed. I'm willing to do the work.
Easy enough to do when I'm going through the headers one-by-one to
enable them in glibc. But I don't want to start this work unless it's
going to be accepted. The symbols would be something like

__USE_MISC

or

__USE_GNU

These are not macros which the user must define. The user sets macros
like _GNU_SOURCE etc which then set all the appropriate __USE_* macros
(see "info libc 'Feature Test Macros'" on machines with glibc
installed). These names are somewhat glibc-specific but other libcs
can (or already have) adapt them.

So, what do you say?


2009-11-30 17:01:07

by H. Peter Anvin

[permalink] [raw]
Subject: Re: using kernel headers in libc headers

On 11/30/2009 08:37 AM, Ulrich Drepper wrote:
>
> It's likely in everybody's interest to get the kernel headers used.
> But for this mode #ifdefs are needed. I'm willing to do the work.
> Easy enough to do when I'm going through the headers one-by-one to
> enable them in glibc. But I don't want to start this work unless it's
> going to be accepted. The symbols would be something like
>
> __USE_MISC
>
> or
>
> __USE_GNU
>
> These are not macros which the user must define. The user sets macros
> like _GNU_SOURCE etc which then set all the appropriate __USE_* macros
> (see "info libc 'Feature Test Macros'" on machines with glibc
> installed). These names are somewhat glibc-specific but other libcs
> can (or already have) adapt them.
>
> So, what do you say?

Speaking for myself, I think #ifdefs utterly suck for this purpose.
First of all, because they tie back a glibc internal (the naming of
feature test macros) with the kernel headers. Second of all, because it
really makes it much harder to get things right. Third, because it
conflicts with the usage model in the kernel itself in a way that is
likely to cause breakage.

A better way is to factor out subsets; if <linux/sched.h> has too many
things, we can break out the POSIX parts into <linux/sched_posix.h> or
(certainly better if we have more than one of these)
<linux/sched/posix.h> which can also be included by <linux/sched.h>.

glibc can then choose to include or not include <linux/sched/posix.h>
depending on its configuration. The configuration macros remain a glibc
internal detail.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.

2009-11-30 17:44:16

by Chris Friesen

[permalink] [raw]
Subject: Re: using kernel headers in libc headers

On 11/30/2009 11:01 AM, H. Peter Anvin wrote:

> A better way is to factor out subsets; if <linux/sched.h> has too many
> things, we can break out the POSIX parts into <linux/sched_posix.h> or
> (certainly better if we have more than one of these)
> <linux/sched/posix.h> which can also be included by <linux/sched.h>.
>
> glibc can then choose to include or not include <linux/sched/posix.h>
> depending on its configuration. The configuration macros remain a glibc
> internal detail.

Yes, absolutely. Personally I find it much easier to open a separate
header file than to read code that is littered with #ifdefs.

Chris

2009-11-30 17:44:07

by Ulrich Drepper

[permalink] [raw]
Subject: Re: using kernel headers in libc headers

On Mon, Nov 30, 2009 at 09:01, H. Peter Anvin <[email protected]> wrote:
> A better way is to factor out subsets; if <linux/sched.h> has too many
> things, we can break out the POSIX parts into <linux/sched_posix.h> or
> (certainly better if we have more than one of these)
> <linux/sched/posix.h> which can also be included by <linux/sched.h>.

This is at least as undesirable.

First, there can be several different of those. E.g., there are
different levels of POSIX compliance and the number of growing. There
are also conditions like

if POSIX version > 2001012 || GNU source

How do you express this?

Second, it makes it hard to impossible for developers to use the
headers as part of the system documentation. Many people (me
included) look at headers and the included comments. With your scheme
the set of definitions (e.g., SCHED_* macros) might be spread out over
several different headers. Currently they are all nicely group (in
the kernel and libc headers) and people can see what is available.


None of the #ifdefs should interfere with kernel compilation. It can
be easily arranged so that when compiling the kernel all these macros
are automatically set.

2009-11-30 17:56:46

by H. Peter Anvin

[permalink] [raw]
Subject: Re: using kernel headers in libc headers

On 11/30/2009 09:43 AM, Ulrich Drepper wrote:
> On Mon, Nov 30, 2009 at 09:01, H. Peter Anvin <[email protected]> wrote:
>> A better way is to factor out subsets; if <linux/sched.h> has too many
>> things, we can break out the POSIX parts into <linux/sched_posix.h> or
>> (certainly better if we have more than one of these)
>> <linux/sched/posix.h> which can also be included by <linux/sched.h>.
>
> This is at least as undesirable.
>
> First, there can be several different of those. E.g., there are
> different levels of POSIX compliance and the number of growing. There
> are also conditions like
>
> if POSIX version > 2001012 || GNU source
>
> How do you express this?

Very simple: you factor it into subsets. The above kind of stuff is
*exactly* why this has no business in the kernel headers -- it exposes
glibc internals way too deeply.

> Second, it makes it hard to impossible for developers to use the
> headers as part of the system documentation. Many people (me
> included) look at headers and the included comments. With your scheme
> the set of definitions (e.g., SCHED_* macros) might be spread out over
> several different headers. Currently they are all nicely group (in
> the kernel and libc headers) and people can see what is available.

That is exactly why I said <linux/sched/foo.h> is preferrable to
<linux/sched_foo.h> -- with more than one subset then it is better to
combine them into a subdirectory so they can be rapidly found.

We already have been through the #ifdef hell once, and we are still
crawling out of it. It was -- and is -- an utter miserable failure.
Explicitly forcing factoring into subsets and leaving it to the libc
layer to decide what subsets to invoke is the only sane option. This is
*especially* so when you consider that you have to account for version
skew next time glibc or uclibc or whateverlibc introduces new feature
macros.

-hpa

--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.