comparison scripts/make.sh @ 1428:e66fb422b78a draft

Parallelize the build. (set CPUS=1 to force single processor build, or another number to override processor count autodetect.)
author Rob Landley <rob@landley.net>
date Sat, 09 Aug 2014 14:33:34 -0500
parents 2538fa09b1b1
children f46ccbcf3f13
comparison
equal deleted inserted replaced
1427:0d58119f0bcd 1428:e66fb422b78a
5 export LANG=c 5 export LANG=c
6 source ./configure 6 source ./configure
7 7
8 [ -z "$KCONFIG_CONFIG" ] && KCONFIG_CONFIG=".config" 8 [ -z "$KCONFIG_CONFIG" ] && KCONFIG_CONFIG=".config"
9 9
10 if [ -z "$KCONFIG_CONFIG" ] 10 if [ -z "$CPUS" ]
11 then 11 then
12 echo "No $KCONFIG_CONFIG (see "make help" for configuration options)." 12 CPUS=$(echo /sys/devices/system/cpu/cpu[0-9]* | wc -w)
13 exit 1 13 CPUS=$(($CPUS+1))
14 fi 14 fi
15 15
16 # Respond to V= by echoing command lines as well as running them 16 # Respond to V= by echoing command lines as well as running them
17 do_loudly() 17 do_loudly()
18 { 18 {
138 echo "generated/help.h" 138 echo "generated/help.h"
139 do_loudly $HOSTCC scripts/config2help.c -I . lib/xwrap.c lib/llist.c lib/lib.c \ 139 do_loudly $HOSTCC scripts/config2help.c -I . lib/xwrap.c lib/llist.c lib/lib.c \
140 -o generated/config2help && \ 140 -o generated/config2help && \
141 generated/config2help Config.in $KCONFIG_CONFIG > generated/help.h || exit 1 141 generated/config2help Config.in $KCONFIG_CONFIG > generated/help.h || exit 1
142 142
143 # Extract a list of toys/*/*.c files to compile from the data in $KCONFIG_CONFIG
144
145 # 1) Get a list of C files in toys/* and glue them together into a regex we can
146 # feed to grep that will match any one of them (whole word, not substring).
147 TOYFILES="^$(ls toys/*/*.c | sed -n 's@^.*/\(.*\)\.c$@\1@;s/-/_/g;H;${g;s/\n//;s/\n/$|^/gp}')\$"
148
149 # 2) Grab the XXX part of all CONFIG_XXX entries, removing everything after the
150 # second underline
151 # 3) Sort the list, keeping only one of each entry.
152 # 4) Convert to lower case.
153 # 5) Remove any config symbol not recognized as a filename from step 1.
154 # 6) Add "toys/*/" prefix and ".c" suffix.
155
156 TOYFILES=$(sed -nre 's/^CONFIG_(.*)=y/\1/p' < "$KCONFIG_CONFIG" \
157 | sort -u | tr A-Z a-z | grep -E "$TOYFILES" | sed 's@\(.*\)@toys/\*/\1.c@')
158
159 echo "Library probe..." 143 echo "Library probe..."
160 144
161 # We trust --as-needed to remove each library if we don't use any symbols 145 # We trust --as-needed to remove each library if we don't use any symbols
162 # out of it, this loop is because the compiler has no way to ignore a library 146 # out of it, this loop is because the compiler has no way to ignore a library
163 # that doesn't exist, so we have to detect and skip nonexistent libraries 147 # that doesn't exist, so we have to detect and skip nonexistent libraries
164 # for it. 148 # for it.
165 149
166 OPTLIBS="$(for i in util crypt m resolv; do echo "int main(int argc, char *argv[]) {return 0;}" | ${CROSS_COMPILE}${CC} $CFLAGS -xc - -o /dev/null -Wl,--as-needed -l$i > /dev/null 2>/dev/null && echo -l$i; done)" 150 > generated/optlibs.dat
167 151 for i in util crypt m resolv
168 echo "Compile toybox..." 152 do
153 echo "int main(int argc, char *argv[]) {return 0;}" | \
154 ${CROSS_COMPILE}${CC} $CFLAGS -xc - -o /dev/null -Wl,--as-needed -l$i > /dev/null 2>/dev/null &&
155 echo -l$i >> generated/optlibs.dat
156 done
157
158 echo -n "Compile toybox"
159 [ ! -z "$V" ] && echo
160
161 # Extract a list of toys/*/*.c files to compile from the data in $KCONFIG_CONFIG
162
163 # Get a list of C files in toys/* and wash it through sed to chop out the
164 # filename, convert - to _, and glue the result together into a new regex
165 # we we can feed to grep to match any one of them (whole word, not substring).
166
167 TOYFILES="^$(ls toys/*/*.c | sed -n 's@^.*/\(.*\)\.c$@\1@;s/-/_/g;H;${g;s/\n//;s/\n/$|^/gp}')\$"
168
169 # 1) Grab the XXX part of all CONFIG_XXX entries from KCONFIG
170 # 2) Sort the list, keeping only one of each entry.
171 # 3) Convert to lower case.
172 # 4) Remove any config symbol not recognized as a filename from step 1.
173 # 5) Add "toys/*/" prefix and ".c" suffix.
174
175 TOYFILES=$(sed -nre 's/^CONFIG_(.*)=y/\1/p' < "$KCONFIG_CONFIG" \
176 | sort -u | tr A-Z a-z | grep -E "$TOYFILES" | sed 's@\(.*\)@toys/\*/\1.c@')
169 177
170 do_loudly() 178 do_loudly()
171 { 179 {
172 [ ! -z "$V" ] && echo "$@" 180 [ ! -z "$V" ] && echo "$@" || echo -n .
173 "$@" 181 "$@"
174 } 182 }
175 183
176 do_loudly ${CROSS_COMPILE}${CC} $CFLAGS -I . -o toybox_unstripped $OPTIMIZE \ 184 BUILD="${CROSS_COMPILE}${CC} $CFLAGS -I . $OPTIMIZE"
177 main.c lib/*.c $TOYFILES -Wl,--as-needed $OPTLIBS || exit 1 185 FILES="$(ls lib/*.c) main.c $TOYFILES"
186 LINK="-o toybox_unstripped -Wl,--as-needed $(cat generated/optlibs.dat)"
187
188 # This is a parallel version of: do_loudly $BUILD $FILES $LINK || exit 1
189
190 rm -f generated/*.o
191 for i in $FILES
192 do
193 # build each generated/*.o file in parallel
194
195 X=${i/lib\//lib_}
196 X=${X##*/}
197 do_loudly $BUILD -c $i -o generated/${X%%.c}.o &
198
199 # ratelimit to $CPUS many parallel jobs, detecting errors
200
201 while true
202 do
203 [ $(jobs -rp | wc -w) -lt "$CPUS" ] && break;
204 wait $(jobs -p | head -n 1) || exit 1
205 done
206 done
207
208 # wait for all background jobs, detecting errors
209
210 for i in $(jobs -p)
211 do
212 wait $i || exit 1
213 done
214
215 do_loudly $BUILD generated/*.o $LINK || exit 1
178 do_loudly ${CROSS_COMPILE}${STRIP} toybox_unstripped -o toybox || exit 1 216 do_loudly ${CROSS_COMPILE}${STRIP} toybox_unstripped -o toybox || exit 1
179 # gcc 4.4's strip command is buggy, and doesn't set the executable bit on 217 # gcc 4.4's strip command is buggy, and doesn't set the executable bit on
180 # its output the way SUSv4 suggests it do so. 218 # its output the way SUSv4 suggests it do so.
181 do_loudly chmod +x toybox || exit 1 219 do_loudly chmod +x toybox || exit 1
220 echo