target-metadata.pl 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. /small_flash/ and $ret .= "\tselect SMALL_FLASH\n";
  38. /nand/ and $ret .= "\tselect NAND_SUPPORT\n";
  39. }
  40. return $ret;
  41. }
  42. sub target_name($) {
  43. my $target = shift;
  44. my $parent = $target->{parent};
  45. if ($parent) {
  46. return $target->{parent}->{name}." - ".$target->{name};
  47. } else {
  48. return $target->{name};
  49. }
  50. }
  51. sub kver($) {
  52. my $v = shift;
  53. $v =~ tr/\./_/;
  54. if (substr($v,0,2) eq "2_") {
  55. $v =~ /(\d+_\d+_\d+)(_\d+)?/ and $v = $1;
  56. } else {
  57. $v =~ /(\d+_\d+)(_\d+)?/ and $v = $1;
  58. }
  59. return $v;
  60. }
  61. sub print_target($) {
  62. my $target = shift;
  63. my $features = target_config_features(@{$target->{features}});
  64. my $help = $target->{desc};
  65. my $confstr;
  66. chomp $features;
  67. $features .= "\n";
  68. if ($help =~ /\w+/) {
  69. $help =~ s/^\s*/\t /mg;
  70. $help = "\thelp\n$help";
  71. } else {
  72. undef $help;
  73. }
  74. my $v = kver($target->{version});
  75. if (@{$target->{subtargets}} == 0) {
  76. $confstr = <<EOF;
  77. config TARGET_$target->{conf}
  78. bool "$target->{name}"
  79. select LINUX_$v
  80. EOF
  81. }
  82. else {
  83. $confstr = <<EOF;
  84. config TARGET_$target->{conf}
  85. bool "$target->{name}"
  86. EOF
  87. }
  88. if ($target->{subtarget}) {
  89. $confstr .= "\tdepends on TARGET_$target->{boardconf}\n";
  90. }
  91. if (@{$target->{subtargets}} > 0) {
  92. $confstr .= "\tselect HAS_SUBTARGETS\n";
  93. grep { /broken/ } @{$target->{features}} and $confstr .= "\tdepends on BROKEN\n";
  94. } else {
  95. $confstr .= $features;
  96. if ($target->{arch} =~ /\w/) {
  97. $confstr .= "\tselect $target->{arch}\n";
  98. }
  99. if ($target->{has_devices}) {
  100. $confstr .= "\tselect HAS_DEVICES\n";
  101. }
  102. }
  103. foreach my $dep (@{$target->{depends}}) {
  104. my $mode = "depends on";
  105. my $flags;
  106. my $name;
  107. $dep =~ /^([@\+\-]+)(.+)$/;
  108. $flags = $1;
  109. $name = $2;
  110. next if $name =~ /:/;
  111. $flags =~ /-/ and $mode = "deselect";
  112. $flags =~ /\+/ and $mode = "select";
  113. $flags =~ /@/ and $confstr .= "\t$mode $name\n";
  114. }
  115. $confstr .= "$help\n\n";
  116. print $confstr;
  117. }
  118. sub merge_package_lists($$) {
  119. my $list1 = shift;
  120. my $list2 = shift;
  121. my @l = ();
  122. my %pkgs;
  123. foreach my $pkg (@$list1, @$list2) {
  124. $pkgs{$pkg} = 1;
  125. }
  126. foreach my $pkg (keys %pkgs) {
  127. push @l, $pkg unless ($pkg =~ /^-/ or $pkgs{"-$pkg"});
  128. }
  129. return sort(@l);
  130. }
  131. sub gen_target_config() {
  132. my $file = shift @ARGV;
  133. my @target = parse_target_metadata($file);
  134. my %defaults;
  135. my @target_sort = sort {
  136. target_name($a) cmp target_name($b);
  137. } @target;
  138. print <<EOF;
  139. choice
  140. prompt "Target System"
  141. default TARGET_ar71xx
  142. reset if !DEVEL
  143. EOF
  144. foreach my $target (@target_sort) {
  145. next if $target->{subtarget};
  146. print_target($target);
  147. }
  148. print <<EOF;
  149. endchoice
  150. choice
  151. prompt "Subtarget" if HAS_SUBTARGETS
  152. EOF
  153. foreach my $target (@target) {
  154. next unless $target->{def_subtarget};
  155. print <<EOF;
  156. default TARGET_$target->{conf}_$target->{def_subtarget} if TARGET_$target->{conf}
  157. EOF
  158. }
  159. print <<EOF;
  160. EOF
  161. foreach my $target (@target) {
  162. next unless $target->{subtarget};
  163. print_target($target);
  164. }
  165. print <<EOF;
  166. endchoice
  167. choice
  168. prompt "Target Profile"
  169. EOF
  170. foreach my $target (@target) {
  171. my $profile = $target->{profiles}->[0];
  172. $profile or next;
  173. print <<EOF;
  174. default TARGET_$target->{conf}_$profile->{id} if TARGET_$target->{conf}
  175. EOF
  176. }
  177. print <<EOF;
  178. config TARGET_MULTI_PROFILE
  179. bool "Multiple devices"
  180. depends on HAS_DEVICES
  181. EOF
  182. foreach my $target (@target) {
  183. my $profiles = $target->{profiles};
  184. foreach my $profile (@{$target->{profiles}}) {
  185. print <<EOF;
  186. config TARGET_$target->{conf}_$profile->{id}
  187. bool "$profile->{name}"
  188. depends on TARGET_$target->{conf}
  189. EOF
  190. my @pkglist = merge_package_lists($target->{packages}, $profile->{packages});
  191. foreach my $pkg (@pkglist) {
  192. print "\tselect DEFAULT_$pkg\n";
  193. $defaults{$pkg} = 1;
  194. }
  195. my $help = $profile->{desc};
  196. if ($help =~ /\w+/) {
  197. $help =~ s/^\s*/\t /mg;
  198. $help = "\thelp\n$help";
  199. } else {
  200. undef $help;
  201. }
  202. print "$help\n";
  203. }
  204. }
  205. print <<EOF;
  206. endchoice
  207. menu "Target Devices"
  208. depends on TARGET_MULTI_PROFILE
  209. EOF
  210. foreach my $target (@target) {
  211. my $profiles = $target->{profiles};
  212. foreach my $profile (@{$target->{profiles}}) {
  213. next unless $profile->{id} =~ /^DEVICE_/;
  214. print <<EOF;
  215. config TARGET_DEVICE_$target->{conf}_$profile->{id}
  216. bool "$profile->{name}"
  217. depends on TARGET_$target->{conf}
  218. EOF
  219. my @pkglist = merge_package_lists($target->{packages}, $profile->{packages});
  220. foreach my $pkg (@pkglist) {
  221. print "\tselect DEFAULT_$pkg\n";
  222. $defaults{$pkg} = 1;
  223. }
  224. }
  225. }
  226. print <<EOF;
  227. endmenu
  228. config HAS_SUBTARGETS
  229. bool
  230. config HAS_DEVICES
  231. bool
  232. config TARGET_BOARD
  233. string
  234. EOF
  235. foreach my $target (@target) {
  236. $target->{subtarget} or print "\t\tdefault \"".$target->{board}."\" if TARGET_".$target->{conf}."\n";
  237. }
  238. print <<EOF;
  239. config TARGET_SUBTARGET
  240. string
  241. default "generic" if !HAS_SUBTARGETS
  242. EOF
  243. foreach my $target (@target) {
  244. foreach my $subtarget (@{$target->{subtargets}}) {
  245. print "\t\tdefault \"$subtarget\" if TARGET_".$target->{conf}."_$subtarget\n";
  246. }
  247. }
  248. print <<EOF;
  249. config TARGET_PROFILE
  250. string
  251. EOF
  252. foreach my $target (@target) {
  253. my $profiles = $target->{profiles};
  254. foreach my $profile (@$profiles) {
  255. print "\tdefault \"$profile->{id}\" if TARGET_$target->{conf}_$profile->{id}\n";
  256. }
  257. }
  258. print <<EOF;
  259. config TARGET_ARCH_PACKAGES
  260. string
  261. EOF
  262. foreach my $target (@target) {
  263. next if @{$target->{subtargets}} > 0;
  264. print "\t\tdefault \"".($target->{arch_packages} || $target->{board})."\" if TARGET_".$target->{conf}."\n";
  265. }
  266. print <<EOF;
  267. config DEFAULT_TARGET_OPTIMIZATION
  268. string
  269. EOF
  270. foreach my $target (@target) {
  271. next if @{$target->{subtargets}} > 0;
  272. print "\tdefault \"".$target->{cflags}."\" if TARGET_".$target->{conf}."\n";
  273. }
  274. print "\tdefault \"-Os -pipe -funit-at-a-time\"\n";
  275. print <<EOF;
  276. config CPU_TYPE
  277. string
  278. EOF
  279. foreach my $target (@target) {
  280. next if @{$target->{subtargets}} > 0;
  281. print "\tdefault \"".$target->{cputype}."\" if TARGET_".$target->{conf}."\n";
  282. }
  283. print "\tdefault \"\"\n";
  284. my %kver;
  285. foreach my $target (@target) {
  286. my $v = kver($target->{version});
  287. next if $kver{$v};
  288. $kver{$v} = 1;
  289. print <<EOF;
  290. config LINUX_$v
  291. bool
  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. sub gen_profile_mk() {
  300. my $file = shift @ARGV;
  301. my $target = shift @ARGV;
  302. my @targets = parse_target_metadata($file);
  303. foreach my $cur (@targets) {
  304. next unless $cur->{id} eq $target;
  305. print "PROFILE_NAMES = ".join(" ", map { $_->{id} } @{$cur->{profiles}})."\n";
  306. foreach my $profile (@{$cur->{profiles}}) {
  307. print $profile->{id}.'_NAME:='.$profile->{name}."\n";
  308. print $profile->{id}.'_PACKAGES:='.join(' ', @{$profile->{packages}})."\n";
  309. }
  310. }
  311. }
  312. sub parse_command() {
  313. GetOptions("ignore=s", \@ignore);
  314. my $cmd = shift @ARGV;
  315. for ($cmd) {
  316. /^config$/ and return gen_target_config();
  317. /^profile_mk$/ and return gen_profile_mk();
  318. }
  319. die <<EOF
  320. Available Commands:
  321. $0 config [file] Target metadata in Kconfig format
  322. $0 profile_mk [file] [target] Profile metadata in makefile format
  323. EOF
  324. }
  325. parse_command();