[PATCH] AC_HEADER_MAJOR: port to glibc 2.25

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] AC_HEADER_MAJOR: port to glibc 2.25

Eric Blake-3
glibc 2.25 is deprecating the namespace pollution of sys/types.h
injecting major(), minor(), and makedev() into the compilation
environment, with a warning that insists that users include
<sys/sysmacros.h> instead.  However, because the expansion of
AC_HEADER_MAJOR didn't bother checking sys/sysmacros.h until
after probing whether sys/types.h pollutes the namespace, it was
not defining MAJOR_IN_SYSMACROS, with the result that code
compiled with -Werror chokes on the deprecation warnings because
it was not including sysmacros.h.

In addition to fixing autoconf (which only benefits projects
that rebuild configure after this fix is released), we can also
give a hint to distros on how they can populate config.site with
a cache variable to force pre-existing configure scripts without
the updated macro to behave sanely in the presence of glibc 2.25.

* lib/autoconf/headers.m4 (AC_HEADER_MAJOR): Check for sysmacros.h
first, rather than after determining if sys/types.h pollutes the
namespace.
* doc/autoconf.texi (Particular Headers) <AC_HEADER_MAJOR>: Expand
details on usage, and on workarounds for non-updated projects.

Signed-off-by: Eric Blake <[hidden email]>
---

I'd like a review on this patch before pushing it; meanwhile,
I'm in the middle of testing that the new definition of
AC_HEADER_MAJOR, when ported to gnulib, is sufficient to solve
the libvirt build failure.

For this patch, I kept the status quo of assuming that if
sys/sysmacros.h exists, then it probably defines major/minor/makedev;
if you want me to rework the patch to explicitly check that this
is the case, I can do that as well (probably best as a followup
patch, in case downstreams want to backport one idea without the
other).

 doc/autoconf.texi       | 21 +++++++++++++++++++++
 lib/autoconf/headers.m4 | 40 +++++++++++++++++++++-------------------
 2 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 029ddd6..f2494d8 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -5977,6 +5977,27 @@ Particular Headers
 @code{makedev}, but @file{sys/mkdev.h} does, define
 @code{MAJOR_IN_MKDEV}; otherwise, if @file{sys/sysmacros.h} does, define
 @code{MAJOR_IN_SYSMACROS}.
+
+To properly use any of these three functions, your code should contain
+something like:
+
+@verbatim
+#include <sys/types.h>
+#ifdef MAJOR_IN_MKDEV
+# include <sys/mkdev.h>
+#elif MAJOR_IN_SYSMACROS
+# include <sys/sysmacros.h>
+#endif
+@end verbatim
+
+Note that glibc 2.25 issues a deprecation warning if these functions are
+used from @file{sys/types.h} without also using @file{sys/sysmacros.h},
+but that configure scripts built with versions of autoconf prior to 2.70
+did not correctly define @code{MAJOR_IN_SYSMACROS} in that scenario; on
+systems where that is a problem, you can use the workaround of priming
+the configure cache by setting @code{ac_cv_header_sys_types_h_makedev}
+to 'no', perhaps as part of a @file{config.site} site default file
+(@pxref{Site Defaults}).
 @end defmac

 @defmac AC_HEADER_RESOLV
diff --git a/lib/autoconf/headers.m4 b/lib/autoconf/headers.m4
index 0c44973..f1ed051 100644
--- a/lib/autoconf/headers.m4
+++ b/lib/autoconf/headers.m4
@@ -427,30 +427,32 @@ fi

 # AC_HEADER_MAJOR
 # ---------------
