diff options
Diffstat (limited to 'scripts/otp_build_check')
-rwxr-xr-x | scripts/otp_build_check | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/scripts/otp_build_check b/scripts/otp_build_check new file mode 100755 index 0000000000..ee6e656cdf --- /dev/null +++ b/scripts/otp_build_check @@ -0,0 +1,344 @@ +#!/bin/sh +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2023. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# %CopyrightEnd% +# + +# +# Performs a lot of (but not always all) build checking that you want to do... +# + +docs=yes +dialyzer=yes +tests=all +opt_only=no +format_check=yes + +have_printf=no + +print_error() { + if [ $have_printf = yes ]; then + printf "\033[31mERROR: %s\033[0m\n" "$1" 1>&2 + else + echo "ERROR: $1" 1>&2 + fi +} + +progress() { + if [ $have_printf = yes ]; then + printf "\n\033[33m*** %s ***\033[0m\n\n" "$1" 1>&2 + else + echo "\n*** $1 ***\n" 1>&2 + fi +} + +print_usage() { + cat <<EOF +Usage: + otp_build check [--help|-h] [--only-opt|-o] [--no-docs|-d] \\ + [--no-dialyzer|-y] [--no-tests|-n] [--no-format-check|-f] \\ + [--tests|-t <App0> ... <AppN>] + + +By default all currently implemented checks will be performed. If any of the +currently used tools are missing, checking will fail. If libraries or tools +needed to support certain conditional features are missing, those features +will not be checked. + +If any of these checks do not pass, the code is *not* ready for testing in OTP +daily builds. Note that this script does not check all requirements for testing +in OTP daily builds. These checks are the bare minimum for even considering +testing in OTP daily builds. Currently the following will be performed by +default: + + * Build all applications in optimized mode. If configure already has been run, + it wont be run again. + * Debug compile C-code in all applications. + * Format checking of JIT code. + * Run dialyzer on all applications. + * Build all documentation. + * Run xmllint on all documentation. + * Run html link check on all documentation. + * Build all test suites. + +Certain build checking can be disabled using the following options: +* [--only-opt|-o] - Only build optimized system. No debug, etc. +* [--no-format-check|-f] - No JIT format checking. +* [--no-docs|-d] - No documentation checking. +* [--no-dialyzer|-y] - No dialyzer checking. +* [--no-tests|-n] - No build checking of test suites. +* [--tests|-t <App0> ... <AppN>] - Only build checking of test suites for + listed applications. + +Only disable build checking for parts of the system that you are certain your +changes wont effect. Note that even though you've made no changes in +documentation source files, documentation build is effected by type changes +in code. + +Environment variables used: +* CONFIG_FLAGS - Arguments to pass to configure if it is executed. + +Build results will be placed under the \$ERL_TOP/release/<TARGET> directory + +EOF +} + +usage () { + print_error "$1" + print_usage >&2 + exit 1 +} + +fail () { + print_error "$1" + exit 1 +} + +type printf >/dev/null 2>&1 +if [ $? -eq 0 ]; then + have_printf=yes +fi + +[ "$ERL_TOP" != "" ] || fail "ERL_TOP needs to be set" + +cd "$ERL_TOP" 2>&1 >/dev/null || { + fail "Failed to change directory into $ERL_TOP" +} + +[ -f "$ERL_TOP/OTP_VERSION" ] || fail "ERL_TOP not valid" + +while [ $# -gt 0 ]; do + case $1 in + --help|-h) + print_usage + exit 0;; + --only-opt|-o) + opt_only=yes;; + --no-docs|-d) + docs=no;; + --no-dialyzer|-y) + dialyzer=no;; + --no-format-check|-f) + format_check=no;; + --no-tests|-n) + tests=none;; + --tests|-t) + shift + while [ $# -gt 0 ]; do + case $1 in + -*) + break;; + test_server|emulator|system|epmd) + ;; + *) + [ -d "$ERL_TOP/lib/$1/test" ] || { + fail "Invalid application: $1" + } + ;; + esac + tapps="$1 $tapps" + shift + done + [ "$tapps" != "" ] || usage "No test apps given" + tests="$tapps" + continue;; + *) + usage "Invalid option: $1" + esac + shift +done + +[ -f "$ERL_TOP/make/config.status" ] || { + ./configure $CONFIG_FLAGS || fail "configure failed" +} + +type gmake >/dev/null 2>&1 +if [ $? -eq 0 ]; then + export MAKE="gmake" +else + type make >/dev/null 2>&1 + if [ $? -eq 0 ]; then + export MAKE="make" + fi +fi + +target=`$MAKE target_configured` || fail "Failed to determine target directory" + +unset TESTROOT +unset RELEASE_ROOT +unset ERL_LIBS +unset OTP_SMALL_BUILD +unset OTP_TINY_BUILD +unset TARGET + +progress "Building OTP in $ERL_TOP" +$MAKE || fail "OTP build failed" +progress "Booting optimized runtime" +$ERL_TOP/bin/cerl -eval "erlang:halt()" || { + fail "Failed to boot runtime" +} + +[ $opt_only = yes ] || { + progress "Building debug OTP in $ERL_TOP" + $MAKE TYPE=debug || fail "OTP debug build failed" + progress "Booting debug runtime" + $ERL_TOP/bin/cerl -debug -eval "erlang:halt()" || { + fail "Failed to boot debug runtime" + } +} + +[ $format_check = no ] || { + clang-format --help 2>&1 >/dev/null || { + fail "clang-format not installed. Use --no-format-check option to skip." + } + + progress "Checking C & C++ code formatting" + $MAKE format-check || { + fail "Failed to format C & C++ code" + } +} + +progress "Releasing OTP" +$MAKE release || fail "Releasing OTP failed" + +cd "$ERL_TOP/release/$target" 2>&1 >/dev/null || { + fail "Failed to change directory into release directory: $ERL_TOP/release/$target" +} + +progress "Installing OTP" +./Install -minimal `pwd` || fail "Failed to install release" + +progress "Booting optimized installed runtime" +./bin/erl -eval "erlang:halt()" || { + fail "Failed to boot installed runtime" +} + +cd "$ERL_TOP" 2>&1 >/dev/null || { + fail "Failed to change directory into $ERL_TOP" +} + +export PATH="$ERL_TOP/release/$target/bin:$PATH" + +[ $docs = no ] || { + progress "Building OTP documentation" + $MAKE docs || fail "Building documentation failed" + progress "Releasing OTP documentation" + $MAKE release_docs || fail "Releasing documentation failed" + progress "Running xmllint on OTP documentation" + $MAKE xmllint || fail "xmllint of documentation failed" + progress "Running HTML check on OTP documentation" + ./scripts/otp_html_check "$ERL_TOP/release/$target/" doc/index.html || { + fail "HTML check of documentation failed" + } +} + +[ $dialyzer = no ] || { + progress "Running dialyzer on OTP" + $MAKE dialyzer || fail "Dialyzing OTP failed" +} + +[ "$tests" = none ] || { + test_dir="$ERL_TOP/release/$target/test" + [ -d "$test_dir" ] || mkdir "$test_dir" 2>&1 >/dev/null || { + fail "Failed to create $test_dir directory" + } + if [ "$tests" = all ]; then + progress "Releasing all OTP tests" + ./otp_build tests "$test_dir" || fail "Release of tests failed" + else + for tapp in $tests; do + case $tapp in + test_server) + tapp_dir="$ERL_TOP/lib/test_server" + if [ ! -d "$tapp_dir" ]; then + tapp_dir="$ERL_TOP/lib/common_test/test_server" + fi + ;; + emulator) tapp_dir="$ERL_TOP/erts/emulator/test";; + system) tapp_dir="$ERL_TOP/erts/test";; + epmd) tapp_dir="$ERL_TOP/erts/epmd/test";; + *) tapp_dir="$ERL_TOP/lib/$tapp/test";; + esac + cd "$tapp_dir" 2>&1 >/dev/null || { + fail "Failed to change directory into $tapp_dir" + } + progress "Releasing $tapp tests" + $MAKE "TESTROOT=$test_dir" release_tests || { + fail "Release of $tapp tests failed" + } + done + + fi + + cd "$test_dir" 2>&1 >/dev/null || { + fail "Failed to change directory into $test_dir" + } + + for dir in *; do + + [ -d "$test_dir/$dir" ] || continue + + progress "Building $dir tests" + + cd "$test_dir/$dir" 2>&1 >/dev/null || { + fail "Failed to change directory into $test_dir/$dir" + } + + for mfile in *_data/Makefile.first; do + + [ "$mfile" != '*_data/Makefile.first' ] || continue + + ddir=`dirname $mfile` || fail "dirname on $test_dir/$dir/$mfile failed" + + cd "$test_dir/$dir/$ddir" 2>&1 >/dev/null || { + fail "Failed to change directory into $test_dir/$dir/$ddir" + } + + $MAKE -f Makefile.first || { + fail "Make of $test_dir/$dir/$ddir/Makefile.first failed" + } + + done + + cd "$test_dir/$dir" 2>&1 >/dev/null || { + fail "Failed to change directory into $test_dir/$dir" + } + + if [ -f Emakefile ]; then + erl -noshell -eval 'case make:all() of error -> erlang:halt(1); _ -> init:stop() end.' || { + fail "Build of $dir failed" + } + else + erlc -I `erl -noshell -eval 'io:format("~ts",[code:lib_dir(common_test)]),init:stop()'`/include -I . *.erl || { + fail "Build of $dir failed" + } + fi + + done + + cd "$ERL_TOP" 2>&1 >/dev/null || { + fail "Failed to change directory into $ERL_TOP" + } +} + +if [ $have_printf = yes ]; then + printf "\n\033[32m*** Success! ***\033[0m\n\n" +else + echo "\n*** Success! ***\n" +fi +exit 0 |