1#!/bin/bash 2 3# Script to build all cross and native compilers supported by musl-libc. 4# This isn't directly used by toybox, but is useful for testing. 5 6trap "exit 1" INT 7 8if [ ! -d litecross ] 9then 10 echo Run this script in musl-cross-make directory to make "ccc" directory. 11 echo 12 echo " "git clone https://github.com/richfelker/musl-cross-make 13 echo " "cd musl-cross-make 14 echo ' ~/toybox/scripts/mcm-buildall.sh' 15 exit 1 16fi 17 18# All toolchains after the first are themselves cross compiled (so they 19# can be statically linked against musl on the host, for binary portability.) 20# static i686 binaries are basically "poor man's x32". 21BOOTSTRAP=i686-linux-musl 22 23[ -z "$OUTPUT" ] && OUTPUT="$PWD/ccc" 24 25if [ "$1" == clean ] 26then 27 rm -rf "$OUTPUT" host-* *.log 28 make clean 29 exit 30fi 31 32make_toolchain() 33{ 34 # Set cross compiler path 35 LP="$PATH" 36 if [ -z "$TYPE" ] 37 then 38 OUTPUT="$PWD/host-$TARGET" 39 EXTRASUB=y 40 else 41 if [ "$TYPE" == static ] 42 then 43 HOST=$BOOTSTRAP 44 [ "$TARGET" = "$HOST" ] && LP="$PWD/host-$HOST/bin:$LP" 45 TYPE=cross 46 EXTRASUB=y 47 LP="$OUTPUT/$HOST-cross/bin:$LP" 48 else 49 HOST="$TARGET" 50 export NATIVE=y 51 LP="$OUTPUT/${RENAME:-$TARGET}-cross/bin:$LP" 52 [ -z "$(PATH="$LP" which $TARGET-cc)" ] && 53 echo "no $TARGET-cc in $LP" && return 54 fi 55 COMMON_CONFIG="CC=\"$HOST-gcc -static --static\" CXX=\"$HOST-g++ -static --static\"" 56 export -n HOST 57 OUTPUT="$OUTPUT/${RENAME:-$TARGET}-$TYPE" 58 fi 59 60 if [ -e "$OUTPUT.sqf" ] || [ -e "$OUTPUT/bin/$TARGET-cc" ] || 61 [ -e "$OUTPUT/bin/cc" ] 62 then 63 return 64 fi 65 66 # Change title bar to say what we're currently building 67 68 echo === building $TARGET-$TYPE 69 echo -en "\033]2;$TARGET-$TYPE\007" 70 71 rm -rf build/"$TARGET" "$OUTPUT" && 72 [ -z "$CPUS" ] && CPUS=$(($(nproc)+1)) 73 set -x && 74 PATH="$LP" make OUTPUT="$OUTPUT" TARGET="$TARGET" \ 75 GCC_CONFIG="--disable-nls --disable-libquadmath --disable-decimal-float --disable-multilib --enable-languages=c,c++ $GCC_CONFIG" \ 76 COMMON_CONFIG="CFLAGS=\"$CFLAGS -g0 -Os\" CXXFLAGS=\"$CXXFLAGS -g0 -Os\" LDFLAGS=\"$LDFLAGS -s\" $COMMON_CONFIG" \ 77 install -j$CPUS || exit 1 78 set +x 79 echo -e '#ifndef __MUSL__\n#define __MUSL__ 1\n#endif' \ 80 >> "$OUTPUT/${EXTRASUB:+$TARGET/}include/features.h" 81 82 if [ ! -z "$RENAME" ] && [ "$TYPE" == cross ] 83 then 84 CONTEXT="output/$RENAME-cross/bin" 85 for i in "$CONTEXT/$TARGET-"* 86 do 87 X="$(echo $i | sed "s@.*/$TARGET-\([^-]*\)@\1@")" 88 ln -sf "$TARGET-$X" "$CONTEXT/$RENAME-$X" 89 done 90 fi 91 92 # Prevent cross compiler reusing dynamically linked host build files for 93 # $BOOTSTRAP arch 94 [ -z "$TYPE" ] && { 95 [ -e musl-git-master ] && mv musl-git-master keep-this-dir 96 make clean 97 [ -e keep-this-dir ] && mv keep-this-dir musl-git-master 98 } 99 100 if [ "$TYPE" == native ] 101 then 102 # gcc looks in "../usr/include" but not "/bin/../include" (relative to the 103 # executable). That means /usr/bin/gcc looks in /usr/usr/include, so that's 104 # not a fix either. So add a NOP symlink as a workaround for The Crazy. 105 ln -s . "$OUTPUT/usr" || exit 1 106 [ ! -z "$(which mksquashfs 2>/dev/null)" ] && 107 mksquashfs "$OUTPUT" "$OUTPUT.sqf" -all-root && 108 [ -z "$CLEANUP" ] && rm -rf "$OUTPUT" 109 fi 110} 111 112# Expand compressed target into binutils/gcc "tuple" and call make_toolchain 113make_tuple() 114{ 115 PART1=${1/:*/} 116 PART3=${1/*:/} 117 PART2=${1:$((${#PART1}+1)):$((${#1}-${#PART3}-${#PART1}-2))} 118 119 # Do we need to rename this toolchain after building it? 120 RENAME=${PART1/*@/} 121 [ "$RENAME" == "$PART1" ] && RENAME= 122 PART1=${PART1/@*/} 123 TARGET=${PART1}-linux-musl${PART2} 124 125 [ -z "$NOCLEAN" ] && rm -rf build 126 127 for TYPE in static native 128 do 129 TYPE=$TYPE TARGET=$TARGET GCC_CONFIG="$PART3" RENAME="$RENAME" \ 130 make_toolchain 2>&1 | tee "$OUTPUT"/log/${RENAME:-$PART1}-${TYPE}.log 131 done 132} 133 134# Packages detect nommu via the absence of fork(). Musl provides a broken fork() 135# on nommu builds that always returns -ENOSYS at runtime. Rip it out. 136# (Currently only for superh/jcore.) 137fix_nommu() 138{ 139 # Rich won't merge this 140 sed -i 's/--enable-fdpic$/& --enable-twoprocess/' litecross/Makefile 141 142 PP=patches/musl-"$(sed -n 's/MUSL_VER[ \t]*=[ \t]*//p' Makefile)" 143 mkdir -p "$PP" && 144 cat > "$PP"/0001-nommu.patch << 'EOF' 145--- a/src/legacy/daemon.c 146+++ b/src/legacy/daemon.c 147@@ -17,3 +17,3 @@ 148 149- switch(fork()) { 150+ switch(vfork()) { 151 case 0: break; 152@@ -25,3 +25,3 @@ 153 154- switch(fork()) { 155+ switch(vfork()) { 156 case 0: break; 157--- a/src/misc/forkpty.c 158+++ b/src/misc/forkpty.c 159@@ -8,2 +8,3 @@ 160 161+#ifndef __SH_FDPIC__ 162 int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws) 163@@ -57,1 +58,2 @@ 164 } 165+#endif 166--- a/src/misc/wordexp.c 167+++ b/src/misc/wordexp.c 168@@ -25,2 +25,3 @@ 169 170+#ifndef __SH_FDPIC__ 171 static int do_wordexp(const char *s, wordexp_t *we, int flags) 172@@ -177,2 +178,3 @@ 173 } 174+#endif 175 176--- a/src/process/fork.c 177+++ b/src/process/fork.c 178@@ -7,2 +7,3 @@ 179 180+#ifndef __SH_FDPIC__ 181 static void dummy(int x) 182@@ -37,1 +38,2 @@ 183 } 184+#endif 185--- a/Makefile 186+++ b/Makefile 187@@ -100,3 +100,3 @@ 188 cp $< $@ 189- sed -n -e s/__NR_/SYS_/p < $< >> $@ 190+ sed -e s/__NR_/SYS_/ < $< >> $@ 191 192--- a/arch/sh/bits/syscall.h.in 193+++ b/arch/sh/bits/syscall.h.in 194@@ -2,3 +2,5 @@ 195 #define __NR_exit 1 196+#ifndef __SH_FDPIC__ 197 #define __NR_fork 2 198+#endif 199 #define __NR_read 3 200EOF 201 202 # I won't sign the FSF's copyright assignment 203 tee $(for i in patches/gcc-*; do echo $i/099-vfork.patch; done) > /dev/null << 'EOF' 204--- gcc-8.3.0/fixincludes/procopen.c 2005-08-14 19:50:43.000000000 -0500 205+++ gcc-bak/fixincludes/procopen.c 2020-02-06 23:27:15.408071708 -0600 206@@ -116,3 +116,3 @@ 207 */ 208- ch_id = fork (); 209+ ch_id = vfork (); 210 switch (ch_id) 211EOF 212} 213 214fix_nommu || exit 1 215mkdir -p "$OUTPUT"/log 216 217# Make bootstrap compiler (no $TYPE, dynamically linked against host libc) 218# We build the rest of the cross compilers with this so they're linked against 219# musl-libc, because glibc doesn't fully support static linking and dynamic 220# binaries aren't really portable between distributions 221TARGET=$BOOTSTRAP make_toolchain 2>&1 | tee -a "$OUTPUT/log/$BOOTSTRAP"-host.log 222 223if [ $# -gt 0 ] 224then 225 for i in "$@" 226 do 227 make_tuple "$i" 228 done 229else 230 # Here's the list of cross compilers supported by this build script. 231 232 # First target builds a proper version of the $BOOTSTRAP compiler above, 233 # which is used to build the rest (in alphabetical order) 234 for i in i686:: \ 235 aarch64:eabi: armv4l:eabihf:"--with-arch=armv5t --with-float=soft" \ 236 "armv5l:eabihf:--with-arch=armv5t --with-fpu=vfpv2 --with-float=hard" \ 237 "armv7l:eabihf:--with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard" \ 238 "armv7m:eabi:--with-arch=armv7-m --with-mode=thumb --disable-libatomic --enable-default-pie" \ 239 armv7r:eabihf:"--with-arch=armv7-r --enable-default-pie" \ 240 i486:: m68k:: microblaze:: mips:: mips64:: mipsel:: powerpc:: \ 241 powerpc64:: powerpc64le:: s390x:: sh2eb:fdpic:--with-cpu=mj2 \ 242 sh4::--enable-incomplete-targets x86_64::--with-mtune=nocona \ 243 x86_64@x32:x32: 244 do 245 make_tuple "$i" 246 done 247fi 248