+# Thanks to glibc 2.25, we need the following logic:
+# If <sys/sysmacros.h> compiles, assume it provides the macros.
+# Otherwise, if <sys/types.h> provides them, nothing further to do.
+# Otherwise, if <sys/mkdev.h> exists, assume it provides the macros.
 AN_FUNCTION([major],     [AC_HEADER_MAJOR])
 AN_FUNCTION([makedev],   [AC_HEADER_MAJOR])
 AN_FUNCTION([minor],     [AC_HEADER_MAJOR])
 AN_HEADER([sys/mkdev.h], [AC_HEADER_MAJOR])
 AC_DEFUN([AC_HEADER_MAJOR],
-[AC_CACHE_CHECK(whether sys/types.h defines makedev,
- ac_cv_header_sys_types_h_makedev,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <sys/types.h>]],
- [[return makedev(0, 0);]])],
- [ac_cv_header_sys_types_h_makedev=yes],
- [ac_cv_header_sys_types_h_makedev=no])
-])
-
-if test $ac_cv_header_sys_types_h_makedev = no; then
-AC_CHECK_HEADER(sys/mkdev.h,
- [AC_DEFINE(MAJOR_IN_MKDEV, 1,
-   [Define to 1 if `major', `minor', and `makedev' are
-    declared in <mkdev.h>.])])
-
-  if test $ac_cv_header_sys_mkdev_h = no; then
-    AC_CHECK_HEADER(sys/sysmacros.h,
-    [AC_DEFINE(MAJOR_IN_SYSMACROS, 1,
-       [Define to 1 if `major', `minor', and `makedev'
- are declared in <sysmacros.h>.])])
+[AC_CHECK_HEADER(sys/sysmacros.h,
+ [AC_DEFINE(MAJOR_IN_SYSMACROS, 1,
+    [Define to 1 if `major', `minor', and `makedev'
+     are declared in <sysmacros.h>.])])
+if test $ac_cv_header_sys_sysmacros_h = no; then
+  AC_CACHE_CHECK(whether sys/types.h defines makedev,
+ ac_cv_header_sys_types_h_makedev,
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <sys/types.h>]],
+   [[return makedev(0, 0);]])],
+  [ac_cv_header_sys_types_h_makedev=yes],
+  [ac_cv_header_sys_types_h_makedev=no])
+  ])
+  if test $ac_cv_header_sys_types_h_makedev = no; then
+  AC_CHECK_HEADER(sys/mkdev.h,
+  [AC_DEFINE(MAJOR_IN_MKDEV, 1,
+     [Define to 1 if `major', `minor', and `makedev'
+      are declared in <mkdev.h>.])])
   fi
 fi
 ])# AC_HEADER_MAJOR
--
2.7.4


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] AC_HEADER_MAJOR: port to glibc 2.25

Zack Weinberg-2
On Wed, Sep 14, 2016 at 9:26 AM, Eric Blake <[hidden email]> wrote:

> glibc 2.25 is deprecating the namespace pollution of sys/types.h
> injecting major(), minor(), and makedev() into the compilation
> environment, with a warning that insists that users include
> <sys/sysmacros.h> instead.  However, because the expansion of
> AC_HEADER_MAJOR didn't bother checking sys/sysmacros.h until
> after probing whether sys/types.h pollutes the namespace, it was
> not defining MAJOR_IN_SYSMACROS, with the result that code
> compiled with -Werror chokes on the deprecation warnings because
> it was not including sysmacros.h.
>
> In addition to fixing autoconf (which only benefits projects
> that rebuild configure after this fix is released), we can also
> give a hint to distros on how they can populate config.site with
> a cache variable to force pre-existing configure scripts without
> the updated macro to behave sanely in the presence of glibc 2.25.

Thanks for writing this patch.

> For this patch, I kept the status quo of assuming that if
> sys/sysmacros.h exists, then it probably defines major/minor/makedev;
> if you want me to rework the patch to explicitly check that this
> is the case, I can do that as well (probably best as a followup
> patch, in case downstreams want to backport one idea without the
> other).

glibc's sys/sysmacros.h _only_ defines major/minor/makedev.  What I'd
worry about is whether any other C library has a different header with
the same name; "sysmacros" is pretty generic.  I don't have any
evidence either way on that question.

