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