genconfig.sh 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #!/bin/bash
  2. # This has to be a separate file from scripts/make.sh so it can be called
  3. # before menuconfig. (It's called again from scripts/make.sh just to be sure.)
  4. source scripts/portability.sh
  5. mkdir -p "$GENDIR"
  6. probecc()
  7. {
  8. ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc -o /dev/null - "$@"
  9. }
  10. # Probe for a single config symbol with a "compiles or not" test.
  11. # Symbol name is first argument, flags second, feed C file to stdin
  12. probesymbol()
  13. {
  14. probecc "${@:2}" 2>/dev/null && DEFAULT=y || DEFAULT=n
  15. rm a.out 2>/dev/null
  16. echo -e "config $1\n\tbool" || exit 1
  17. echo -e "\tdefault $DEFAULT\n" || exit 1
  18. }
  19. probeconfig()
  20. {
  21. # Probe for container support on target
  22. probesymbol TOYBOX_CONTAINER << EOF
  23. #include <stdio.h>
  24. #include <sys/syscall.h>
  25. #include <linux/sched.h>
  26. int x=CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET;
  27. int main(int argc, char *argv[]){printf("%d", x+SYS_unshare+ SYS_setns);}
  28. EOF
  29. probesymbol TOYBOX_FIFREEZE -c << EOF
  30. #include <linux/fs.h>
  31. #ifndef FIFREEZE
  32. #error nope
  33. #endif
  34. EOF
  35. # Work around some uClibc limitations
  36. probesymbol TOYBOX_ICONV -c << EOF
  37. #include "iconv.h"
  38. EOF
  39. # Android and some other platforms miss utmpx
  40. probesymbol TOYBOX_UTMPX -c << EOF
  41. #include <utmpx.h>
  42. #ifndef BOOT_TIME
  43. #error nope
  44. #endif
  45. int main(int argc, char *argv[]) {
  46. struct utmpx *a;
  47. if (0 != (a = getutxent())) return 0;
  48. return 1;
  49. }
  50. EOF
  51. # Android is missing shadow.h
  52. probesymbol TOYBOX_SHADOW -c << EOF
  53. #include <shadow.h>
  54. int main(int argc, char *argv[]) {
  55. struct spwd *a = getspnam("root"); return 0;
  56. }
  57. EOF
  58. # Some commands are android-specific
  59. probesymbol TOYBOX_ON_ANDROID -c << EOF
  60. #ifndef __ANDROID__
  61. #error nope
  62. #endif
  63. EOF
  64. probesymbol TOYBOX_ANDROID_SCHEDPOLICY << EOF
  65. #include <processgroup/sched_policy.h>
  66. int main(int argc,char *argv[]) { get_sched_policy_name(0); }
  67. EOF
  68. # nommu support
  69. probesymbol TOYBOX_FORK << EOF
  70. #include <unistd.h>
  71. int main(int argc, char *argv[]) { return fork(); }
  72. EOF
  73. echo -e '\tdepends on !TOYBOX_FORCE_NOMMU'
  74. probesymbol TOYBOX_PRLIMIT << EOF
  75. #include <sys/types.h>
  76. #include <sys/time.h>
  77. #include <sys/resource.h>
  78. int prlimit(pid_t pid, int resource, const struct rlimit *new_limit,
  79. struct rlimit *old_limit);
  80. int main(int argc, char *argv[]) { prlimit(0, 0, 0, 0); }
  81. EOF
  82. probesymbol TOYBOX_GETRANDOM << EOF
  83. #include <sys/random.h>
  84. int main(void) { char buf[100]; getrandom(buf, 100, 0); }
  85. EOF
  86. # glibc requires #define GNU to get the wrapper for this Linux system call,
  87. # so just use syscall().
  88. probesymbol TOYBOX_COPYFILERANGE << EOF
  89. #include <sys/syscall.h>
  90. #include <unistd.h>
  91. int main(void) { syscall(__NR_copy_file_range, 0, 0, 1, 0, 123, 0); }
  92. EOF
  93. probesymbol TOYBOX_HASTIMERS << EOF
  94. #include <signal.h>
  95. #include <time.h>
  96. int main(void) {void *x=0;timer_create(CLOCK_MONOTONIC,x,x);}
  97. EOF
  98. }
  99. genconfig()
  100. {
  101. # Reverse sort puts posix first, examples last.
  102. for j in $(ls toys/*/README | sort -s -r)
  103. do
  104. DIR="$(dirname "$j")"
  105. [ $(ls "$DIR" | wc -l) -lt 2 ] && continue
  106. echo "menu \"$(head -n 1 $j)\""
  107. echo
  108. # extract config stanzas from each source file, in alphabetical order
  109. for i in $(ls -1 $DIR/*.c)
  110. do
  111. # Grab the config block for Config.in
  112. echo "# $i"
  113. $SED -n '/^\*\//q;/^config [A-Z]/,$p' $i || return 1
  114. echo
  115. done
  116. echo endmenu
  117. done
  118. }
  119. probeconfig > "$GENDIR"/Config.probed || rm "$GENDIR"/Config.probed
  120. genconfig > "$GENDIR"/Config.in || rm "$GENDIR"/Config.in
  121. # Find names of commands that can be built standalone in these C files
  122. toys()
  123. {
  124. grep 'TOY(.*)' "$@" | grep -v TOYFLAG_NOFORK | grep -v "0))" | \
  125. $SED -En 's/([^:]*):.*(OLD|NEW)TOY\( *([a-zA-Z][^,]*) *,.*/\1:\3/p'
  126. }
  127. WORKING=
  128. PENDING=
  129. toys toys/*/*.c | (
  130. while IFS=":" read FILE NAME
  131. do
  132. [ "$NAME" == help ] && continue
  133. [ "$NAME" == install ] && continue
  134. [ "$NAME" == sh ] && FILE="toys/*/*.c"
  135. echo -e "$NAME: $FILE *.[ch] lib/*.[ch]\n\tscripts/single.sh $NAME\n"
  136. echo -e "test_$NAME:\n\tscripts/test.sh $NAME\n"
  137. [ "${FILE/pending//}" != "$FILE" ] &&
  138. PENDING="$PENDING $NAME" ||
  139. WORKING="$WORKING $NAME"
  140. done &&
  141. echo -e "clean::\n\t@rm -f $WORKING $PENDING" &&
  142. echo -e "list:\n\t@echo $(echo $WORKING | tr ' ' '\n' | sort | xargs)" &&
  143. echo -e "list_pending:\n\t@echo $(echo $PENDING | tr ' ' '\n' | sort | xargs)" &&
  144. echo -e ".PHONY: $WORKING $PENDING" | $SED 's/ \([^ ]\)/ test_\1/g'
  145. ) > .singlemake