mwlwifi: Update to latest commit in upstream repo
[openwrt/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 /^minor$/ and $ret .= "\tselect USES_MINOR\n";
31 /^ubifs$/ and $ret .= "\tselect USES_UBIFS\n";
32 /^fpu$/ and $ret .= "\tselect HAS_FPU\n";
33 /^spe_fpu$/ and $ret .= "\tselect HAS_SPE_FPU\n";
34 /^ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n";
35 /^powerpc64$/ and $ret .= "\tselect powerpc64\n";
36 /^nommu$/ and $ret .= "\tselect NOMMU\n";
37 /^mips16$/ and $ret .= "\tselect HAS_MIPS16\n";
38 /^rfkill$/ and $ret .= "\tselect RFKILL_SUPPORT\n";
39 /^low_mem$/ and $ret .= "\tselect LOW_MEMORY_FOOTPRINT\n";
40 /^small_flash$/ and $ret .= "\tselect SMALL_FLASH\n";
41 /^nand$/ and $ret .= "\tselect NAND_SUPPORT\n";
42 /^virtio$/ and $ret .= "\tselect VIRTIO_SUPPORT\n";
43 }
44 return $ret;
45 }
46
47 sub target_name($) {
48 my $target = shift;
49 my $parent = $target->{parent};
50 if ($parent) {
51 return $target->{parent}->{name}." - ".$target->{name};
52 } else {
53 return $target->{name};
54 }
55 }
56
57 sub kver($) {
58 my $v = shift;
59 $v =~ tr/\./_/;
60 if (substr($v,0,2) eq "2_") {
61 $v =~ /(\d+_\d+_\d+)(_\d+)?/ and $v = $1;
62 } else {
63 $v =~ /(\d+_\d+)(_\d+)?/ and $v = $1;
64 }
65 return $v;
66 }
67
68 sub print_target($) {
69 my $target = shift;
70 my $features = target_config_features(@{$target->{features}});
71 my $help = $target->{desc};
72 my $confstr;
73
74 chomp $features;
75 $features .= "\n";
76 if ($help =~ /\w+/) {
77 $help =~ s/^\s*/\t /mg;
78 $help = "\thelp\n$help";
79 } else {
80 undef $help;
81 }
82
83 my $v = kver($target->{version});
84 if (@{$target->{subtargets}} == 0) {
85 $confstr = <<EOF;
86 config TARGET_$target->{conf}
87 bool "$target->{name}"
88 select LINUX_$v
89 EOF
90 }
91 else {
92 $confstr = <<EOF;
93 config TARGET_$target->{conf}
94 bool "$target->{name}"
95 EOF
96 }
97 if ($target->{subtarget}) {
98 $confstr .= "\tdepends on TARGET_$target->{boardconf}\n";
99 }
100 if (@{$target->{subtargets}} > 0) {
101 $confstr .= "\tselect HAS_SUBTARGETS\n";
102 grep { /broken/ } @{$target->{features}} and $confstr .= "\tdepends on BROKEN\n";
103 } else {
104 $confstr .= $features;
105 if ($target->{arch} =~ /\w/) {
106 $confstr .= "\tselect $target->{arch}\n";
107 }
108 if ($target->{has_devices}) {
109 $confstr .= "\tselect HAS_DEVICES\n";
110 }
111 }
112
113 foreach my $dep (@{$target->{depends}}) {
114 my $mode = "depends on";
115 my $flags;
116 my $name;
117
118 $dep =~ /^([@\+\-]+)(.+)$/;
119 $flags = $1;
120 $name = $2;
121
122 next if $name =~ /:/;
123 $flags =~ /-/ and $mode = "deselect";
124 $flags =~ /\+/ and $mode = "select";
125 $flags =~ /@/ and $confstr .= "\t$mode $name\n";
126 }
127 $confstr .= "$help\n\n";
128 print $confstr;
129 }
130
131 sub merge_package_lists($$) {
132 my $list1 = shift;
133 my $list2 = shift;
134 my @l = ();
135 my %pkgs;
136
137 foreach my $pkg (@$list1, @$list2) {
138 $pkgs{$pkg} = 1;
139 }
140 foreach my $pkg (keys %pkgs) {
141 push @l, $pkg unless ($pkg =~ /^-/ or $pkgs{"-$pkg"});
142 }
143 return sort(@l);
144 }
145
146 sub gen_target_config() {
147 my $file = shift @ARGV;
148 my @target = parse_target_metadata($file);
149 my %defaults;
150
151 my @target_sort = sort {
152 target_name($a) cmp target_name($b);
153 } @target;
154
155 foreach my $target (@target_sort) {
156 next if @{$target->{subtargets}} > 0;
157 print <<EOF;
158 config DEFAULT_TARGET_$target->{conf}
159 bool
160 depends on TARGET_PER_DEVICE_ROOTFS
161 default y if TARGET_$target->{conf}
162 EOF
163 foreach my $pkg (@{$target->{packages}}) {
164 print "\tselect DEFAULT_$pkg if TARGET_PER_DEVICE_ROOTFS\n";
165 }
166 }
167
168 print <<EOF;
169 choice
170 prompt "Target System"
171 default TARGET_ar71xx
172 reset if !DEVEL
173
174 EOF
175
176 foreach my $target (@target_sort) {
177 next if $target->{subtarget};
178 print_target($target);
179 }
180
181 print <<EOF;
182 endchoice
183
184 choice
185 prompt "Subtarget" if HAS_SUBTARGETS
186 EOF
187 foreach my $target (@target) {
188 next unless $target->{def_subtarget};
189 print <<EOF;
190 default TARGET_$target->{conf}_$target->{def_subtarget} if TARGET_$target->{conf}
191 EOF
192 }
193 print <<EOF;
194
195 EOF
196 foreach my $target (@target) {
197 next unless $target->{subtarget};
198 print_target($target);
199 }
200
201 print <<EOF;
202 endchoice
203
204 choice
205 prompt "Target Profile"
206 default TARGET_MULTI_PROFILE if BUILDBOT
207
208 EOF
209 foreach my $target (@target) {
210 my $profile = $target->{profiles}->[0];
211 $profile or next;
212 print <<EOF;
213 default TARGET_$target->{conf}_$profile->{id} if TARGET_$target->{conf} && !BUILDBOT
214 EOF
215 }
216
217 print <<EOF;
218
219 config TARGET_MULTI_PROFILE
220 bool "Multiple devices"
221 depends on HAS_DEVICES
222 help
223 Instead of only building a single image, or all images, this allows you
224 to select images to be built for multiple devices in one build.
225
226 EOF
227
228 foreach my $target (@target) {
229 my $profiles = $target->{profiles};
230 foreach my $profile (@{$target->{profiles}}) {
231 print <<EOF;
232 config TARGET_$target->{conf}_$profile->{id}
233 bool "$profile->{name}"
234 depends on TARGET_$target->{conf}
235 EOF
236 my @pkglist = merge_package_lists($target->{packages}, $profile->{packages});
237 foreach my $pkg (@pkglist) {
238 print "\tselect DEFAULT_$pkg\n";
239 $defaults{$pkg} = 1;
240 }
241 my $help = $profile->{desc};
242 if ($help =~ /\w+/) {
243 $help =~ s/^\s*/\t /mg;
244 $help = "\thelp\n$help";
245 } else {
246 undef $help;
247 }
248 print "$help\n";
249 }
250 }
251
252 print <<EOF;
253 endchoice
254
255 menu "Target Devices"
256 depends on TARGET_MULTI_PROFILE
257
258 config TARGET_ALL_PROFILES
259 bool "Enable all profiles by default"
260 default BUILDBOT
261
262 config TARGET_PER_DEVICE_ROOTFS
263 bool "Use a per-device root filesystem that adds profile packages"
264 default BUILDBOT
265 help
266 When disabled, all device packages from all selected devices
267 will be included in all images by default. (Marked as <*>) You will
268 still be able to manually deselect any/all packages.
269 When enabled, each device builds it's own image, including only the
270 profile packages for that device. (Marked as {M}) You will be able
271 to change a package to included in all images by marking as {*}, but
272 will not be able to disable a profile package completely.
273
274 To get the most use of this setting, you must set in a .config stub
275 before calling "make defconfig". Selecting TARGET_MULTI_PROFILE and
276 then manually selecting (via menuconfig for instance) this option
277 will have pre-defaulted all profile packages to included, making this
278 option appear to have had no effect.
279
280 EOF
281 foreach my $target (@target) {
282 my @profiles = sort {
283 my $x = $a->{name};
284 my $y = $b->{name};
285 "\L$x" cmp "\L$y";
286 } @{$target->{profiles}};
287 foreach my $profile (@profiles) {
288 next unless $profile->{id} =~ /^DEVICE_/;
289 print <<EOF;
290 menuconfig TARGET_DEVICE_$target->{conf}_$profile->{id}
291 bool "$profile->{name}"
292 depends on TARGET_$target->{conf}
293 default y if TARGET_ALL_PROFILES
294 EOF
295 my @pkglist = merge_package_lists($target->{packages}, $profile->{packages});
296 foreach my $pkg (@pkglist) {
297 print "\tselect DEFAULT_$pkg if !TARGET_PER_DEVICE_ROOTFS\n";
298 print "\tselect MODULE_DEFAULT_$pkg if TARGET_PER_DEVICE_ROOTFS\n";
299 $defaults{$pkg} = 1;
300 }
301
302 print <<EOF;
303
304
305 config TARGET_DEVICE_PACKAGES_$target->{conf}_$profile->{id}
306 string "$profile->{name} additional packages"
307 default ""
308 depends on TARGET_PER_DEVICE_ROOTFS
309 depends on TARGET_DEVICE_$target->{conf}_$profile->{id}
310
311 EOF
312 }
313 }
314
315 print <<EOF;
316
317 endmenu
318
319 config HAS_SUBTARGETS
320 bool
321
322 config HAS_DEVICES
323 bool
324
325 config TARGET_BOARD
326 string
327
328 EOF
329 foreach my $target (@target) {
330 $target->{subtarget} or print "\t\tdefault \"".$target->{board}."\" if TARGET_".$target->{conf}."\n";
331 }
332 print <<EOF;
333 config TARGET_SUBTARGET
334 string
335 default "generic" if !HAS_SUBTARGETS
336
337 EOF
338
339 foreach my $target (@target) {
340 foreach my $subtarget (@{$target->{subtargets}}) {
341 print "\t\tdefault \"$subtarget\" if TARGET_".$target->{conf}."_$subtarget\n";
342 }
343 }
344 print <<EOF;
345 config TARGET_PROFILE
346 string
347 EOF
348 foreach my $target (@target) {
349 my $profiles = $target->{profiles};
350 foreach my $profile (@$profiles) {
351 print "\tdefault \"$profile->{id}\" if TARGET_$target->{conf}_$profile->{id}\n";
352 }
353 }
354
355 print <<EOF;
356
357 config TARGET_ARCH_PACKAGES
358 string
359
360 EOF
361 foreach my $target (@target) {
362 next if @{$target->{subtargets}} > 0;
363 print "\t\tdefault \"".($target->{arch_packages} || $target->{board})."\" if TARGET_".$target->{conf}."\n";
364 }
365 print <<EOF;
366
367 config DEFAULT_TARGET_OPTIMIZATION
368 string
369 EOF
370 foreach my $target (@target) {
371 next if @{$target->{subtargets}} > 0;
372 print "\tdefault \"".$target->{cflags}."\" if TARGET_".$target->{conf}."\n";
373 }
374 print "\tdefault \"-Os -pipe -funit-at-a-time\"\n";
375 print <<EOF;
376
377 config CPU_TYPE
378 string
379 EOF
380 foreach my $target (@target) {
381 next if @{$target->{subtargets}} > 0;
382 print "\tdefault \"".$target->{cputype}."\" if TARGET_".$target->{conf}."\n";
383 }
384 print "\tdefault \"\"\n";
385
386 my %kver;
387 foreach my $target (@target) {
388 my $v = kver($target->{version});
389 next if $kver{$v};
390 $kver{$v} = 1;
391 print <<EOF;
392
393 config LINUX_$v
394 bool
395
396 EOF
397 }
398 foreach my $def (sort keys %defaults) {
399 print <<EOF;
400 config DEFAULT_$def
401 bool
402
403 config MODULE_DEFAULT_$def
404 tristate
405 depends on TARGET_PER_DEVICE_ROOTFS
406 depends on m
407 default m if DEFAULT_$def
408 select PACKAGE_$def
409
410 EOF
411 }
412 }
413
414 sub gen_profile_mk() {
415 my $file = shift @ARGV;
416 my $target = shift @ARGV;
417 my @targets = parse_target_metadata($file);
418 foreach my $cur (@targets) {
419 next unless $cur->{id} eq $target;
420 print "PROFILE_NAMES = ".join(" ", map { $_->{id} } @{$cur->{profiles}})."\n";
421 foreach my $profile (@{$cur->{profiles}}) {
422 print $profile->{id}.'_NAME:='.$profile->{name}."\n";
423 print $profile->{id}.'_PACKAGES:='.join(' ', @{$profile->{packages}})."\n";
424 }
425 }
426 }
427
428 sub parse_command() {
429 GetOptions("ignore=s", \@ignore);
430 my $cmd = shift @ARGV;
431 for ($cmd) {
432 /^config$/ and return gen_target_config();
433 /^profile_mk$/ and return gen_profile_mk();
434 }
435 die <<EOF
436 Available Commands:
437 $0 config [file] Target metadata in Kconfig format
438 $0 profile_mk [file] [target] Profile metadata in makefile format
439
440 EOF
441 }
442
443 parse_command();