build: split scripts/metadata.pl into target-metadata.pl and package-metadata.pl
[oweals/openwrt.git] / scripts / target-metadata.pl
1 #!/usr/bin/env perl
2 use FindBin;
3 use lib "$FindBin::Bin";
4 use strict;
5 use metadata;
6 use Getopt::Long;
7
8 sub target_config_features(@) {
9         my $ret;
10
11         while ($_ = shift @_) {
12                 /arm_v(\w+)/ and $ret .= "\tselect arm_v$1\n";
13                 /broken/ and $ret .= "\tdepends on BROKEN\n";
14                 /audio/ and $ret .= "\tselect AUDIO_SUPPORT\n";
15                 /display/ and $ret .= "\tselect DISPLAY_SUPPORT\n";
16                 /dt/ and $ret .= "\tselect USES_DEVICETREE\n";
17                 /gpio/ and $ret .= "\tselect GPIO_SUPPORT\n";
18                 /pci/ and $ret .= "\tselect PCI_SUPPORT\n";
19                 /pcie/ and $ret .= "\tselect PCIE_SUPPORT\n";
20                 /usb/ and $ret .= "\tselect USB_SUPPORT\n";
21                 /usbgadget/ and $ret .= "\tselect USB_GADGET_SUPPORT\n";
22                 /pcmcia/ and $ret .= "\tselect PCMCIA_SUPPORT\n";
23                 /rtc/ and $ret .= "\tselect RTC_SUPPORT\n";
24                 /squashfs/ and $ret .= "\tselect USES_SQUASHFS\n";
25                 /jffs2$/ and $ret .= "\tselect USES_JFFS2\n";
26                 /jffs2_nand/ and $ret .= "\tselect USES_JFFS2_NAND\n";
27                 /ext4/ and $ret .= "\tselect USES_EXT4\n";
28                 /targz/ and $ret .= "\tselect USES_TARGZ\n";
29                 /cpiogz/ and $ret .= "\tselect USES_CPIOGZ\n";
30                 /ubifs/ and $ret .= "\tselect USES_UBIFS\n";
31                 /fpu/ and $ret .= "\tselect HAS_FPU\n";
32                 /spe_fpu/ and $ret .= "\tselect HAS_SPE_FPU\n";
33                 /ramdisk/ and $ret .= "\tselect USES_INITRAMFS\n";
34                 /powerpc64/ and $ret .= "\tselect powerpc64\n";
35                 /nommu/ and $ret .= "\tselect NOMMU\n";
36                 /mips16/ and $ret .= "\tselect HAS_MIPS16\n";
37                 /rfkill/ and $ret .= "\tselect RFKILL_SUPPORT\n";
38                 /low_mem/ and $ret .= "\tselect LOW_MEMORY_FOOTPRINT\n";
39                 /nand/ and $ret .= "\tselect NAND_SUPPORT\n";
40         }
41         return $ret;
42 }
43
44 sub target_name($) {
45         my $target = shift;
46         my $parent = $target->{parent};
47         if ($parent) {
48                 return $target->{parent}->{name}." - ".$target->{name};
49         } else {
50                 return $target->{name};
51         }
52 }
53
54 sub kver($) {
55         my $v = shift;
56         $v =~ tr/\./_/;
57         if (substr($v,0,2) eq "2_") {
58                 $v =~ /(\d+_\d+_\d+)(_\d+)?/ and $v = $1;
59         } else {
60                 $v =~ /(\d+_\d+)(_\d+)?/ and $v = $1;
61         }
62         return $v;
63 }
64
65 sub print_target($) {
66         my $target = shift;
67         my $features = target_config_features(@{$target->{features}});
68         my $help = $target->{desc};
69         my $confstr;
70
71         chomp $features;
72         $features .= "\n";
73         if ($help =~ /\w+/) {
74                 $help =~ s/^\s*/\t  /mg;
75                 $help = "\thelp\n$help";
76         } else {
77                 undef $help;
78         }
79
80         my $v = kver($target->{version});
81         if (@{$target->{subtargets}} == 0) {
82         $confstr = <<EOF;
83 config TARGET_$target->{conf}
84         bool "$target->{name}"
85         select LINUX_$v
86 EOF
87         }
88         else {
89                 $confstr = <<EOF;
90 config TARGET_$target->{conf}
91         bool "$target->{name}"
92 EOF
93         }
94         if ($target->{subtarget}) {
95                 $confstr .= "\tdepends on TARGET_$target->{boardconf}\n";
96         }
97         if (@{$target->{subtargets}} > 0) {
98                 $confstr .= "\tselect HAS_SUBTARGETS\n";
99                 grep { /broken/ } @{$target->{features}} and $confstr .= "\tdepends on BROKEN\n";
100         } else {
101                 $confstr .= $features;
102                 if ($target->{arch} =~ /\w/) {
103                         $confstr .= "\tselect $target->{arch}\n";
104                 }
105         }
106
107         foreach my $dep (@{$target->{depends}}) {
108                 my $mode = "depends on";
109                 my $flags;
110                 my $name;
111
112                 $dep =~ /^([@\+\-]+)(.+)$/;
113                 $flags = $1;
114                 $name = $2;
115
116                 next if $name =~ /:/;
117                 $flags =~ /-/ and $mode = "deselect";
118                 $flags =~ /\+/ and $mode = "select";
119                 $flags =~ /@/ and $confstr .= "\t$mode $name\n";
120         }
121         $confstr .= "$help\n\n";
122         print $confstr;
123 }
124
125 sub merge_package_lists($$) {
126         my $list1 = shift;
127         my $list2 = shift;
128         my @l = ();
129         my %pkgs;
130
131         foreach my $pkg (@$list1, @$list2) {
132                 $pkgs{$pkg} = 1;
133         }
134         foreach my $pkg (keys %pkgs) {
135                 push @l, $pkg unless ($pkg =~ /^-/ or $pkgs{"-$pkg"});
136         }
137         return sort(@l);
138 }
139
140 sub gen_target_config() {
141         my $file = shift @ARGV;
142         my @target = parse_target_metadata($file);
143         my %defaults;
144
145         my @target_sort = sort {
146                 target_name($a) cmp target_name($b);
147         } @target;
148
149
150         print <<EOF;
151 choice
152         prompt "Target System"
153         default TARGET_ar71xx
154         reset if !DEVEL
155         
156 EOF
157
158         foreach my $target (@target_sort) {
159                 next if $target->{subtarget};
160                 print_target($target);
161         }
162
163         print <<EOF;
164 endchoice
165
166 choice
167         prompt "Subtarget" if HAS_SUBTARGETS
168 EOF
169         foreach my $target (@target) {
170                 next unless $target->{def_subtarget};
171                 print <<EOF;
172         default TARGET_$target->{conf}_$target->{def_subtarget} if TARGET_$target->{conf}
173 EOF
174         }
175         print <<EOF;
176
177 EOF
178         foreach my $target (@target) {
179                 next unless $target->{subtarget};
180                 print_target($target);
181         }
182
183 print <<EOF;
184 endchoice
185
186 choice
187         prompt "Target Profile"
188
189 EOF
190
191         foreach my $target (@target) {
192                 my $profiles = $target->{profiles};
193                 foreach my $profile (@{$target->{profiles}}) {
194                         print <<EOF;
195 config TARGET_$target->{conf}_$profile->{id}
196         bool "$profile->{name}"
197         depends on TARGET_$target->{conf}
198 EOF
199                         my @pkglist = merge_package_lists($target->{packages}, $profile->{packages});
200                         foreach my $pkg (@pkglist) {
201                                 print "\tselect DEFAULT_$pkg\n";
202                                 $defaults{$pkg} = 1;
203                         }
204                         my $help = $profile->{desc};
205                         if ($help =~ /\w+/) {
206                                 $help =~ s/^\s*/\t  /mg;
207                                 $help = "\thelp\n$help";
208                         } else {
209                                 undef $help;
210                         }
211                         print "$help\n";
212                 }
213         }
214
215         print <<EOF;
216 endchoice
217
218 config HAS_SUBTARGETS
219         bool
220
221 config TARGET_BOARD
222         string
223
224 EOF
225         foreach my $target (@target) {
226                 $target->{subtarget} or print "\t\tdefault \"".$target->{board}."\" if TARGET_".$target->{conf}."\n";
227         }
228         print <<EOF;
229 config TARGET_SUBTARGET
230         string
231         default "generic" if !HAS_SUBTARGETS
232
233 EOF
234
235         foreach my $target (@target) {
236                 foreach my $subtarget (@{$target->{subtargets}}) {
237                         print "\t\tdefault \"$subtarget\" if TARGET_".$target->{conf}."_$subtarget\n";
238                 }
239         }
240         print <<EOF;
241 config TARGET_PROFILE
242         string
243 EOF
244         foreach my $target (@target) {
245                 my $profiles = $target->{profiles};
246                 foreach my $profile (@$profiles) {
247                         print "\tdefault \"$profile->{id}\" if TARGET_$target->{conf}_$profile->{id}\n";
248                 }
249         }
250
251         print <<EOF;
252
253 config TARGET_ARCH_PACKAGES
254         string
255         
256 EOF
257         foreach my $target (@target) {
258                 next if @{$target->{subtargets}} > 0;
259                 print "\t\tdefault \"".($target->{arch_packages} || $target->{board})."\" if TARGET_".$target->{conf}."\n";
260         }
261         print <<EOF;
262
263 config DEFAULT_TARGET_OPTIMIZATION
264         string
265 EOF
266         foreach my $target (@target) {
267                 next if @{$target->{subtargets}} > 0;
268                 print "\tdefault \"".$target->{cflags}."\" if TARGET_".$target->{conf}."\n";
269         }
270         print "\tdefault \"-Os -pipe -funit-at-a-time\"\n";
271         print <<EOF;
272
273 config CPU_TYPE
274         string
275 EOF
276         foreach my $target (@target) {
277                 next if @{$target->{subtargets}} > 0;
278                 print "\tdefault \"".$target->{cputype}."\" if TARGET_".$target->{conf}."\n";
279         }
280         print "\tdefault \"\"\n";
281
282         my %kver;
283         foreach my $target (@target) {
284                 my $v = kver($target->{version});
285                 next if $kver{$v};
286                 $kver{$v} = 1;
287                 print <<EOF;
288
289 config LINUX_$v
290         bool
291
292 EOF
293         }
294         foreach my $def (sort keys %defaults) {
295                 print "\tconfig DEFAULT_".$def."\n";
296                 print "\t\tbool\n\n";
297         }
298 }
299
300 sub gen_profile_mk() {
301         my $file = shift @ARGV;
302         my $target = shift @ARGV;
303         my @targets = parse_target_metadata($file);
304         foreach my $cur (@targets) {
305                 next unless $cur->{id} eq $target;
306                 print "PROFILE_NAMES = ".join(" ", map { $_->{id} } @{$cur->{profiles}})."\n";
307                 foreach my $profile (@{$cur->{profiles}}) {
308                         print $profile->{id}.'_NAME:='.$profile->{name}."\n";
309                         print $profile->{id}.'_PACKAGES:='.join(' ', @{$profile->{packages}})."\n";
310                 }
311         }
312 }
313
314 sub parse_command() {
315         GetOptions("ignore=s", \@ignore);
316         my $cmd = shift @ARGV;
317         for ($cmd) {
318                 /^config$/ and return gen_target_config();
319                 /^profile_mk$/ and return gen_profile_mk();
320         }
321         die <<EOF
322 Available Commands:
323         $0 config [file]                        Target metadata in Kconfig format
324         $0 profile_mk [file] [target]           Profile metadata in makefile format
325
326 EOF
327 }
328
329 parse_command();