linux-26-build-updates-20040601
[openafs.git] / src / libafs / make_kbuild_makefile.pl
1 #!/usr/bin/perl
2 # make_kbuild_makefile.pl
3 # Generate a Makefile for use with the Linux 2.6+ kernel build system
4 #
5 # Usage: make_kbuild_makefile.pl ${KDIR} ${TARG} Makefiles...
6 #
7 # The specified makefiles will be scanned for variable values
8 # The module ${TARG} will be built in ${TOP_SRCDIR}/src/libafs/${KDIR}.
9 # It will include objects listed in ${AFSAOBJS} and ${AFSNONFSOBJS}
10 # Appropriate source files for each object will be symlinked into ${KDIR}
11 # EXTRA_CFLAGS will be set to ${CFLAGS} ${COMMON_INCLUDE}
12
13 # Produces ${KDIR}/Makefile, suitable for use with kbuild
14
15 use IO::File;
16
17
18 if (@ARGV < 3) {
19   die "Usage: echo objects... | $0 KDIR TARG Makefiles...\n";
20 }
21
22 ($KDIR, $TARG, @Makefiles) = @ARGV;
23 $TARG =~ s/\.k?o$//;
24
25 ## Read in all of the Makefiles given on the command line
26 ## Our ultimate goal is to find the correct source file for each object.
27 ## We make the following assumptions:
28 ## - Every variable is defined before it is used.
29 ## - Each of our objects has exactly one dependency, which is the name
30 ##   of the source file that needs to be symlinked into $KDIR
31 foreach $mf (@Makefiles) {
32   $F = new IO::File($mf, O_RDONLY) or die "$mf: $!\n";
33   $text = '';
34   while (<$F>) {
35     chomp;
36     $text .= $_;
37     next if $text =~ s/\\$/ /;                 ## Continuation
38     if ($text =~ /^#/) { $text = ''; next }    ## Comment
39     #print STDERR "<< $text\n";
40
41     $text =~ s/\$\((\w+)\)/$vars{$1}/g;        # Substitute variables
42     $text =~ s/\$\{(\w+)\}/$vars{$1}/g;
43     #print STDERR ">> $text\n";
44
45     if ($text =~ /^\s*(\S+)\s*=/) {            ## Variable definition
46       ($key, $value) = ($1, $');
47       $value =~ s/^\s*//;                      # Remove leading and
48       $value =~ s/\s*$//;                      # trailing whitespace
49       $vars{$key} = $value;                    # Store it
50     }
51     elsif ($text =~ /^(\S+\.o):\s*(\S+\.c)/) {    ## Dependency
52       $deps{$1} = $2;
53     }
54     $text = '';
55   }
56   $F->close();
57 }
58
59
60 $KDIR = "$vars{TOP_OBJDIR}/src/libafs/$KDIR";
61 @objects = (split(' ', $vars{AFSAOBJS}), split(' ', $vars{AFSNONFSOBJS}));
62
63 $MV = new IO::File("$vars{TOP_OBJDIR}/src/config/Makefile.version", O_RDONLY)
64         or die "$vars{TOP_OBJDIR}/src/config/Makefile.version: $!\n";
65 while (<$MV>) {
66   s#AFS_component_version_number#$KDIR/AFS_component_version_number#g;
67   $MakefileVersion .= $_;
68 }
69 $MV->close();
70
71 if (! -d $KDIR) {
72   mkdir($KDIR, 0777) or die "$KDIR: $!\n";
73 }
74
75
76 foreach (@objects) {
77   ($src = $_) =~ s/\.o$/.c/;
78   die "No source known for $_\n" unless exists $deps{$_};
79   if (-e "$KDIR/$src" || -l "$KDIR/$src") {
80     unlink("$KDIR/$src") or die "$KDIR/$src: $!\n";
81   }
82   next unless $deps{$_} =~ m#/#;
83   symlink($deps{$_}, "$KDIR/$src") or die "$KDIR/$src: $!\n";
84 }
85
86 foreach $src (qw(h sys netinet)) {
87   if (-e "$KDIR/$src" || -l "$KDIR/$src") {
88     unlink("$KDIR/$src") or die "$KDIR/$src: $!\n";
89   }
90   symlink("$vars{LINUX_KERNEL_PATH}/include/linux", "$KDIR/$src")
91     or die "$KDIR/$src: $!\n";
92 }
93
94 $cflags = "$vars{CFLAGS} $vars{COMMON_INCLUDE}";
95 $cflags =~ s#-I(?!/)#-I$KDIR/#g;
96 $cflags =~ s/\s+/ \\\n /g;
97 $F = new IO::File("$KDIR/Makefile", O_WRONLY|O_CREAT|O_TRUNC, 0666)
98      or die "$KDIR/Makefile: $!\n";
99 print $F "EXTRA_CFLAGS=$cflags\n";
100 print $F "obj-m := $TARG.o\n";
101 print $F "$TARG-objs := ", join("\\\n $_", @objects), "\n";
102 print $F "\n$MakefileVersion\n";
103 $F->close() or die "$KDIR/Makefile: $!\n";
104