target-metadata.pl 8.3 KB

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