From 01d390d0d022309d06760aac1373829a35a6d79c Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 6 Jul 2009 17:51:00 -0700 Subject: [PATCH] Build shadow header files when necessary on Linux The current kernel module build infrastructure relies on the ability to create symlinks from known directory names used in the AFS code to the actual locations of the kernel header files. This breaks if there is no single kernel header tree and instead multiple trees are layered together by kbuild using compile-time -I include paths. Attempt to detect this case by seeing if linux/types.h is in the kernel header directory where we expect it. If not, rather than creating symlinks for h, sys, and netinet, create directories and populate them with single-line headers that just include the corresponding linux/*.h header. The list of headers for which to do this is generated dynamically by analyzing the AFS kernel source code and looking for relevant #include directives. This patch has been part of the Debian OpenAFS package since 1.4.10+dfsg1-1. The check for whether we have layered kernel header trees may be specific to Debian and may require modification later if other Linux distributions do something similar. FIXES 124583 Reviewed-on: http://gerrit.openafs.org/6 Verified-by: Russ Allbery Reviewed-by: Derrick Brashear Verified-by: Derrick Brashear --- src/libafs/make_kbuild_makefile.pl | 59 +++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/libafs/make_kbuild_makefile.pl b/src/libafs/make_kbuild_makefile.pl index 9116869a2..3de680e74 100755 --- a/src/libafs/make_kbuild_makefile.pl +++ b/src/libafs/make_kbuild_makefile.pl @@ -94,12 +94,61 @@ foreach (keys %all_objs) { symlink($deps{$_}, "$KDIR/$src") or die "$KDIR/$src: $!\n"; } -foreach $src (qw(h sys netinet)) { - if (-e "$KDIR/$src" || -l "$KDIR/$src") { - unlink("$KDIR/$src") or die "$KDIR/$src: $!\n"; +%remap = ('h' => 'linux', 'netinet' => 'linux', 'sys' => 'linux'); +if (-f "$vars{LINUX_KERNEL_PATH}/include/linux/types.h") { + foreach $src (keys %remap) { + if (-e "$KDIR/$src" || -l "$KDIR/$src") { + unlink("$KDIR/$src") or die "$KDIR/$src: $!\n"; + } + symlink("$vars{LINUX_KERNEL_PATH}/include/linux", "$KDIR/$src") + or die "$KDIR/$src: $!\n"; + } +} else { + foreach $src (keys %remap) { + system ('rm', '-rf', "$KDIR/$src"); # too crude? + mkdir("$KDIR/$src", 0777) or die "$KDIR/$src: $!\n"; + } + %seen = (); + @q = <$KDIR/*.[Sc]>; + @include_dirs = map { /^\// ? $_ : "$KDIR/$_" } + split /[\s\\]*-I/, $vars{COMMON_INCLUDE}; + push @include_dirs, "$vars{TOP_SRCDIR}/../include/rx", "$vars{TOP_SRCDIR}/rx"; + while (@q) { + $src = shift @q; + $content = new IO::File($src, O_RDONLY) or die "$src: $!\n"; + LINE: + while (<$content>) { + chomp; + if (/^\s*#\s*include\s*[<"](?:\.\.\/)?([^\/>"]*)(.*?)[>"]/) { + $inc = "$1$2"; + if (exists $seen{$inc}) { + next; + } elsif (exists $remap{$1} && $2 !~ /.\//) { + $H = new IO::File("$KDIR/$inc", O_WRONLY|O_CREAT|O_TRUNC, 0666) + or die "$KDIR/$inc: $!\n"; + print $H "#include \n"; + $H->close() or die "$KDIR/$inc: $!\n"; + } else { + for $dir (@include_dirs) { + if (-f "$dir/$inc") { + push @q, "$dir/$inc"; + $seen{$inc} = 1; + next LINE; + } + } + if ($1 =~ /^(arpa|asm|.*fs|i?net|kern|ksys|linux|mach|rpc|scsi|vm)$/ + || !length($2)) { + # Safe to ignore silently. + } else { + warn "Ignoring $_ ($inc not found)\n"; + } + } + $seen{$inc} = 1; + } elsif (/^\s*#\s*include/) { + warn "Ignoring $_ (unrecognized syntax)\n"; + } + } } - symlink("$vars{LINUX_KERNEL_PATH}/include/linux", "$KDIR/$src") - or die "$KDIR/$src: $!\n"; } $cflags = "$vars{CFLAGS} $vars{COMMON_INCLUDE}"; -- 2.39.5