This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Weird behavior in glibc Makefiles, or: another example why you should never build software as root user


Hi!

This is about an oddity in glibc's Makefiles.  The underlying Makefile
issue is generally valid even if it was triggered on GNU/Hurd in this
case.


My first email on this topic has been eaten by the libc-alpha moderators
(and I did not exactly enjoy their boilerplate answer); perhaps this one
will make it through?  At least I would consider it on-topic for
libc-alpha.


On Tue, 20 Sep 2011 10:49:06 +0200, I wrote:
> About a year ago I have once seen this while running ``make check'' after
> having run ``make check'' before on the same build tree.  Now, on a
> different system, I have seen it with a plain ``make''.  Mind you, *not*
> ``make install''.
> 
>     [...]
>     make  subdir=nss -C nss ..=../ others
>     make[2]: Entering directory `/media/erich/home/thomas/tmp/glibc/tschwinge/Roger_Whittaker/nss'
>     /usr/bin/install -c -m 644 ../include/pthread.h /usr/include/pthread.h
>     /usr/bin/install: cannot remove `/usr/include/pthread.h': Permission denied
>     make[2]: *** [/usr/include/pthread.h] Error 1
>     make[2]: Leaving directory `/media/erich/home/thomas/tmp/glibc/tschwinge/Roger_Whittaker/nss'
>     make[1]: *** [nss/others] Error 2
>     make[1]: Leaving directory `/media/erich/home/thomas/tmp/glibc/tschwinge/Roger_Whittaker'
>     make: *** [all] Error 2
> 
> That happend after I was editing nss/nss_db/db-initgroups.c, and then
> resuming the build.
> 
> I guess nobody has ever seen this before, or has an explanation for such
> behavior?
> 
> This is on GNU/Hurd (but I can't see why that would matter), with Debian
> make 3.81-8.1.
> 
> I will try poking around in the Makefiles later on...

Which I have now done, and here follows my analysis.

In the recent case, this behavior is triggered with
[glibc]/nss/nss_files/files-init.c.  That one contains #include
<nscd/nscd.h>.

[glibc]/nscd/nscd.h contains #include <pthread.h>.  <pthread.h> is
resolved to [glibc]/include/pthread.h which is a glibc-internal wrapper
that does #include_next <pthread.h> to get the real pthread header, and
additionally ``extern void __pthread_initialize (void) __attribute__
((weak));''.  On GNU/Hurd, the #include_next <pthread.h> resolves to
/usr/include/pthread.h, as our libpthread is not yet integrated with
glibc.  So far, so good; this works.

After the first build, [glibc.build]/nss/files-init.os.d contains these
dependency rules:

    $(common-objpfx)nss/files-init.os: \
     nss_files/files-init.c ../include/libc-symbols.h \
     $(common-objpfx)config.h \
     ../sysdeps/wordsize-32/symbol-hacks.h ../nscd/nscd.h \
     ../include/pthread.h /usr/include/pthread.h \
     /usr/include/pthread/pthread.h ../include/features.h \
     [...]

That is, [glibc.build]/nss/files-init.os depends on
/usr/include/pthread.h (which is correct).

Now, [glibc]/Makerules happens to contain the following rules:

    # This implicit rule installs headers from the source directory.
    # It may be ignored in preference to rules from sysd-rules to find
    # headers in the sysdeps tree.
    $(inst_includedir)/%.h: $(objpfx)%.h $(+force)
            $(do-install)
    $(inst_includedir)/%.h: %.h $(+force)
            $(do-install)
    $(inst_includedir)/%.h: $(..)include/%.h $(+force)
            $(do-install)

These are, of course intended for header installation.  (But are not
guarded for the ``make install'' case.)

The last of these can be expanded as follows:

    /usr/include/pthread.h: $(..)include/pthread.h $(+force)
            $(do-install)

Thus, we can see what happens -- due to the *.d file containing a
files-init.os: /usr/include/pthread dependency, the build system will try
to $(do-install) from include/pthread.h to /usr/include/pthread.h -- even
in a ``make all'' or ``make check'' case, not ``make install''!  This
will only be triggered on a re-make (after the *.d files have been
built), and it can also be triggered in the testsuite where there are
also several #include <pthread.h>.

At first I thought: ``Why would glibc ever install a header from
[glibc]/include/ to /usr/include/; aren't these purely for glibc-local
build-internal headers?''  But this is not true, as it turns out.  For
example, on x86 GNU/Linux, include/limits.h, include/values.h,
include/features.h, include/gnu-versions.h, include/bits/xopen_lim.h,
include/gnu/libc-version.h, include/stubs-biarch.h are installed from
[glibc]/include/ to /usr/include/.


Thinking about it, a cure is to *build* (as in ``make all'') with
``install_root=/INVALID'', thus invalidating the
``$(inst_includedir)/%.h: $(..)include/%.h'' rule.  This works; nice.

For a one-off build of glibc, this issue does never matter, as there are
no *.d files yet.


In the long term, we (GNU/Hurd) are planning on integrating our
libpthread with glibc, as there are other inter-dependency issues, too.
Doing so will resolve this specific case, but the general Makefile oddity
remains.


GrÃÃe,
 Thomas

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]