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