> @@ -5977,6 +5977,27 @@ Particular Headers
>  @code{makedev}, but @file{sys/mkdev.h} does, define
>  @code{MAJOR_IN_MKDEV}; otherwise, if @file{sys/sysmacros.h} does, define
>  @code{MAJOR_IN_SYSMACROS}.

This part of the description should probably be adjusted to match what
the code does now.

> +To properly use any of these three functions, your code should contain
> +something like:

Also, I think "three functions" here is meant to refer to
major/minor/makedev, but it tripped me up the first time I read it.  I
suggest instead

   Detect the headers required to use @code{makedev}, @code{major}, and
   @code{minor}.  These functions may be defined by @file{sys/mkdev.h},
   @code{sys/sysmacros.h}, or @file{sys/types.h}.

   @code{AC_HEADER_MAJOR} defines @code{MAJOR_IN_MKDEV} if they are in
   @file{sys/mkdev.h}, or @code{MAJOR_IN_SYSMACROS} if they are in
   @file{sys/sysmacros.h.}.  If neither macro is defined, they are either
   in @file{sys/types.h} or they are unavailable.

   To portably use these functions, your code should contain something
   like

and then your @verbatim block.

(Should AC_HEADER_MAJOR maybe throw an error if none of the possible
headers we know about defines major/minor/makedev?  I believe this is
the case on MinGW, for instance.)

> +Note that glibc 2.25 issues a deprecation warning if these functions are
> +used from @file{sys/types.h} without also using @file{sys/sysmacros.h},
> +but that configure scripts built with versions of autoconf prior to 2.70
> +did not correctly define @code{MAJOR_IN_SYSMACROS} in that scenario; on
> +systems where that is a problem, you can use the workaround of priming
> +the configure cache by setting @code{ac_cv_header_sys_types_h_makedev}
> +to 'no', perhaps as part of a @file{config.site} site default file
> +(@pxref{Site Defaults}).

This is a really long sentence.  Also, "used from @file{sys/types.h}
without also using @file{sys/types.h}" is confusing, and since this is
the Autoconf manual, probably the paragraph should highlight the
affected Autoconf versions first.  Suggested:

   Note: Configure scripts built with Autoconf 2.69 or earlier will
   not detect a problem if @file{sys/types.h} contains definitions of
   @code{major}, @code{minor}, and/or @code{makedev} that trigger
   compiler warnings upon use.  This is known to occur with GNU libc
   2.25, where those definitions are being deprecated, to reduce
   namespace pollution.  If it is not practical to regenerate affected
   software's configure scripts with Autoconf 2.70, you can work around
   the problem by setting @samp{ac_cv_header_sys_types_h_makedev=no} in
   a @file{config.site} site default file (@pxref{Site Defaults}).


> +# Thanks to glibc 2.25, we need the following logic:
> +# If <sys/sysmacros.h> compiles, assume it provides the macros.
> +# Otherwise, if <sys/types.h> provides them, nothing further to do.
> +# Otherwise, if <sys/mkdev.h> exists, assume it provides the macros.

I think we should check sys/types.h last.  That will future-proof
against C libraries where these functions are in both sys/mkdev.h and
sys/types.h deciding to do the same deprecation that glibc has done.

zw

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] AC_HEADER_MAJOR: port to glibc 2.25

Eric Blake-3
On 09/14/2016 10:27 AM, Zack Weinberg wrote:
> glibc's sys/sysmacros.h _only_ defines major/minor/makedev.  What I'd
> worry about is whether any other C library has a different header with
> the same name; "sysmacros" is pretty generic.  I don't have any
> evidence either way on that question.
>

