summaryrefslogtreecommitdiff
path: root/scripts/otp_build_check
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/otp_build_check')
-rwxr-xr-xscripts/otp_build_check344
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