cpp.req: track included files down to the first external file

Some header files have protection against being included into user
code directly.  This means that, when processing such files, cpp
is going to fail, and some dependencies probably will be missing.

/usr/include/gtk-2.0/gtk/gtkaccessible.h:
    20  #if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
    21  #error "Only <gtk/gtk.h> can be included directly."
    22  #endif
    23
    24  #ifndef __GTK_ACCESSIBLE_H__
    25  #define __GTK_ACCESSIBLE_H__
    26
    27  #include <atk/atk.h>
    28  #include <gtk/gtkwidget.h>

To remedy the problem, we should, as per the above example, process
gtk/gtk.h dependencies recursively.  Dependencies which we now attribute
to gtk/gtk.h are: 1) files which are packaged within the same subpackage
- these dependencies will be optimized out later by rpm; 2) the first
file not packaged into this subpackage, which is atk/atk.h.  Files below
atk/atk.h are not processed.

    Packaged?     Stack
                +---------------------+
        +       | gtk/gtk.h           |
                +---------------------+
        +       | gtk/gtkaccessible.h | <- SPmark
                +---------------------+
        -       | atk/atk.h           |
                +---------------------+
                | ...                 |

Also note that packaged files in cpp output should not be identified by
filenames, since filenames in the output will be possibly non-canonical.
Therefore I use standard unix technique to identify files by (dev,ino).

/usr/include/boost/spirit/home/support/detail/lexer/containers/ptr_vector.hpp:
     9  #include "../size_t.hpp"
This commit is contained in:
Alexey Tourbin 2011-09-20 04:56:07 +04:00
parent cf9820cea4
commit 8af14dd777

View File

@ -1,6 +1,6 @@
#!/bin/sh -efu
#
# Copyright (C) 2008 Alexey Tourbin <at@altlinux.org>
# Copyright (C) 2008, 2011 Alexey Tourbin <at@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -9,6 +9,7 @@
. @RPMCONFIGDIR@/functions
. @RPMCONFIGDIR@/find-package
. @RPMCONFIGDIR@/tmpdir.sh
[ -n "${RPM_LIBDIR-}" ] || RPM_LIBDIR=`rpm --eval %_libdir`
PKG_CONFIG_PATH=$RPM_LIBDIR/pkgconfig:/usr/share/pkgconfig
@ -101,21 +102,38 @@ CppReq()
fi
fi
out=$(echo "$out" |sed -n '/^#.* "\//{s/"//g;p}')
echo "$out" |awk -v prog="$PROG" -v hdr="$f" '
# Prepare the list of files in cpp output which are packaged in this supbackage.
echo "$out" |cut -d' ' -f3 |
xargs -r --delimiter='\n' stat -c '%d,%i %n' |
sort -u >$tmpdir/out.f2i
PackagedFiles "$f" |sed "s|^|${RPM_BUILD_ROOT-}|" |
xargs -r --delimiter='\n' stat -c '%d,%i %n' |
sort -u >$tmpdir/pkg.f2i
join -o 1.2 $tmpdir/{out,pkg}.f2i >$tmpdir/pf
echo "$out" |awk -v prog="$PROG" -v hdr="$f" -v pf="$tmpdir"/pf '
# info cpp "Preprocessor Output"
BEGIN {
SP = 0
SPmark = 0
Stack[SP] = hdr
while ((getline <pf) > 0)
Packaged[$1] = 1
}
function Push(f) {
Stack[++SP]=f
if (SP==1)
if (SPmark == SP && !Printed[f]++)
print f
if (SPmark == SP && Packaged[f])
SPmark++
Stack[++SP] = f
}
function Pop(f) {
if (f != Stack[--SP])
printf "%s: %s: expected pop %s, got pop %s\n",
prog, hdr, Stack[SP], f >"/dev/stderr"
if (SPmark > SP)
SPmark = SP
}
$4==1 { Push($3) }
$4==2 { Pop($3) }