Nor do I; and I also wonder if the fact that we checked mkdev.h first
(which catches BSD systems, if I'm not mistaken) would mask the effect
of a BSD system with both mkdev.h and sysmacros.h.  A quick google found
at least one other vendor with a sysmacros.h, with a lot more contents
than glibc's:
http://opensource.apple.com//source/zfs/zfs-59/zfs_common/sys/sysmacros.h

>> @@ -5977,6 +5977,27 @@ Particular Headers
>>  @code{makedev}, but @file{sys/mkdev.h} does, define
>>  @code{MAJOR_IN_MKDEV}; otherwise, if @file{sys/sysmacros.h} does, define
>>  @code{MAJOR_IN_SYSMACROS}.
>
> This part of the description should probably be adjusted to match what
> the code does now.
>
>> +To properly use any of these three functions, your code should contain
>> +something like:
>
> Also, I think "three functions" here is meant to refer to
> major/minor/makedev, but it tripped me up the first time I read it.  I
> suggest instead
>
>    Detect the headers required to use @code{makedev}, @code{major}, and
>    @code{minor}.  These functions may be defined by @file{sys/mkdev.h},
>    @code{sys/sysmacros.h}, or @file{sys/types.h}.
>
>    @code{AC_HEADER_MAJOR} defines @code{MAJOR_IN_MKDEV} if they are in
>    @file{sys/mkdev.h}, or @code{MAJOR_IN_SYSMACROS} if they are in
>    @file{sys/sysmacros.h.}.  If neither macro is defined, they are either
>    in @file{sys/types.h} or they are unavailable.
>
>    To portably use these functions, your code should contain something
>    like
>
> and then your @verbatim block.
>
Thanks for the wordsmithing help.  I'll post a v2.

> (Should AC_HEADER_MAJOR maybe throw an error if none of the possible
> headers we know about defines major/minor/makedev?  I believe this is
> the case on MinGW, for instance.)

If so, it would be a separate patch, as a change in policy.  For now,
compilation failure on mingw when attempting to use major() is no change
in status quo.

> I think we should check sys/types.h last.  That will future-proof
> against C libraries where these functions are in both sys/mkdev.h and
> sys/types.h deciding to do the same deprecation that glibc has done.

Good idea. Will respin to check mkdev.h first (as before), then
sysmacros.h, and sys/types.h last.

--
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


signature.asc (617 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] AC_HEADER_MAJOR: port to glibc 2.25

Nick Bowler-2
In reply to this post by Eric Blake-3
Hi Eric,

On 2016-09-14, Eric Blake <[hidden email]> wrote:
[...]
> * lib/autoconf/headers.m4 (AC_HEADER_MAJOR): Check for sysmacros.h
> first, rather than after determining if sys/types.h pollutes the
> namespace.
> * doc/autoconf.texi (Particular Headers) <AC_HEADER_MAJOR>: Expand
> details on usage, and on workarounds for non-updated projects.
[...]
> diff --git a/doc/autoconf.texi b/doc/autoconf.texi
> index 029ddd6..f2494d8 100644
> --- a/doc/autoconf.texi
> +++ b/doc/autoconf.texi
> @@ -5977,6 +5977,27 @@ Particular Headers
>  @code{makedev}, but @file{sys/mkdev.h} does, define
>  @code{MAJOR_IN_MKDEV}; otherwise, if @file{sys/sysmacros.h} does, define
>  @code{MAJOR_IN_SYSMACROS}.

I think this text above should also be updated for clarity.  From the
current text one might reasonably infer that the MAJOR_IN_xxx macros are
defined only if <sys/types.h> does not define major, minor and makedev,
which is true originally but no longer the case with this patch.

Perhaps something like this:

  If <sys/sysmacros.h> is required (possibly in addition to
  <sys/types.h>) for the definitions of major, minor and makedev,
  define MAJOR_IN_SYSMACROS.  Otherwise, if <sys/mkdev.h> is
  required, define MAJOR_IN_MKDEV.

Followed by the example usage.  I left it vague about <sys/types.h>
because I don't know whether any systems require explicitly including
<sys/types.h> in addition to either <sys/sysmacros.h> or <sys/mkdev.h>.

> +To properly use any of these three functions, your code should contain
> +something like:
[...]

Cheers,
  Nick