musllvm

musl and LLVM cross-toolchain build system
git clone https://git.daat.foo/repos/musllvm.git
Log | Files | Refs | README | LICENSE

verify.sh (3329B)


      1 #!/bin/sh
      2 set -eu
      3 
      4 . "$(dirname "$0")/config.sh"
      5 unset MUSLLVM_SYSROOT
      6 cc="$PREFIX/bin/$TARGET-cc"
      7 cxx="$PREFIX/bin/$TARGET-c++"
      8 readelf="$PREFIX/bin/$TARGET-readelf"
      9 work="$BUILD_DIR/verify"
     10 loader="$SYSROOT/lib/ld-musl-$ARCH.so.1"
     11 for program in "$cc" "$cxx" "$readelf"; do
     12 	[ -x "$program" ] || die "toolchain is incomplete: $program"
     13 done
     14 
     15 run()
     16 {
     17 	if [ -n "$RUNNER" ]; then "$RUNNER" "$@"; else "$@"; fi
     18 }
     19 
     20 mkdir -p "$work"
     21 "$cc" -std=c99 -Werror -c "$PROOT/tests/hello.c" -o "$work/hello-c.o"
     22 "$cxx" -std=c++20 -Werror -c "$PROOT/tests/hello.cpp" -o "$work/hello-cxx.o"
     23 "$cc" -std=c99 -O2 -pthread "$PROOT/tests/hello.c" -o "$work/hello-c"
     24 "$cc" -std=c99 -O2 -pthread -static "$PROOT/tests/hello.c" -o "$work/hello-c-static"
     25 "$cxx" -std=c++20 -O2 -pthread "$PROOT/tests/hello.cpp" -o "$work/hello-cxx"
     26 "$cxx" -std=c++20 -O2 -pthread -static "$PROOT/tests/hello.cpp" -o "$work/hello-cxx-static"
     27 "$cxx" -std=c++20 -O2 -pthread -static-pie "$PROOT/tests/hello.cpp" -o "$work/hello-cxx-static-pie"
     28 
     29 cmake -S "$PROOT/tests/cmake" -B "$work/cmake" -G Ninja \
     30 	-DCMAKE_TOOLCHAIN_FILE="$PREFIX/share/musllvm/toolchain.cmake"
     31 cmake --build "$work/cmake" --parallel "$JOBS"
     32 
     33 static='hello-c-static hello-cxx-static hello-cxx-static-pie cmake/hello-cxx-static'
     34 dynamic='hello-c hello-cxx cmake/hello-c cmake/hello-cxx'
     35 for program in $static $dynamic; do
     36 	"$readelf" -h "$work/$program" > "$work/$program.header"
     37 	grep -F "$ELF_MACHINE" "$work/$program.header" >/dev/null || die "wrong ELF machine: $program"
     38 	"$readelf" -l "$work/$program" > "$work/$program.segments"
     39 	"$readelf" -d "$work/$program" > "$work/$program.dynamic"
     40 	if grep -E 'libc\.so\.6|libstdc\+\+|libgcc_s|ld-linux' "$work/$program.dynamic" "$work/$program.segments"; then
     41 		die "host runtime dependency in $program"
     42 	fi
     43 	case " $static " in
     44 	*" $program "*)
     45 		if grep -E 'INTERP|NEEDED' "$work/$program.segments" "$work/$program.dynamic"; then
     46 			die "static executable has dynamic dependencies: $program"
     47 		fi ;;
     48 	*)
     49 		grep -F "/lib/ld-musl-$ARCH.so.1" "$work/$program.segments" >/dev/null ||
     50 			die "wrong dynamic loader in $program"
     51 		grep -F GNU_RELRO "$work/$program.segments" >/dev/null &&
     52 			grep -E 'BIND_NOW|FLAGS.* NOW' "$work/$program.dynamic" >/dev/null ||
     53 			die "hardening defaults missing from $program" ;;
     54 	esac
     55 done
     56 grep -E 'Type: +DYN' "$work/hello-cxx-static-pie.header" >/dev/null ||
     57 	die "static-pie executable is not position independent"
     58 
     59 for language in c c++; do
     60 	compiler=$cc
     61 	[ "$language" = c ] || compiler=$cxx
     62 	CPATH=/usr/include CPLUS_INCLUDE_PATH=/usr/include LIBRARY_PATH=/usr/lib \
     63 		"$compiler" -E -v -x "$language" /dev/null > /dev/null 2> "$work/$language.includes"
     64 	if grep -E '^ /usr/(local/)?include([ /]|$)|^ /usr/.*/c\+\+' "$work/$language.includes"; then
     65 		die "host headers found in $language search path"
     66 	fi
     67 done
     68 
     69 host_arch=$(uname -m)
     70 if [ "$host_arch" = "$ARCH" ] || [ -n "$RUNNER" ]; then
     71 	for program in $static; do
     72 		run "$work/$program"
     73 	done
     74 	for program in $dynamic; do
     75 		run "$loader" --library-path "$SYSROOT/usr/lib:$SYSROOT/lib" "$work/$program"
     76 	done
     77 else
     78 	printf 'Execution skipped for %s on %s; set RUNNER=qemu-%s to run the programs.\n' "$ARCH" "$host_arch" "$ARCH"
     79 fi
     80 printf 'Verified %s: static, static-pie and dynamic C and C++, -Werror compiles, target ELF, isolated headers, and CMake\n' "$TARGET"