sub srcdir { my($uname_r)=@_; $basedir."/".($uname_r lt "2.5" ? "2.4" : "2.5"); }
my $modbindir=$basedir."/modbin";
my @sources=qw(proc.c inode.c dir.c file.c symlink.c);
-my $tmp_dir="prepmod-tmp-dir";
my $quiet;
my $kernel;
my $uname_r=($proc_version=~/^Linux version (\S+)/)[0] || _readfile "uname -r|";
chomp $uname_r;
confess "Failed to detect kernel version" if !$uname_r;
+my $uname_smp=($uname_r=~s/smp$// && "smp");
my $uname_r_base=($uname_r=~/^([^-]+)/)[0];
print STDERR "Running kernel version: $uname_r (base version $uname_r_base)\n" if !$quiet;
-my $moduledir="/lib/modules/$uname_r/kernel/fs/lufs";
+my $moduledir="/lib/modules/$uname_r$uname_smp/kernel/fs/lufs";
print STDERR "Destination module directory: $moduledir\n" if !$quiet;
-do { $kernel||=$_ if -d $_; } for ("/lib/modules/$uname_r/build");
-do { $kernel||=$_ if -d $_; } for ("/usr/src/kernel-headers-$uname_r");
-do { $kernel||=$_ if -d $_; } for ("/usr/src/linux-$uname_r");
-do { $kernel||=$_ if -d $_; } for ("/usr/src/linux-$uname_r_base");
-do { $kernel||=$_ if -d $_; } for ("/usr/src/linux");
+my @kernel_paths=(
+ "/lib/modules/$uname_r/build",
+ "/usr/src/kernel-headers-$uname_r",
+ "/usr/src/linux-$uname_r",
+ "/usr/src/linux-$uname_r_base",
+ "/usr/src/linux",
+ );
+do { $kernel||=$_ if -d $_; } for (@kernel_paths);
if (!$kernel) {
print STDERR "Failed to find kernel headers for $uname_r\n" if !$kernel && !$quiet;
}
if _system "/bin/rm -rf $moduledir; /bin/mkdir -p $moduledir; /bin/ln -s $_ $moduledir/lufs.o";
_pass 1;
}
-confess "lufs module not loaded: Try running $basedir/prepmod to see more.";
+confess "lufs module not loaded: Try running $basedir/prepmod to see more." if $quiet;
+confess "Failed to prepare lufs.o module for your Linux kernel $uname_r.\n"
+ .($kernel ? "Detected Linux kernel sources \"$kernel\" do not appear to be valid.\n"
+ : "No Linux kernel sources for your running kernel were found.\n")
+ ."Please install kernel-source-x.y.z.i386.rpm or kernel-headers_x.y.z_i386.deb.\n"
+ ."The following directory paths were search (first existing directory used):\n"
+ .join("",map("\t\t$_\n",@kernel_paths));
-sub build
+sub build_gcc
{
my($kernel,$uname_r,$destmodule)=@_;
my $config=_readfile "$kernel/.config","optional";
my $autoconf=_readfile "$kernel/include/linux/autoconf.h","optional";
- $cmdline.=" -DMODVERSIONS -include $kernel/include/linux/modversions.h"
+ $cmdline.=" -DMODVERSIONS -include $kernel/include/linux/version.h -include $kernel/include/linux/modversions.h"
if 0
|| $config=~/^CONFIG_MODVERSIONS=y\b/m
|| $autoconf=~/^#define CONFIG_MODVERSIONS\b/m
}
+sub build_make
+{
+my($kernel,$uname_r,$destmodule,%args)=@_;
+
+ print STDERR "Using kernel sources: $kernel\n" if !$quiet;
+ confess "Kernel sources $kernel do not contain 'Rules.make' file" if ! -f $kernel."/Rules.make";
+
+ my $kdebug="";
+ do { $kdebug=$_ if !/^@/; } for ('@KDEBUG_FLAGS@');
+ my $predir=srcdir $uname_r;
+ $predir=$ENV{"PWD"}."/$predir" if $predir!~m#^/#;
+ # Do not use existing '$kernel/tmp_include_depends' or '$kernel/.depend'
+ # as it may contain non-existing pathnames:
+ _system "make -C $kernel dep" if !$args{"nodep"};
+ # Workaround a bug in at least Red Hat 2.4.18-18.8.0
+ for ("$kernel/include/linux/modversions.h") {
+ _system "cp -p $_ $_-orig" if ! -f "$_-orig";
+ _writefile $_,"#include <linux/version.h>\t/* lufs */\n"._readfile $_;
+ }
+ my $cmdline="make -C $kernel"
+ ." SUBDIRS=\"$predir\" modules"
+ ." EXTRA_CFLAGS=\"$kernel_gcc_args\""
+ .($quiet ? ' &>/dev/null' : '');
+ my @objects=map({ my $o=$_; $o=~s/[.]c$/.o/; $o; } @sources);
+ return !_system "set -e; /bin/mkdir -p `dirname $destmodule`; /bin/rm -f $destmodule;"
+ ." $cmdline;"
+ ." /bin/rm -f ".join(" ",map(("$predir/$_","$predir/.$_.flags"),@objects)).";"
+ ." /bin/mv -f $predir/lufs.o $destmodule;";
+}
+
+
+sub build
+{
+my($kernel,$uname_r,$destmodule,%args)=@_;
+
+ # Debian uname(1) does not support '-p'.
+ my $arch=_readfile "uname -p|" || _readfile "uname -m|";
+ chomp $arch;
+ my $single_config=-f "$kernel/.config";
+ if (!$single_config) {
+ my $spec_config="$kernel/configs/kernel-$uname_r_base-$arch".($uname_smp ? "-smp" : "").".config";
+ _system "ln -s $spec_config $kernel/.config"
+ if -f $spec_config;
+ }
+ my $r;
+ if (-f "$kernel/Rules.make" && -f "$kernel/.config")
+ { $r=build_make $kernel,$uname_r,$destmodule,%args; }
+ else
+ { $r=build_gcc $kernel,$uname_r,$destmodule,%args; }
+ _system "rm -f $kernel/.config"
+ if !$single_config;
+ return $r;
+}
+
+
sub prebuild_kernel
{
-my($dir,$vendor,$uname_r)=@_;
+my($dir,$vendor,$uname_r,%args)=@_;
confess "Unrecognized vendor for dir: $dir" if !$vendor;
confess "Unrecognized uname_r for dir: $dir" if !$uname_r;
- confess "Failed to build $dir" if !build $dir,$uname_r,$modbindir."/lufs-$vendor-$uname_r.o";
+ confess "Failed to build $dir" if !build $dir,$uname_r,$modbindir."/lufs-$vendor-$uname_r.o",%args;
}
my $uname_r;
$uname_r||=($rpm=~m#/kernel-source-([^-]+-[^-]+)[.][^.]+[.]rpm$#)[0];
my $uname_r_base=($uname_r=~/^([^-]+)/)[0];
- _system "/bin/rm -rf $tmp_dir; /bin/mkdir $tmp_dir; set -e;"
- # Here we will extract even some false 'include's but we filter dirs just for speed/space.
- ." /usr/bin/rpm2cpio '$rpm' | (cd $tmp_dir; /bin/cpio -id --quiet ./usr/src/linux*/{.config,include/*})"
- and confess "Extraction of: $rpm";
my $dir;
- do { $dir||=$_ if -d $_; } for ($tmp_dir."/usr/src/linux-$uname_r");
- do { $dir||=$_ if -d $_; } for ($tmp_dir."/usr/src/linux-$uname_r_base"); # older RedHat kernels
+ do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r");
+ do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r_base"); # older RedHat kernels
+ confess "Kernel sources already found in $dir" if $dir;
+ # '--nodeps' to prevent: error: Failed dependencies: perl-base is needed by *mdk
+ _system "rpm -i --nodeps '$rpm'" and confess "RPM installation of $rpm";
+ do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r");
+ do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r_base"); # older RedHat kernels
$dir or confess "Kernel source tree not found in: $rpm";
- _writefile "| patch $dir/include/linux/rhconfig.h",<<'RHCONFIG_H_NOBOOT_EOF';
---- ./include/linux/rhconfig.h-orig Thu Aug 21 14:50:16 2003
-+++ ./include/linux/rhconfig.h Thu Aug 21 14:59:22 2003
-@@ -10,7 +10,7 @@
- * /boot/kernel.h - initscripts should create it for us
- */
-
--#include "/boot/kernel.h"
-+/* lufs: #include "/boot/kernel.h" */
-
- #if defined(__BOOT_KERNEL_SMP) && (__BOOT_KERNEL_SMP == 1)
- #define __module__smp
-RHCONFIG_H_NOBOOT_EOF
+ _system "cp -p $dir/include/linux/rhconfig.h $dir/include/linux/rhconfig.h-orig"
+ if -f "$dir/include/linux/rhconfig.h";
+ # Do not use existing '$dir/tmp_include_depends' or '$dir/.depend'
+ # as it may contain non-existing pathnames:
+ _system "make -C $dir dep";
for my $smp ("","smp") {
my @archs=qw(i386 i586 i686 athlon);
for my $arch (@archs) {
"__BOOT_KERNEL_BIGMEM"=>0,
"__BOOT_KERNEL_DEBUG"=>0,
);
- local $kernel_gcc_args=join(" ",map({ " -D$_=".($boot{$_} ? 1 : 0); } keys(%boot)))
- ." -march=$arch"
- ." ".$kernel_gcc_args;
- prebuild_kernel $dir,$vendor,$uname_r.$smp.".".$arch;
+ if (-f "$dir/include/linux/rhconfig.h") {
+ my $defines="";
+ for (keys(%boot)) {
+ $defines.="+#define $_ ".($boot{$_} ? 1 : 0)."\n";
+ }
+ _system "cp -p -f $dir/include/linux/rhconfig.h-orig $dir/include/linux/rhconfig.h";
+ _writefile "| patch $dir/include/linux/rhconfig.h",<<"RHCONFIG_H_NOBOOT_EOF";
+--- ./include/linux/rhconfig.h-orig Thu Aug 21 14:50:16 2003
++++ ./include/linux/rhconfig.h Thu Aug 21 14:59:22 2003
+\@\@ -10,7 +10,@{[ 7+keys(%boot) ]} \@\@
+ * /boot/kernel.h - initscripts should create it for us
+ */
+
+-#include "/boot/kernel.h"
++/* lufs: #include "/boot/kernel.h" */
+$defines
+ #if defined(__BOOT_KERNEL_SMP) && (__BOOT_KERNEL_SMP == 1)
+ #define __module__smp
+RHCONFIG_H_NOBOOT_EOF
+ }
+ # Mandrake packages have no configs/ and they have just that '.config' file.
+ my $single_config=-f "$dir/.config";
+ if (!$single_config) {
+ my $spec_config="$dir/configs/kernel-$uname_r_base-$arch".($smp ? "-smp" : "").".config";
+ next if ! -f $spec_config;
+ _system "ln -s $spec_config $dir/.config";
+ }
+ prebuild_kernel $dir,$vendor,$uname_r.$smp.".".$arch,"nodep"=>1;
+ _system "rm -f $dir/.config"
+ if !$single_config;
}
}
- _system "/bin/rm -rf $tmp_dir" and confess "Deletion of: $tmp_dir";
+ _system "rpm -e kernel-source-$uname_r" and confess "Remove of kernel-source-$uname_r";
+ _system "rm -rf $dir";
}
sub prebuild_dir
my $vendor;
chomp (my $debian=_readfile "/etc/debian_version","optional");
+ $debian=~tr#/#_#;
$vendor="Debian".$debian if $debian && $dir=~m#^/usr/src/#;
my $uname_r;
$uname_r||=($dir=~m#/kernel-headers-([^/]+)/*$#)[0];