8af14dd777
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"
152 lines
3.7 KiB
Bash
Executable File
152 lines
3.7 KiB
Bash
Executable File
#!/bin/sh -efu
|
|
#
|
|
# 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
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
. @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
|
|
[ -z "${RPM_BUILD_ROOT-}" ] ||
|
|
PKG_CONFIG_PATH=$RPM_BUILD_ROOT$RPM_LIBDIR/pkgconfig:$RPM_BUILD_ROOT/usr/share/pkgconfig:$PKG_CONFIG_PATH
|
|
export PKG_CONFIG_PATH
|
|
|
|
PkgconfigCflags()
|
|
{
|
|
local f="$1"; shift
|
|
local pc_files
|
|
pc_files=$(PackagedFiles "$f" |egrep "^$RPM_LIBDIR/pkgconfig/[^/]+[.]pc\$" || [ $? = 1 ])
|
|
if [ -n "${RPM_BUILD_ROOT-}" ]; then
|
|
pc_files=$(
|
|
echo "$pc_files" |sed "s|^/|0 $RPM_BUILD_ROOT/|"
|
|
set +f; ls "$RPM_BUILD_ROOT$RPM_LIBDIR/pkgconfig"/*.pc 2>/dev/null |sed 's|^/|1 /|')
|
|
pc_files=$(echo "$pc_files" |sort -u -k2 |sort -n |cut -d' ' -f2-)
|
|
Debug "pc_files:" $pc_files
|
|
fi
|
|
local pc
|
|
for pc in $pc_files; do
|
|
pkg-config --enable-recursion --cflags "$pc" ||
|
|
Fatal "$pc: pkg-config failed"
|
|
done
|
|
}
|
|
|
|
Cflags()
|
|
{
|
|
local f="$1"; shift
|
|
local cflags
|
|
cflags=$(PkgconfigCflags "$f")
|
|
set -- $cflags -I/usr/include -I${f%/*} -I${f%/*/*} -I${f%/*/*/*}
|
|
local cf
|
|
for cf; do
|
|
case $cf in
|
|
-D?*) echo $cf ;;
|
|
esac
|
|
done
|
|
for cf; do
|
|
[ -n "${RPM_BUILD_ROOT-}" ] || continue
|
|
case $cf in
|
|
-I/*) echo -I$RPM_BUILD_ROOT${cf#-I} ;;
|
|
esac
|
|
done
|
|
for cf; do
|
|
case $cf in
|
|
-I/*) echo $cf ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
gcc=
|
|
cpp=
|
|
cxx=
|
|
CppReq()
|
|
{
|
|
local f="$1"; shift
|
|
|
|
local srpm="${RPM_PACKAGE_NAME-}"
|
|
[ -n "$srpm" ] || srpm=$(rpmquery --qf='%{SOURCERPM}' -f "$f" 2>/dev/null) || srpm=foo
|
|
case "$srpm" in
|
|
gcc | gcc-[345]* | gcc[345]* )
|
|
[ -n "$gcc" ] ||
|
|
Verbose "$f: $PROG disabled for gcc"
|
|
gcc=$srpm
|
|
return 0 ;;
|
|
esac
|
|
|
|
if [ -z "$cpp" ]; then
|
|
cpp=/usr/bin/${RPM_ARCH:-noarch}-alt-linux-cpp
|
|
[ -x "$cpp" ] || cpp=/usr/bin/cpp
|
|
[ -z "${GCC_VERSION-}" ] || cpp=$cpp-$GCC_VERSION
|
|
Debug "cpp=$cpp"
|
|
fi
|
|
|
|
cflags=$(Cflags "$f")
|
|
Debug "$f: cflags:" $cflags
|
|
|
|
if ! out=$("$cpp" -w $cxx $cflags "$f"); then
|
|
if [ -n "$cxx" ]; then
|
|
Warning "$f: cpp failed"
|
|
return 0
|
|
fi
|
|
Info "$f: cpp failed, trying c++ mode"
|
|
cxx='-x c++'
|
|
if ! out=$("$cpp" -w $cxx $cflags "$f"); then
|
|
cxx=
|
|
Warning "$f: cpp failed"
|
|
return 0
|
|
fi
|
|
fi
|
|
out=$(echo "$out" |sed -n '/^#.* "\//{s/"//g;p}')
|
|
|
|
# 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) {
|
|
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) }
|
|
END {
|
|
if (SP > 0)
|
|
printf "%s: %s: non-empty stack, top %s\n",
|
|
prog, hdr, Stack[SP] >"/dev/stderr"
|
|
}' |
|
|
while read -r h; do
|
|
RPM_FINDPACKAGE_HOST_PKG_NAMES=1
|
|
FindPackage "$f" "${h#${RPM_BUILD_ROOT-}}"
|
|
done
|
|
}
|
|
|
|
ArgvFileAction CppReq "$@"
|