#!/bin/sh # vim: ts=4 sw=4 et ft=sh #---------------------------------------------------------------------------# # Copyright (C) 1995-2008, 2010-2011 The University of Melbourne. # Copyright (C) 2013-2026 The Mercury team. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# usage="\ Usage: $0 [options] Options: -d , --test-dir Run the tests in directory . Multiple such options may be given, in which case the tests in all the named directories will be run. In the absence of any such options, all tests in all directories will be run (unless testing as a whole is disabled). -s , --specified-test Run only the tests whose names are specified as arguments of this option, which may be given more than once. The test names must include the directory name component. -f, --failing-tests Run only the tests which failed on the last run, as recorded in the FAILED_TESTS files in the various test directories. Meaningful only in the absence of -s options. --error-file Run only the tests which failed on the last run, as recorded in the tests/runtests.errs file. Meaningful only in the absence of -s and -f options. --expect-no-failures Exit with a nonzero exit status if any test fails, even if the failure of that test is otherwise expected. -e, --extras Test the programs in the extras directory. -h, --help Display this usage message. -j , --jobs Run using different parallel processes. -k, --keep-objs Keep the stage 2 object files even if stage 2 is successful. -m , --mmake-opts Pass as options to \`mmake'. -M , --make-opts Pass as options to \`make'. -o , --output-file Output results to . --target Specify the target to use in creating stages 2 and 3. -G , --grade Specify the grade to use in creating stages 2 and 3. The tests will also be executed in this grade, unless the --test-grade option says otherwise. Implies -r -g. --gradedir Same as '--grade ', except that it also causes the grade name to be included in the names of the stage 2 and stage 3 directories. This can be useful if you have lots of disk space and want to run bootchecks in several grades at once. Note however that the name of the tests directory doesn't include the grade, so you might also need to use --no-test-suite (see below) for this to work. --test-grade Specify the grade to use in executing the tests. If this is the same as the grade of stages 2 and 3, then we use the stage 2 runtime, library etc for the tests. Otherwise, we use the stage 1 runtime, library etc, and trust that these are compatible with the given grade. Implies -r -g. --mercury-options Set MERCURY_OPTIONS to the given string when doing the bootcheck. -g, --copy-boehm-gc Copy the boehm_gc directory instead of linking it. This is necessary if one wants to bootcheck a grade that is not compatible with the standard one. -r, --copy-runtime Copy the runtime directory instead of linking it. This is necessary if one wants to bootcheck a grade that is not compatible with the standard one. -p-, --no-copy-profilers Link the profiler directories instead of copying them. --no-copy-slice Link the slice directory instead of copying it. -b-, --no-bootcheck Do not run the bootstrap check; execute the test suite and/or the extras only. This option requires a previous bootstrap check to have left a working stage 2 directory. --no-check-namespace Don't build the check_namespace targets in the runtime, trace, browser, ssdb, mdbcomp and library directories. -t-, --no-test-suite By default, bootcheck will also run the test suite. This option prevents that. --skip-stage-2 Take the existing stage 2 directory as given; do not run mmake in it. --skip-stage-3 Skip building the stage 3 directory, and the comparison to the stage 2 directory. -2, --keep-stage-2 Don't rebuild the stage 2 directory from scratch after building stage 1. Instead use the existing stage 2 directory as the starting point for mmake. -3, --keep-stage-3 Don't rebuild the stage 3 directory from scratch after building stage 1. Instead use the existing stage 3 directory as the starting point for mmake. --no-test-params When executing the test suite, do not use the stage 2 Mmake.params file. --test-with-stage-1-compiler Use the stage 1 compiler when executing the test suite. By default, the stage 2 compiler is used. --keep-success-log-files Keep every test case's .log file, renamed as a .kept_log file, even if the test passes. It can be useful to compare these files in a known-good workspace with the corresponding log files in a workspace containing a change that fails some test cases. Note that unneeded .kept_log files must be deleted manually; they do *not* get deleted by any mmake targets. --stop-after-stage-2 Stop after building stage 2, even if it is successful. --use-subdirs Assume intermediate files are built in subdirectories. (Same as the \`--use-subdirs' option to mmake and mmc.) --use-mmc-make Use \`mmc --make' to build the files. (Same as the \`--use-mmc-make' option to mmake.) --compile-times Report information about compilation times in the stage 2 library and compiler directories. --no-write-out-profile-data When doing bootcheck in a deep profiling grade, disable the writing out of profile data files. This makes the bootcheck faster, but avoiding writing out the profiling data also avoids the checks on its integrity. --type-stats TYPE_STATS_FILE_NAME Collect statistics about the builtin operations (unify, index and compare) performed on various types. The argument of this option should give the absolute pathname of the file in which the runtime has been configured to accumulate statistics. The statistics derived from the creation of the stage 3 compiler will be put into TYPE_STATS_FILE_NAME.stage3.$$, while the statistics derived from the execution of the test suite will be put into TYPE_STATS_FILE_NAME.tests.$$. Both filenames will be reported in the output of bootcheck, to allow the statistics files to be matched with the bootcheck that created them. --trace-count Collect counts of the number of times each label is executed in modules compiled with debugging. --coverage-test Collect counts of the number of times each label is executed in modules compiled with debugging, and put the raw data needed by the mtc script into a bunch of files in the coverage directory. -W, --windows Translate paths into the Microsoft Windows format. This is automatically selected when using MSYS2. This option also implies --no-sym-links. --no-sym-links Use this option on systems which do not support symbolic links. --disable-debug-libs Make the trace, browser, ssdb libraries empty. This can be useful when trying to track down the reason why they are being linked into the compiler in the first place. --delete-deep-data Delete any Deep.data and Deep.procrep files created by the bootcheck, in the interest of conserving disk space. --deep-all-write In deep profiling grades, write out the profiling tree on every invocation. (The default is to write it out only for every 25th invocation, on average.) --deep-debug Turn on the flag that enables debugging output from the deep profiling runtime. --progress Create a timestamp file when finishing the execution of each test case, to allow the user to monitor the bootcheck's progress. The timestamp files will have names of the form .date.. " unset WORKSPACE testdirs="" specified_tests_only="" failing_tests_only=false error_file_only=false expect_listed_failures=true extras=false jfactor="" keep_objs=false mmake_opts="-k" outfile="" runtests=true do_bootcheck=true check_namespace=true grade= use_gradedir=false target=c test_grade= test_params=true test_with_stage_1_compiler=false copy_runtime=false copy_boehm_gc=false copy_slice=true copy_profilers=true build_stage_2=true build_stage_3=true keep_stage_2=false keep_stage_3=false stop_after_stage_2=false windows=false use_cp=false if test -d compiler/Mercury then use_subdirs=${MMAKE_USE_SUBDIRS=yes} else use_subdirs=${MMAKE_USE_SUBDIRS=no} fi use_mmc_make=no compile_times=false write_out_profile_data=true type_stats="" trace_count=false coverage_test=false disable_debug_libs=false delete_deep_data=false deep_write_sample=true deep_debug=false progress=false if test -f .KEEP_OBJS then keep_objs=true fi if test -f .DELETE_DEEP_DATA then delete_deep_data=true fi if test -f .BOOT_GRADE then grade=$(cat .BOOT_GRADE) fi if test -f .NO_WRITE_DEEP then write_out_profile_data=false fi if test -f .PROGRESS then progress=true fi # If you change these, you will also need to change the files indicated # in scripts/c2init.in. # RT_LIB_NAME=mer_rt # not used in this script STD_LIB_NAME=mer_std TRACE_LIB_NAME=mer_trace BROWSER_LIB_NAME=mer_browser SSDB_LIB_NAME=mer_ssdb MDBCOMP_LIB_NAME=mer_mdbcomp while test $# -gt 0 do case "$1" in -b-|--no-bootcheck) do_bootcheck=false ;; -d|--test-dir) testdirs="${testdirs} $2" shift ;; -d*) testdirs="${testdirs} ` expr X$1 : 'X-d\(.*\)' `"; ;; -e|--extras) extras=true ;; -s|--specified-tests) specified_tests_only="${specified_tests_only} $2" shift ;; -f|--failing-tests) failing_tests_only=true ;; --error-file) error_file_only=true ;; --expect-no-failures) expect_listed_failures=false ;; -h|--help) echo "${usage}" exit 0 ;; -j|--jobs) jfactor="-j$2" shift ;; -j*) jfactor="-j` expr X$1 : X'-j\(.*\)' `" ;; --jobs*) jfactor="--jobs` expr X$1 : 'X--jobs\(.*\)' `" ;; -k|--keep-objs) keep_objs=true ;; -m|--mmake|--mmake-opts) mmake_opts="${mmake_opts} $2" shift ;; -o|--output-file) outfile="$2" shift ;; -o*) outfile="` expr X$1 : 'X-o\(.*\)' `" ;; --target) case "$2" in c|java|csharp) target="$2" shift ;; *) echo "unknown target \`$2'" 1>&2 exit 1 ;; esac ;; -G|--grade) grade="$2" shift ;; -G*) grade="` expr X$1 : 'X-G\(.*\)' `" ;; --gradedir) use_gradedir=true grade="$2" shift ;; --test-grade) test_grade="$2" shift ;; --mercury-options) MERCURY_OPTIONS="$2" export MERCURY_OPTIONS shift ;; -r|--copy-runtime) copy_runtime=true ;; -g|--copy-boehm-gc) copy_boehm_gc=true ;; -p-|-no-copy-profilers) copy_profilers=false ;; --no-copy-slice) copy_slice=false ;; --check-namespace) check_namespace=true ;; --no-check-namespace) check_namespace=false ;; -t-|--no-test-suite) runtests=false ;; --skip-stage-2) keep_stage_2=true build_stage_2=false ;; --skip-stage-3) keep_stage_3=true build_stage_3=false ;; -2|--keep-stage-2) keep_stage_2=true ;; -3|--keep-stage-3) keep_stage_3=true ;; --test-params) test_params=true ;; --no-test-params) test_params=false ;; --test-with-stage-1-compiler) test_with_stage_1_compiler=true ;; --keep-success-log-files) KEEP_SUCCESS_LOG_FILES=keep_success_log_files export KEEP_SUCCESS_LOG_FILES ;; --stop-after-stage-2) stop_after_stage_2=true ;; --use-subdirs) use_subdirs=yes ;; --no-use-subdirs) use_subdirs=no ;; --use-mmc-make) use_mmc_make=yes use_subdirs=yes ;; --no-use-mmc-make) use_mmc_make=no ;; --compile-times) compile_times=true ;; --no-compile-times) compile_times=false ;; --no-write-out-profile-data) write_out_profile_data=false ;; --type-stats) type_stats="$2" shift ;; --trace-count|--trace-counts) trace_count=true ;; --coverage-test) coverage_test=true ;; -W|--windows) windows=true use_cp=true ;; --use-cp) use_cp=true ;; --no-sym-links) use_cp=true ;; --disable-debug-libs) disable_debug_libs=true ;; --delete-deep-data) delete_deep_data=true ;; --deep-all-write) deep_write_sample=false ;; --deep-debug) deep_debug=true ;; --progress) progress=true ;; --) shift break ;; -*) echo "$0: unknown option \`$1'" 1>&2 echo "${usage}" 1>&2 exit 1 ;; *) break ;; esac shift done if test $# -ne 0 then echo "$0: unexpected argument(s) \`$*'" 1>&2 echo "${usage}" 1>&2 exit 1 fi if test "${grade}" != "" -a "${test_grade}" = "" then test_grade="${grade}" fi # For the C# and Java grades, we have to use mmc --make. # We also disable the namespace cleanliness check for these grades. case "${grade}" in java*) target=java use_mmc_make=yes use_subdirs=yes check_namespace=false ;; csharp*) target=csharp use_mmc_make=yes use_subdirs=yes check_namespace=false ;; esac case ${use_subdirs} in yes) cs_subdir=Mercury/cs/ css_subdir=Mercury/css/ javas_subdir=Mercury/javas/jmercury/ ;; no) cs_subdir= css_subdir= javas_subdir= ;; esac case ${target} in c) target_ext=c collective_target=all_cs target_subdir=${cs_subdir} target_opt= ;; csharp) target_ext=cs collective_target=all_css target_subdir=${css_subdir} target_opt= ;; java) target_ext=java collective_target=all_javas target_subdir=${javas_subdir} target_opt= ;; esac if test "${grade}" != "" -o "${test_grade}" != "" then copy_runtime=true copy_boehm_gc=true fi #-----------------------------------------------------------------------------# # Work out how to parallelise the bootcheck when -jN with N > 1 is given. # # If --use-mmc-make is *not* enabled, then all parallelism is handled by mmake, # using its -jN option. # # If --use-mmc-make is enabled, then each directory containing Mercury # libraries or executables must be built using a single invocation of # mmc --make. Multiple invocation of mmc --make in the same directory # will conflict with each other. # XXX This should not prevent us from using parallelism *within* a single # invocations of mmc --make. # # Directories containing target code only, such as the runtime and trace # directories, still need to be built with mmake in order to parallelise # their builds. # # Regardless of whether --use-mmc-make is enabled or not, we run the test suite # using mmake -jN. if test "${jfactor}" != "" then if test "${use_mmc_make}" = "yes" then mmake_jobs= mmc_make_jobs="MCFLAGS += ${jfactor}" else mmake_jobs="${jfactor}" mmc_make_jobs= fi else mmake_jobs= mmc_make_jobs= fi #-----------------------------------------------------------------------------# if ${use_cp} then LN="cp -pr" LN_S="cp -pr" else LN="ln" LN_S="ln -s" fi #-----------------------------------------------------------------------------# SED=${SED:-sed} #-----------------------------------------------------------------------------# # Are we in one of the MSYS2 environments on Windows? If so, then work out # which one and set up any necessary path translation and diff options. # We are concerned with two classes of MSYS2 environment: # # 1. MSYS. This environment is similar to Cygwin. Executables are linked # against msys-2.0.dll, which is a POSIX emulation layer. In this environment # we can use Unix-style paths and LF line endings. # # 2. Environments that create native Windows executables (e.g MING64, UCRT64). # In these environments, the shell and tools like make will use POSIX-style # paths (overlaid on the Windows file system), but the Mercury compiler will # use Windows-style paths. There is some automatic translation done between the # two, but we need to ensure that paths put in .options or _FLAGS files are in # the appropriate format. We also need to set some things for the test suite # to work properly (e.g. tell diff to ignore differences due the presence of # CRLF line endings). case "${MSYSTEM}" in MINGW64|MINGW32|UCRT64|CLANG64) env_is_msys2_native=true windows=true ;; MSYS) env_is_msys2_native=false windows=true ;; CLANGARM64) echo "bootchecking using MSYS2 environment ${MSYSTEM} is not supported." exit 1 ;; *) env_is_msys2_native=false ;; esac #-----------------------------------------------------------------------------# if ${windows} then CYGPATH='cygpath -m' else CYGPATH='echo' fi #-----------------------------------------------------------------------------# # Turn off the debugger, since accidentally leaving it on will result # in user interaction every time we invoke any version of the compiler # that was compiled with tracing. This has happened to me accidentally # one too many times - zs. if echo "${MERCURY_OPTIONS}" | grep '\-Di' > /dev/null then MERCURY_OPTIONS=$(echo "${MERCURY_OPTIONS}" | ${SED} -e 's/-Di//') export MERCURY_OPTIONS fi if test -r ${HOME}/.bootcheck_date then date_opts="$(cat ${HOME}/.bootcheck_date)" else date_opts="" fi echo "starting at $(date ${date_opts})" # set -x root=$(/bin/pwd) root=$(${CYGPATH} "${root}") PATH=${root}/tools:${PATH} export PATH #-----------------------------------------------------------------------------# if test "${use_gradedir}" = "true" then stage2dir=stage2.${grade} stage3dir=stage3.${grade} else stage2dir=stage2 stage3dir=stage3 fi if ${progress} then BOOTCHECK_TEST_PROGRESS=yes export BOOTCHECK_TEST_PROGRESS fi ORIG_MERCURY_OPTIONS="${MERCURY_OPTIONS}" if ${write_out_profile_data} then true else # Turn off the writing out of deep profiling files, since # Deep.data will be overwritten many times in each directory, # and thus the time spent writing them out is wasted. If deep # profiling debugging is enabled, this also avoids the writing # of *huge* amounts of stuff on stderr. MERCURY_OPTIONS="${MERCURY_OPTIONS} -s" export MERCURY_OPTIONS fi # In deep profiling grades, we want to test the code for writing out the # profiling tree, but there is no point in testing it on every single # invocation of the compiler, and doing so leads to *very* slow bootchecks. # We therefore enable it only for every 25th invocation, on average. # # When the profiling data is written out, however, we also want to test # writing out the program representation. if ${deep_write_sample} then MERCURY_OPTIONS="${MERCURY_OPTIONS} --deep-random-write=25" export MERCURY_OPTIONS fi # Always use the filenames "Deep.data" and "Deep.procrep" to store # the output of the deep profiler. By default, we include both # the executable and the date and time of the profiling run in the filenames, # but that makes it harder to clean up those files after each bootcheck. MERCURY_OPTIONS="${MERCURY_OPTIONS} --deep-std-name" if ${deep_debug} then MERCURY_OPTIONS="${MERCURY_OPTIONS} --deep-debug-file" export MERCURY_OPTIONS fi if ${trace_count} then MERCURY_OPTIONS="${MERCURY_OPTIONS} --trace-count-if-exec=mercury_compile" export MERCURY_OPTIONS fi if ${coverage_test} then mkdir -p "${root}"/coverage # Don't contaminate the coverage test with old data. /bin/rm "${root}"/coverage/COVERAGE_TEST_DATA* > /dev/null 2>&1 MERCURY_OPTIONS="${MERCURY_OPTIONS} --coverage-test-if-exec=mercury_compile --trace-count-summary-file=${root}/coverage/COVERAGE_TEST_DATA --trace-count-summary-cmd=${root}/slice/mtc_union" export MERCURY_OPTIONS # Check whether we can compile the slice directory. copy_slice=true fi NEW_MERCURY_OPTIONS="${MERCURY_OPTIONS} --mdb-disable-progress" if ${do_bootcheck} then MERCURY_OPTIONS="${ORIG_MERCURY_OPTIONS}" export MERCURY_OPTIONS if mmake ${mmake_opts} MMAKEFLAGS=${jfactor} all then echo "building of stage 1 successful" else mmake ${mmake_opts} depend if mmake ${mmake_opts} MMAKEFLAGS=${jfactor} all then echo "building of stage 1 successful" else echo "building of stage 1 not successful" exit 1 fi fi MMAKE_USE_SUBDIRS=${use_subdirs} export MMAKE_USE_SUBDIRS # We use TESTS_USE_SUBDIRS to record the value that we set # MMAKE_USE_SUBDIRS to. While mmake can override the value that # we assign to MMAKE_USE_SUBDIRS here (by effectively force-enabling # the use of subdirs if a Mercury directory exists), mmake won't # do this to the TESTS_USE_SUBDIRS variable, since it does not know # about it. Some test directories (mmc_make and valid_make_int, as of # 2025 mar 28) need this stability. TESTS_USE_SUBDIRS=${use_subdirs} export TESTS_USE_SUBDIRS MMAKE_USE_MMC_MAKE=${use_mmc_make} export MMAKE_USE_MMC_MAKE MERCURY_OPTIONS="${NEW_MERCURY_OPTIONS}" export MERCURY_OPTIONS MERCURY_COMPILER=${root}/compiler/mercury_compile export MERCURY_COMPILER # now in FLAGS files # MERCURY_CONFIG_FILE=${root}/scripts/Mercury.config # export MERCURY_CONFIG_FILE test -d ${stage2dir} || mkdir ${stage2dir} if ${keep_stage_2} then echo keeping existing stage 2 else /bin/rm -fr "${root:?}/${stage2dir}" < /dev/null mkdir "${root}/${stage2dir}" fi if ${build_stage_2} then set +x echo linking stage 2... 1>&2 cd "${stage2dir}" ${LN_S} "${root}"/RESERVED_MACRO_NAMES . ${LN_S} "${root}"/STANDARD_MCFLAGS . mkdir compiler cd compiler # Break up the links into several chunks. # This is needed to cope with small limits # on the size of argument vectors. ${LN_S} "${root}"/compiler/[a-h]*.m . ${LN_S} "${root}"/compiler/[i-o]*.m . ${LN_S} "${root}"/compiler/[p-s]*.m . ${LN_S} "${root}"/compiler/[t-z]*.m . ${LN_S} "${root}"/compiler/notes . cp "${root}"/compiler/Mmake* "${root}"/compiler/Mercury.options . cp "${root}"/compiler/*_FLAGS.in . cp "${root}"/compiler/.mgnu* . cd "${root}/${stage2dir}" mkdir library cd library ${LN_S} "${root}"/library/[a-l]*.m . ${LN_S} "${root}"/library/[m-z]*.m . # See comment below for why we use ${LN} rather than ${LN_S} here ${LN} "${root}"/library/library_strong_name.sn . ${LN_S} "${root}"/library/print_extra_inits . ${LN_S} "${root}"/library/MODULES_DOC . ${LN_S} "${root}"/library/MODULES_UNDOC . cp "${root}"/library/Mmake* "${root}"/library/Mercury.options . cp "${root}"/library/*_FLAGS.in . cp "${root}"/library/INTER_FLAGS* . cp "${root}"/library/mer_std.trans_opt_deps_spec . cp "${root}"/library/.mgnu* . ${LN_S} "${root}"/library/${STD_LIB_NAME}.init . ${LN_S} "${root}"/library/RESERVED_MACRO_NAMES . cd "${root}/${stage2dir}" mkdir mdbcomp cd mdbcomp ${LN_S} "${root}"/mdbcomp/*.m . cp "${root}"/mdbcomp/Mmake* "${root}"/mdbcomp/Mercury.options . cp "${root}"/mdbcomp/*_FLAGS.in . cp "${root}"/mdbcomp/.mgnu* . ${LN_S} "${root}"/mdbcomp/${MDBCOMP_LIB_NAME}.init . ${LN_S} "${root}"/mdbcomp/RESERVED_MACRO_NAMES . cd "${root}/${stage2dir}" mkdir browser cd browser ${LN_S} "${root}"/browser/*.m . cp "${root}"/browser/Mmake* "${root}"/browser/Mercury.options . cp "${root}"/browser/*_FLAGS.in . cp "${root}"/browser/.mgnu* . ${LN_S} "${root}"/browser/${BROWSER_LIB_NAME}.init . ${LN_S} "${root}"/browser/RESERVED_MACRO_NAMES . cd "${root}/${stage2dir}" mkdir ssdb cd ssdb ${LN_S} "${root}"/ssdb/*.m . cp "${root}"/ssdb/Mmake* "${root}"/ssdb/Mercury.options . cp "${root}"/ssdb/*_FLAGS.in . cp "${root}"/ssdb/.mgnu* . ${LN_S} "${root}"/ssdb/${SSDB_LIB_NAME}.init . ${LN_S} "${root}"/ssdb/RESERVED_MACRO_NAMES . cd "${root}/${stage2dir}" mkdir grade_lib cd grade_lib ${LN_S} "${root}"/grade_lib/*.m . cp "${root}"/grade_lib/Mmake* "${root}"/grade_lib/Mercury.options . cp "${root}"/grade_lib/*_FLAGS.in . cp "${root}"/grade_lib/.mgnu* . cd "${root}/${stage2dir}" mkdir mfilterjavac cd mfilterjavac ${LN_S} "${root}"/mfilterjavac/*.m . cp "${root}"/mfilterjavac/Mmake* . cp "${root}"/mfilterjavac/*_FLAGS.in . cp "${root}"/mfilterjavac/.mgnu* . cd "${root}/${stage2dir}" if ${copy_runtime} then # Remove symbolic link to the stage 1 runtime # if it is present, which it can be with the -2 option. rm -f runtime mkdir runtime cd runtime ${LN_S} "${root}"/runtime/*.h . ${LN_S} "${root}"/runtime/*.c . ${LN_S} "${root}"/runtime/*.cs . # We need to use ${LN} rather than ${LN_S} for the files # that get processed with Microsoft's tools, since # Microsoft's tools don't understand Cygwin symbolic links # (hard links are OK, Cygwin's ln just makes copies). rm -f mercury_conf*.h ${LN} "${root}"/runtime/mercury_conf*.h . ${LN_S} "${root}"/runtime/*.in . cp "${root}"/runtime/Mmake* . cp "${root}"/runtime/.mgnu* . ${LN_S} "${root}"/runtime/machdeps . ${LN_S} "${root}"/runtime/RESERVED_MACRO_NAMES . cd "${root}/${stage2dir}" rm -f trace mkdir trace cd trace ${LN_S} "${root}"/trace/*.h . ${LN_S} "${root}"/trace/*.c . ${LN_S} "${root}"/trace/*.[yl] . cp "${root}"/trace/Mmake* . cp "${root}"/trace/.mgnu* . ${LN_S} "${root}"/trace/RESERVED_MACRO_NAMES . cd "${root}/${stage2dir}" rm -f robdd mkdir robdd cd robdd ${LN_S} "${root}"/robdd/*.h . ${LN_S} "${root}"/robdd/*.c . cp "${root}"/robdd/Mmake* . cp "${root}"/robdd/Make* . cd "${root}/${stage2dir}" else ${LN_S} "${root}"/runtime . ${LN_S} "${root}"/trace . ${LN_S} "${root}"/robdd . fi if ${copy_boehm_gc} then # Remove symbolic link to the stage 1 gc # if it is present, which it can be with the -2 option. rm -f boehm_gc mkdir boehm_gc cd boehm_gc ${LN_S} "${root}"/boehm_gc/*.c . ${LN_S} "${root}"/boehm_gc/*.s . ${LN_S} "${root}"/boehm_gc/*.S . ${LN_S} "${root}"/boehm_gc/include . cp "${root}"/boehm_gc/Mmake* . cp "${root}"/boehm_gc/Makefile.direct . cp "${root}"/boehm_gc/NT*_MAKEFILE . cp "${root}"/boehm_gc/gc_cpp.cc . cp "${root}"/boehm_gc/gc_cpp.cpp . cp -r "${root}"/boehm_gc/cord . cp -r "${root}"/boehm_gc/libatomic_ops . cp -r "${root}"/boehm_gc/extra . cp -r "${root}"/boehm_gc/tools . cd "${root}/${stage2dir}" else ${LN_S} "${root}"/boehm_gc . fi ${LN_S} "${root}"/java . ${LN_S} "${root}"/bindist . ${LN_S} "${root}"/doc . ${LN_S} "${root}"/scripts . ${LN_S} "${root}"/tools . ${LN_S} "${root}"/util . if ${copy_slice} then mkdir slice cd slice ${LN_S} "${root}"/slice/*.m . cp "${root}"/slice/Mmake* "${root}"/slice/Mercury.options . cp "${root}"/slice/*_FLAGS.in . cp "${root}"/slice/.mgnu* . cd "${root}/${stage2dir}" else ${LN_S} "${root}"/slice . fi if ${copy_profilers} then mkdir profiler cd profiler ${LN_S} "${root}"/profiler/*.m . cp "${root}"/profiler/Mmake* "${root}"/profiler/Mercury.options . cp "${root}"/profiler/*_FLAGS.in . cp "${root}"/profiler/.mgnu* . cd "${root}/${stage2dir}" mkdir deep_profiler cd deep_profiler ${LN_S} "${root}"/deep_profiler/*.m . cp "${root}"/deep_profiler/Mmake* . cp "${root}"/deep_profiler/Mercury.options . cp "${root}"/deep_profiler/*_FLAGS.in . cp "${root}"/deep_profiler/.mgnu* . cd "${root}/${stage2dir}" else ${LN_S} "${root}"/profiler . ${LN_S} "${root}"/deep_profiler . fi ${LN_S} "${root}"/conf* . ${LN_S} "${root}"/aclocal.m4 . ${LN_S} "${root}"/m4 . ${LN_S} "${root}"/VERSION . ${LN_S} "${root}"/install-sh . ${LN_S} "${root}"/.*.in . ${LN_S} "${root}"/mercury.snk . rm -f config*.log cp "${root}"/Mmake* "${root}"/Mercury.options . if test -f "${root}"/Mmake.stage.params then /bin/rm -f Mmake.params cp "${root}"/Mmake.stage.params Mmake.params fi if test -f "${root}"/Mmake.stage.slice.params then /bin/rm -f slice/Mmake.slice.params cp "${root}"/Mmake.stage.slice.params slice/Mmake.slice.params fi if test -f "${root}"/Mmake.stage.mdbcomp.params then /bin/rm -f mdbcomp/Mmake.mdbcomp.params cp "${root}"/Mmake.stage.mdbcomp.params \ mdbcomp/Mmake.mdbcomp.params fi if test -f "${root}"/Mmake.stage.browser.params then /bin/rm -f browser/Mmake.browser.params cp "${root}"/Mmake.stage.browser.params \ browser/Mmake.browser.params fi if test -f "${root}"/Mmake.stage.ssdb.params then /bin/rm -f ssdb/Mmake.ssdb.params cp "${root}"/Mmake.stage.ssdb.params ssdb/Mmake.ssdb.params fi if test -f "${root}"/Mmake.stage.grade_lib.params then /bin/rm -f grade_lib/Mmake.grade_lib.params cp "${root}"/Mmake.stage.grade_lib.params \ grade_lib/Mmake.grade_lib.params fi if test -f "${root}"/Mmake.stage.deep.params then /bin/rm -f deep_profiler/Mmake.deep.params cp "${root}"/Mmake.stage.deep.params \ deep_profiler/Mmake.deep.params fi if test -f "${root}"/Mmake.stage.compiler.params then /bin/rm -f compiler/Mmake.compiler.params cp "${root}"/Mmake.stage.compiler.params \ compiler/Mmake.compiler.params fi if test -f "${root}"/Mmake.stage.library.params then /bin/rm -f library/Mmake.library.params cp "${root}"/Mmake.stage.library.params \ library/Mmake.library.params fi if test -f "${root}"/Mmake.stage.runtime.params then /bin/rm -f runtime/Mmake.runtime.params cp "${root}"/Mmake.stage.runtime.params \ runtime/Mmake.runtime.params fi if test -f "${root}"/Mmake.stage.trace.params then /bin/rm -f trace/Mmake.trace.params cp "${root}"/Mmake.stage.trace.params trace/Mmake.trace.params fi if test -f "${root}"/Mercury.stage.options then /bin/rm -f Mercury.options cp "${root}"/Mercury.stage.options Mercury.options fi if test "${grade}" != "" then echo "GRADE = ${grade}" >> Mmake.params fi if test "${use_mmc_make}" = "yes" then echo "${mmc_make_jobs}" >> Mmake.params fi # set -x cd "${root}" MMAKE_VPATH=. export MMAKE_VPATH MMAKE_DIR="${root}"/scripts export MMAKE_DIR # Use the new mmake to build stage 2. MMAKE=${MMAKE_DIR}/mmake mmake_opts="${mmake_opts} ${target_opt}" MERCURY_MKINIT="${root}/util/mkinit" export MERCURY_MKINIT if (cd ${stage2dir} && ${MMAKE} ${mmake_opts} ${jfactor} runtime) then echo "building of stage 2 runtime successful" else echo "building of stage 2 runtime not successful" exit 1 fi case ${use_mmc_make} in yes) # The rules to generate *_FLAGS files from *_FLAGS.in files # will not run if we are using `mmc --make', so run them now. if (cd ${stage2dir} && \ ${MMAKE} \ library/LIB_FLAGS \ mdbcomp/MDBCOMP_FLAGS \ browser/MDB_FLAGS \ ssdb/SSDB_FLAGS \ grade_lib/GRADE_LIB_FLAGS \ compiler/COMP_FLAGS \ slice/SLICE_FLAGS \ profiler/PROF_FLAGS \ deep_profiler/DEEP_FLAGS \ mfilterjavac/MFILTERJAVAC_FLAGS) then echo "building of stage 2 flags files successful" else echo "building of stage 2 flags files not successful" exit 1 fi ;; esac # If you update this list, you will probably also need to update # the list of *_FLAGS files just above. if (cd ${stage2dir} && \ ${MMAKE} ${mmake_opts} \ dep_library \ dep_mdbcomp \ dep_browser dep_browser_aux \ dep_ssdb \ dep_grade_lib \ dep_compiler \ dep_slice \ dep_profiler dep_profiler_aux \ dep_deep_profiler \ dep_mfilterjavac) then echo "building of stage 2 dependencies successful" else echo "building of stage 2 dependencies not successful" exit 1 fi # For the csharp grade, Mmake.workspace needs to see the grade setting # when it defines MLLIBS, otherwise we will try to reference a separate # Mercury runtime assembly, which we do not have for the csharp grade. # As per Documentation/README.CSharp.md, we need to set GRADE as part # of the command line that invokes mmake. if test "${grade}" = "csharp" then ENVGRADE="GRADE=${grade}" else ENVGRADE= fi if (cd ${stage2dir}/library && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} all-ints mercury ${ENVGRADE}) then echo "building of stage 2 library successful" else echo "building of stage 2 library not successful" exit 1 fi if (cd ${stage2dir}/mdbcomp && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} library ${ENVGRADE}) then echo "building of stage 2 mdbcomp successful" else echo "building of stage 2 mdbcomp not successful" exit 1 fi if (cd ${stage2dir}/browser && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} library aux ${ENVGRADE}) then echo "building of stage 2 browser successful" else echo "building of stage 2 browser not successful" exit 1 fi if (cd ${stage2dir}/ssdb && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} library ${ENVGRADE}) then echo "building of stage 2 ssdb successful" else echo "building of stage 2 ssdb not successful" exit 1 fi if (cd ${stage2dir}/trace && \ ${MMAKE} ${mmake_opts} ${jfactor} trace ${ENVGRADE}) then echo "building of stage 2 trace successful" else echo "building of stage 2 trace not successful" exit 1 fi if ${disable_debug_libs} then /bin/rm ${stage2dir}/browser/lib${BROWSER_LIB_NAME}.a ar cr ${stage2dir}/browser/lib${BROWSER_LIB_NAME}.a /bin/rm ${stage2dir}/ssdb/lib${SSDB_LIB_NAME}.a ar cr ${stage2dir}/ssdb/lib${SSDB_LIB_NAME}.a /bin/rm ${stage2dir}/trace/lib${TRACE_LIB_NAME}.a ar cr ${stage2dir}/trace/lib${TRACE_LIB_NAME}.a fi if (cd ${stage2dir}/compiler && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} mercury_compile ${ENVGRADE}) then echo "building of stage 2 compiler successful" else echo "building of stage 2 compiler not successful" exit 1 fi # We use "mmake" instead ${MMAKE} because we don't want to override # the mmc in ${PATH} with the one in scripts, since that one will # probably refer to a nonexistent executable in /usr/local/mercury-DEV. if (cd ${stage2dir}/grade_lib && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} all ${ENVGRADE}) then echo "building of stage 2 grade_lib successful" else echo "building of stage 2 grade_lib not successful" exit 1 fi if (cd ${stage2dir}/slice && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} all ${ENVGRADE}) then echo "building of stage 2 slice successful" else echo "building of stage 2 slice not successful" exit 1 fi if (cd ${stage2dir}/profiler && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} all aux ${ENVGRADE}) then echo "building of stage 2 profiler successful" else echo "building of stage 2 profiler not successful" exit 1 fi if (cd ${stage2dir}/deep_profiler && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} all ${ENVGRADE}) then echo "building of stage 2 deep profiler successful" else echo "building of stage 2 deep profiler not successful" exit 1 fi if (cd ${stage2dir}/mfilterjavac && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} all ${ENVGRADE}) then echo "building of stage 2 mfilterjavac successful" else echo "building of stage 2 mfilterjavac not successful" exit 1 fi if (cd ${stage2dir} && \ ${MMAKE} ${mmake_opts} MMAKEFLAGS=${mmake_jobs} all ${ENVGRADE}) then echo "building of stage 2 successful" else echo "building of stage 2 not successful" exit 1 fi if ${compile_times} then ls -lt ${stage2dir}/library/*.c ls -lt ${stage2dir}/library/*.o ls -lt ${stage2dir}/library/*.{a,so,dylib} ls -lt ${stage2dir}/compiler/*.c ls -lt ${stage2dir}/compiler/*.o ls -lt ${stage2dir}/compiler/mercury_compile fi fi echo "finishing stage 2 at $(date ${date_opts})" # Build the check_namespace target in the relevant directories. # We want to do so before we delete any of the stage 2 object files. check_namespace_status=0 if ${check_namespace} then echo "starting namespace checks at $(date ${date_opts})" cd "${root}"/${stage2dir}/runtime mmake ${mmake_opts} check_namespace || { echo '** mmake check_namespace failed in runtime!' check_namespace_status=1 } mmake ${mmake_opts} clean_check cd "${root}"/${stage2dir}/trace mmake ${mmake_opts} check_namespace || { echo '** mmake check_namespace failed in trace!' check_namespace_status=1 } mmake ${mmake_opts} clean_check cd "${root}"/${stage2dir}/library mmake ${mmake_opts} check_namespace || { echo '** mmake check_namespace failed in library!' check_namespace_status=1 } mmake ${mmake_opts} clean_check cd "${root}"/${stage2dir}/mdbcomp mmake ${mmake_opts} check_namespace || { echo '** mmake check_namespace failed in mdbcomp!' check_namespace_status=1 } mmake ${mmake_opts} clean_check cd "${root}"/${stage2dir}/browser mmake ${mmake_opts} check_namespace || { echo '** mmake check_namespace failed in browser!' check_namespace_status=1 } mmake ${mmake_opts} clean_check cd "${root}"/${stage2dir}/ssdb mmake ${mmake_opts} check_namespace || { echo '** mmake check_namespace failed in ssdb!' check_namespace_status=1 } mmake ${mmake_opts} clean_check cd "${root}" echo "namespace checks done at $(date ${date_opts})" fi check_stdlib_modules_status=0 cd "${root}"/${stage2dir}/library mmake ${mmake_opts} check_stdlib_modules || { echo '** mmake check_stdlib_modules failed in library!' check_stdlib_modules_status=1 } cd "${root}" if ${stop_after_stage_2} then echo "stopping after building stage 2 at $(date ${date_opts})" exit 0 fi # We can now remove the object files from most stage 2 directories, # but we will keep the compiler objects for a while longer. if ${keep_objs} then true else libdirs="library mdbcomp browser ssdb" if ${copy_slice} then slicedirs="slice" else slicedirs= fi if ${copy_profilers} then profdirs="profiler deep_profiler" else profdirs= fi if ${copy_runtime} then rundirs="runtime trace" else rundirs= fi objdirs="${libdirs} ${slicedirs} ${profdirs} ${rundirs}" for rmdir in ${objdirs} do cd "${root}/${stage2dir}/${rmdir}" /bin/rm -f -- *.o *.pic_o *.obj done if ${check_namespace} then for cleandir in runtime trace library mdbcomp browser ssdb do cd "${root}/${stage2dir}/${cleandir}" mmake clean_check done fi cd "${root}" fi # In the java grade, the generated mercury_compile wrapper script # will not set the CLASSPATH correctly when building stage 3. # Replace it with one that will. # if test "${grade}" = "java" then cat > "${root}/${stage2dir}"/compiler/mercury_compile << EOF #!/bin/sh case \$WINDIR in '') SEP=':' ;; *) SEP=';' ;; esac CLASSPATH=${root}/${stage2dir}/compiler/mercury_compile.jar\${SEP}${root}/${stage2dir}/library/mer_rt.jar\${SEP}${root}/${stage2dir}/library/mer_std.jar\${SEP}${root}/${stage2dir}/mdbcomp/mer_mdbcomp.jar export CLASSPATH JAVA=\${JAVA:-/usr/bin/java} exec "\$JAVA" -Xss32m jmercury.mercury_compile "\$@" EOF # The Java version of the Mercury runtime does not currently support # most of the runtime options and will abort if they are passed to it. MERCURY_OPTIONS= export MERCURY_OPTIONS fi # In the csharp grade we also need to replace the generated mercury_compile # wrapper script. # XXX the following only works with Mono. if test "${grade}" = "csharp" then cat > "${root}"/${stage2dir}/compiler/mercury_compile << EOF #!/bin/sh MONO_PATH=\$MONO_PATH:${root}/${stage2dir}/library:${root}/${stage2dir}/mdbcomp export MONO_PATH CLI_INTERPRETER=\${CLI_INTERPRETER:-/usr/bin/mono} exec "\$CLI_INTERPRETER" "${root}/${stage2dir}/compiler/mercury_compile.exe" "\$@" EOF fi MERCURY_COMPILER="${root}/${stage2dir}"/compiler/mercury_compile export MERCURY_COMPILER test -d ${stage3dir} || mkdir ${stage3dir} if ${keep_stage_3} then echo keeping existing stage 3 else /bin/rm -fr "${root:?}/${stage3dir}" < /dev/null mkdir "${root}/${stage3dir}" fi if ${build_stage_3} then echo linking stage 3... 1>&2 set +x cd "${stage3dir}" mkdir compiler cd compiler # Break up the links into several chunks. # This is needed to cope with small limits # on the size of argument vectors. ${LN_S} "${root}"/compiler/[a-h]*.m . ${LN_S} "${root}"/compiler/[i-o]*.m . ${LN_S} "${root}"/compiler/[p-s]*.m . ${LN_S} "${root}"/compiler/[t-z]*.m . ${LN_S} "${root}"/compiler/notes . cp "${root}"/compiler/Mmake* "${root}"/compiler/Mercury.options . cp "${root}"/compiler/*_FLAGS.in . cp "${root}"/compiler/.mgnu* . cd "${root}/${stage3dir}" mkdir library cd library ${LN_S} "${root}"/library/[a-l]*.m . ${LN_S} "${root}"/library/[m-z]*.m . ${LN_S} "${root}"/library/print_extra_inits . ${LN_S} "${root}"/library/library_strong_name.sn . ${LN_S} "${root}"/library/MODULES_DOC . ${LN_S} "${root}"/library/MODULES_UNDOC . cp "${root}"/library/Mmake* "${root}"/library/Mercury.options . cp "${root}"/library/*_FLAGS.in . cp "${root}"/library/INTER_FLAGS* . cp "${root}"/library/mer_std.trans_opt_deps_spec . cp "${root}"/library/.mgnu* . ${LN_S} "${root}"/library/${STD_LIB_NAME}.init . cd "${root}/${stage3dir}" mkdir mdbcomp cd mdbcomp ${LN_S} "${root}"/mdbcomp/*.m . cp "${root}"/mdbcomp/Mmake* "${root}"/mdbcomp/Mercury.options . cp "${root}"/mdbcomp/*_FLAGS.in . cp "${root}"/mdbcomp/.mgnu* . ${LN_S} "${root}"/mdbcomp/${MDBCOMP_LIB_NAME}.init . cd "${root}/${stage3dir}" mkdir browser cd browser ${LN_S} "${root}"/browser/*.m . cp "${root}"/browser/Mmake* "${root}"/browser/Mercury.options . cp "${root}"/browser/*_FLAGS.in . cp "${root}"/browser/.mgnu* . ${LN_S} "${root}"/browser/${BROWSER_LIB_NAME}.init . cd "${root}/${stage3dir}" mkdir ssdb cd ssdb ${LN_S} "${root}"/ssdb/*.m . cp "${root}"/ssdb/Mmake* "${root}"/ssdb/Mercury.options . cp "${root}"/ssdb/*_FLAGS.in . cp "${root}"/ssdb/.mgnu* . ${LN_S} "${root}"/ssdb/${SSDB_LIB_NAME}.init . cd "${root}/${stage3dir}" ${LN_S} "${root}"/${stage2dir}/boehm_gc . ${LN_S} "${root}"/${stage2dir}/java . ${LN_S} "${root}"/bindist . ${LN_S} "${root}"/doc . ${LN_S} "${root}"/${stage2dir}/runtime . ${LN_S} "${root}"/${stage2dir}/trace . ${LN_S} "${root}"/${stage2dir}/robdd . ${LN_S} "${root}"/scripts . ${LN_S} "${root}"/tools . ${LN_S} "${root}"/util . cd "${root}/${stage3dir}" mkdir grade_lib cd grade_lib ${LN_S} "${root}"/grade_lib/*.m . cp "${root}"/grade_lib/Mmake* "${root}"/grade_lib/Mercury.options . cp "${root}"/grade_lib/*_FLAGS.in . cp "${root}"/grade_lib/.mgnu* . cd "${root}/${stage3dir}" mkdir slice cd slice ${LN_S} "${root}"/slice/*.m . cp "${root}"/slice/Mmake* "${root}"/slice/Mercury.options . cp "${root}"/slice/*_FLAGS.in . cp "${root}"/slice/.mgnu* . cd "${root}/${stage3dir}" mkdir profiler cd profiler ${LN_S} "${root}"/profiler/*.m . cp "${root}"/profiler/Mmake* "${root}"/profiler/Mercury.options . cp "${root}"/profiler/*_FLAGS.in . cp "${root}"/profiler/.mgnu* . cd "${root}/${stage3dir}" mkdir deep_profiler cd deep_profiler ${LN_S} "${root}"/deep_profiler/*.m . cp "${root}"/deep_profiler/Mmake* \ "${root}"/deep_profiler/Mercury.options . cp "${root}"/deep_profiler/*_FLAGS.in . cp "${root}"/deep_profiler/.mgnu* . cd "${root}/${stage3dir}" mkdir mfilterjavac cd mfilterjavac ${LN_S} "${root}"/mfilterjavac/*.m . cp "${root}"/mfilterjavac/Mmake* \ "${root}"/mfilterjavac/Mercury.options . cp "${root}"/mfilterjavac/*_FLAGS.in . cp "${root}"/mfilterjavac/.mgnu* . cd "${root}/${stage3dir}" ${LN_S} "${root}"/conf* . ${LN_S} "${root}"/aclocal.m4 . ${LN_S} "${root}"/m4 . ${LN_S} "${root}"/VERSION . ${LN_S} "${root}"/install-sh . ${LN_S} "${root}"/.*.in . rm -f config*.log cp "${root}"/${stage2dir}/Mmake* \ "${root}"/${stage2dir}/Mercury.options . cd "${root}" # set -x MMAKE_VPATH=. export MMAKE_VPATH MMAKE_DIR="${root}"/scripts export MMAKE_DIR # Use the new mmake to build stage 3. MMAKE=${MMAKE_DIR}/mmake # This setting is ignored unless the stage 2 was compiled with # -DMR_HO_CALL_STATS. HO_CALL_STATS="${root}/HO_CALL_STATS" export HO_CALL_STATS if test "${type_stats}" != "" then # Start collecting statistics from stage 3 with a clean slate, # while making sure that the existing stats are not lost. # Note: we do not have to go to any great lengths to restore # the old stats if bootcheck fails, since the save files # can easily be recovered outside bootcheck. cat "${type_stats}" >> "${type_stats}".save.$$ cp /dev/null "${type_stats}" fi case ${use_mmc_make} in yes) # The rules to generate *_FLAGS files from *_FLAGS.in files # will not run if we are using `mmc --make', so run them now. if (cd ${stage3dir} && \ ${MMAKE} \ library/LIB_FLAGS \ mdbcomp/MDBCOMP_FLAGS \ browser/MDB_FLAGS \ ssdb/SSDB_FLAGS \ grade_lib/GRADE_LIB_FLAGS \ compiler/COMP_FLAGS \ slice/SLICE_FLAGS \ profiler/PROF_FLAGS \ deep_profiler/DEEP_FLAGS \ mfilterjavac/MFILTERJAVAC_FLAGS) then echo "building of stage 3 flags files successful" else echo "building of stage 3 flags files not successful" exit 1 fi ;; esac if (cd ${stage3dir} && \ ${MMAKE} ${mmake_opts} \ dep_library \ dep_mdbcomp \ dep_browser dep_browser_aux \ dep_ssdb \ dep_compiler \ dep_grade_lib \ dep_slice \ dep_profiler dep_profiler_aux \ dep_deep_profiler \ dep_mfilterjavac) then echo "building of stage 3 dependencies successful" else echo "building of stage 3 dependencies not successful" exit 1 fi if (cd ${stage3dir}/library && ${MMAKE} ${mmake_opts} ${mmake_jobs} all-ints && ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 library successful" else echo "building of stage 3 library initially not successful" df . # Try again, in case the failure cause was transient. if (cd ${stage3dir}/library && ${MMAKE} ${mmake_opts} ${mmake_jobs} all-ints && ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 library successful" else echo "building of stage 3 library not successful" exit 1 fi fi # We delay deleting the stage 2 compiler objects until now, # so that if (a) an error manifests itself during the creation # of the stage 3 library, and (b) this error can be fixed by # changing the runtime, a bootcheck -2, which requires a relink, # will not have to expensively recreate the stage 2 compiler objects. if ${keep_objs} then true else find "${root}/${stage2dir}/compiler" -name "*.o" -print | xargs /bin/rm -f fi if (cd ${stage3dir}/mdbcomp && ${MMAKE} ${mmake_opts} ${mmake_jobs} all-ints && ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 mdbcomp successful" else echo "building of stage 3 mdbcomp initially not successful" df . # Try again, in case the failure cause was transient. if (cd ${stage3dir}/mdbcomp && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 mdbcomp successful" else echo "building of stage 3 mdbcomp not successful" exit 1 fi fi if (cd ${stage3dir}/browser && ${MMAKE} ${mmake_opts} ${mmake_jobs} all-ints && ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 browser successful" else echo "building of stage 3 browser initially not successful" df . # Try again, in case the failure cause was transient. if (cd ${stage3dir}/browser && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 browser successful" else echo "building of stage 3 browser not successful" exit 1 fi fi if (cd ${stage3dir}/ssdb && ${MMAKE} ${mmake_opts} ${mmake_jobs} all-ints && ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 ssdb successful" else echo "building of stage 3 ssdb initially not successful" df . # Try again, in case the failure cause was transient. if (cd ${stage3dir}/ssdb && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 ssdb successful" else echo "building of stage 3 ssdb not successful" exit 1 fi fi if (cd ${stage3dir}/compiler && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 compiler successful" else echo "building of stage 3 compiler initially not successful" df . # Try again, in case the failure cause was transient. if (cd ${stage3dir}/compiler && \ ${MMAKE} ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 compiler successful" else echo "building of stage 3 compiler not successful" exit 1 fi fi if (cd ${stage3dir}/grade_lib && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 grade_lib successful" else echo "building of stage 3 grade_lib not successful" exit 1 fi if (cd ${stage3dir}/slice && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 slice successful" else echo "building of stage 3 slice not successful" exit 1 fi if (cd ${stage3dir}/profiler && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 profiler successful" else echo "building of stage 3 profiler not successful" exit 1 fi if (cd ${stage3dir}/deep_profiler && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 deep profiler successful" else echo "building of stage 3 deep profiler not successful" exit 1 fi if (cd ${stage3dir}/mfilterjavac && \ unset MMAKE && \ unset MMAKE_VPATH && \ unset MMAKE_DIR && \ unset MERCURY_CONFIG_DIR && \ unset MERCURY_STDLIB_DIR && \ mmake ${mmake_opts} ${mmake_jobs} ${collective_target}) then echo "building of stage 3 mfilterjavac successful" else echo "building of stage 3 mfilterjavac not successful" exit 1 fi if test "${type_stats}" != "" then echo "Saving stage 3 stats in ${type_stats}.stage3.$$" mv "${type_stats}" "${type_stats}".stage3.$$ cp /dev/null "${type_stats}" fi diff_status=0 exec 3>&1 # save stdout in fd 3 if test -n "${outfile}" then exec > "${outfile}" # redirect stdout to ${outfile} fi for dir in \ library \ mdbcomp \ browser \ ssdb \ compiler \ grade_lib \ slice \ profiler \ deep_profiler \ mfilterjavac do # `mmake all_cs' in the compiler directory doesn't build # `mercury_compile_init.c', so we only compare the `.c' # files present in the stage 3 directory. for file in ${stage3dir}/${dir}/${target_subdir}*.${target_ext} do # In the C# and Java grades, some modules have expected # differences between the code generated for them # in stage 2 and stage 3, due to stage 2 being (usually) # generated by a 64 bit compiler, but stage 3 being generated # by a compiler in which native integers are 32 bits. compare_file=true base_file=$(basename "${file}") case "${grade}" in java*) case "${dir},${base_file}" in library,mr_float.java) compare_file=false ;; library,bitmap.java) compare_file=false ;; library,fat_sparse_bitset.java) compare_file=false ;; library,fatter_sparse_bitset.java) compare_file=false ;; library,sparse_bitset.java) compare_file=false ;; library,test_bitset.java) compare_file=false ;; library,tree_bitset.java) compare_file=false ;; library,version_bitmap.java) compare_file=false ;; profiler,snapshots.java) compare_file=false ;; deep_profiler,display_report.java) compare_file=false ;; deep_profiler,measurement_units.java) compare_file=false ;; deep_profiler,read_profile.java) compare_file=false ;; esac ;; csharp*) case "${dir},${base_file}" in library,bitmap.cs) compare_file=false ;; library,fat_sparse_bitset.cs) compare_file=false ;; library,fatter_sparse_bitset.cs) compare_file=false ;; library,sparse_bitset.cs) compare_file=false ;; library,test_bitmap.cs) compare_file=false ;; library,test_bitset.cs) compare_file=false ;; library,tree_bitset.cs) compare_file=false ;; library,version_bitmap.cs) compare_file=false ;; profiler,snapshots.cs) compare_file=false ;; deep_profiler,display_report.cs) compare_file=false ;; deep_profiler,measurement_units.cs) compare_file=false ;; deep_profiler,read_profile.cs) compare_file=false ;; esac ;; esac if ${compare_file} then diff -u \ "${stage2dir}/${dir}/${target_subdir}${base_file}" \ "${file}" \ || diff_status=1 fi done done exec >&3 # restore stdout from fd 3 if test ${diff_status} -ne 0 then echo "** error - stage 2 and stage 3 have unexpected differences!" else echo "stage 2 and stage 3 compare ok" if test -d ${stage3dir}/library/ComplexityArgs then mv ${stage3dir}/library/ComplexityArgs \ "${root}"/stage3_library_ComplexityArgs fi if test -d ${stage3dir}/library/ComplexityData then mv ${stage3dir}/library/ComplexityData \ "${root}"/stage3_library_ComplexityData fi if test -d ${stage3dir}/compiler/ComplexityArgs then mv ${stage3dir}/compiler/ComplexityArgs \ "${root}"/stage3_compiler_ComplexityArgs fi if test -d ${stage3dir}/compiler/ComplexityData then mv ${stage3dir}/compiler/ComplexityData \ "${root}"/stage3_compiler_ComplexityData fi echo "removing stage 3..." /bin/rm -fr "${root:?}/${stage3dir}" < /dev/null if ${keep_objs} then true else case "${grade}" in *debug*) # These files take up a lot of disk space, # so we compress them. This reduces the probability # that running the tests will run out of disk space, # while still allowing the original files to be # reconstructed relatively quickly. gzip "${root}"/${stage2dir}/library/*.c gzip "${root}"/${stage2dir}/mdbcomp/*.c gzip "${root}"/${stage2dir}/browser/*.c gzip "${root}"/${stage2dir}/ssdb/*.c gzip "${root}"/${stage2dir}/compiler/*.c ;; esac fi fi echo "finishing stage 3 at $(date ${date_opts})" else diff_status=0 echo "building of stage 3 skipped" fi else MMAKE_USE_SUBDIRS=${use_subdirs} export MMAKE_USE_SUBDIRS MMAKE_USE_MMC_MAKE=${use_mmc_make} export MMAKE_USE_MMC_MAKE # The Java version of the Mercury runtime does not currently support most # of the runtime options and will abort if they are passed to it. if test "${grade}" = "java" then MERCURY_OPTIONS= export MERCURY_OPTIONS fi diff_status=0 check_namespace_status=0 check_stdlib_modules_status=0 echo "building of stages 1 and 2 skipped" fi #-----------------------------------------------------------------------------# mdb_command_test_inp_status=0 if test "${runtests}" = "true" -o "${extras}" = "true" then # Use everything from stage 2, unless the options say that the tests # should be done in grade different from the grade of stage 2, # in which case use everything from stage 1, trusting the user # that the grade of the tests and the grade of stage 1 are compatible. if test "${test_with_stage_1_compiler}" = true then MERCURY_COMPILER=${root}/compiler/mercury_compile else MERCURY_COMPILER=${root}/${stage2dir}/compiler/mercury_compile fi export MERCURY_COMPILER # now in FLAGS files # MERCURY_CONFIG_FILE=${root}/scripts/Mercury.config # export MERCURY_CONFIG_FILE if test "${test_grade}" = "${grade}" then stage2_insert="/${stage2dir}" else stage2_insert="" fi if "$env_is_msys2_native" then WORKSPACE=$($CYGPATH "${root}${stage2_insert}") else WORKSPACE="${root}${stage2_insert}" fi export WORKSPACE MMAKE_DIR="${root}${stage2_insert}/scripts" export MMAKE_DIR # Set PATH for mkinit, mmc, mgnuc, ml etc PATH=${root}${stage2_insert}/util:${root}${stage2_insert}/scripts:${PATH} export PATH fi #-----------------------------------------------------------------------------# # Run the tests in the tests/* directories. if test -s "${HOME}"/.bootcheck_diff_opts then DIFF_OPTS=$(cat "${HOME}"/.bootcheck_diff_opts) export DIFF_OPTS fi if "${windows}" then DIFF_OPTS="${DIFF_OPTS:-} -u --strip-trailing-cr" export DIFF_OPTS fi test_status=0 if ${runtests} then echo "starting the test suite at $(date ${date_opts})" # If the workspace has been moved since ${root}/scripts/test_mdbrc # was last built, that file will refer to the OLD location of # the workspace, which may not exist anymore. We therefore rebuild # the file. (cd "${root}"/scripts; /bin/rm test_mdbrc; mmake test_mdbrc) MERCURY_DEBUGGER_INIT="${root}"/scripts/test_mdbrc export MERCURY_DEBUGGER_INIT MERCURY_SUPPRESS_STACK_TRACE=yes export MERCURY_SUPPRESS_STACK_TRACE if test "${test_grade}" != "" then test_grade_opt="GRADE=${test_grade}" else test_grade_opt="" fi # If you try to set all these at once, you get a too-long line. SUBJECT="subject=87" CORRECT="correct=40" INCORRECT="incorrect=203" INCONSISTENT="inconsistent=171" HINT="hint=226" COLORS123="${SUBJECT}:${CORRECT}:${INCORRECT}" COLORS45="${INCONSISTENT}:${HINT}" MERCURY_COLOR_SCHEME="specified@${COLORS123}:${COLORS45}" export MERCURY_COLOR_SCHEME echo "MERCURY_COLOR_SCHEME=${MERCURY_COLOR_SCHEME}" MERCURY_ENABLE_COLOR=always export MERCURY_ENABLE_COLOR test_status=0 if test "${test_status}" = 0 then if ${test_params} then cp "${root}"/${stage2dir}/Mmake.params tests else /bin/rm tests/Mmake.params > /dev/null 2>&1 fi if cmp \ "${root}"/doc/mdb_command_test.inp \ tests/debugger/mdb_command_test.inp then true else mdb_command_test_inp_status=1 fi cp "${root}"/doc/mdb_command_test.inp tests/debugger ${SED} -e "s,@WORKSPACE@,${WORKSPACE}," \ < tests/WS_FLAGS.ws \ > tests/WS_FLAGS ${SED} -e "s,@WORKSPACE@,${WORKSPACE}," \ < tests/.mgnuc_copts.ws \ > tests/.mgnuc_copts # If you modify this, modify SUBDIRS in tests/Mmakefile as well. all_test_dirs=" accumulator analysis analysis_ctgc analysis_excp analysis_external analysis_sharing analysis_table analysis_trail analysis_unused_args benchmarks debugger declarative_debugger dppd exceptions feedback general grade_subdirs hard_coded invalid invalid_make_int invalid_nodepend invalid_onlydepend invalid_options_file invalid_purity invalid_submodules misc_tests mmc_make options_file par_conj purity recompilation string_format structure_reuse submodules tabling term trailing typeclasses valid valid_make_int valid_seq warnings" for d in ${all_test_dirs} do cp tests/.mgnuc_copts tests/"${d}" cp tests/.mgnuc_opts tests/"${d}" /bin/rm -fr tests/"${d}"/Mercury done WORKSPACE_FLAGS=yes export WORKSPACE_FLAGS if test "${grade}" = "java" then MERCURY_STAGE2_LAUNCHER_BASE=${root}/${stage2dir} export MERCURY_STAGE2_LAUNCHER_BASE fi # Tell the executables for the tests where the stage 2 library lives. # XXX this only works for Mono; MS .NET doesn't have an equivalent of # the MONO_PATH environment variable. (To support MS .NET we may just # have to copy the library DLL into any test directory that creates # executables.) if test "${grade}" = "csharp" then MONO_PATH=${root}/${stage2dir}/library export MONO_PATH fi case ${error_file_only} in true) if test ! -f tests/runtests.errs then echo "bootcheck: \`--failing-tests' specified but" 1>&2 echo "\`tests/runtests.errs' does not exist." 1>&2 exit 1 fi mv tests/runtests.errs tests/runtests.$$ test_log_opt="ERROR_FILE=${root}/tests/runtests.$$" ;; false) test_log_opt="" ;; esac case ${failing_tests_only} in true) test_log_opt="FAILED_TESTS_ONLY=yes" ;; esac cd "${root}/tests" true > FAILED_TESTS_SUMMARY true > NOMAKE_DIRS /bin/rm -fr PASSED_TC_DIR FAILED_TC_DIR > /dev/null 2>&1 mkdir -p PASSED_TC_DIR FAILED_TC_DIR echo 0 > PASSED_TC_DIR/NEXT_NUMBER echo 0 > FAILED_TC_DIR/NEXT_NUMBER SLICE_DIR="${root}/slice/" export SLICE_DIR if test "${specified_tests_only}" != "" then test_status=0 for specified_test in ${specified_tests_only} do specified_test_dir=$(dirname "${specified_test}") specified_test_base=$(basename "${specified_test}") if test -d "${root}/tests/${specified_test_dir}" then cd "${root}/tests/${specified_test_dir}" mmake ${mmake_opts} ${target_opt} ${jfactor} \ ${test_grade_opt} \ SPECIFIED_TESTS="${specified_test_base}" \ runtests_local < /dev/null if test "$?" -ne "0" then test_status=$? fi else test_status=1 fi done else if test "${testdirs}" = "" then testdirs="${all_test_dirs}" fi test_status=0 for testdir in ${testdirs} do if test -d "${root}/tests/${testdir}" then cd "${root}/tests/${testdir}" mmake ${mmake_opts} ${target_opt} ${jfactor} \ ${test_grade_opt} ${test_log_opt} \ runtests_dir < /dev/null if test "$?" -ne 0 then test_status=1 fi else echo "test dir ${testdir} does not exist" test_status=1 fi done fi case ${failing_tests_only} in true) rm -f tests/runtests.$$ ;; esac if test "${type_stats}" != "" then echo "Saving test suite stats in ${type_stats}.test.$$" mv "${type_stats}" "${type_stats}".test.$$ fi cd "${root}"/tests for tcdir in PASSED_TC_DIR FAILED_TC_DIR do if test "$(cat ${tcdir}/NEXT_NUMBER)" -gt 0 then "${SLICE_DIR}"slice/mtc_union -o ${tcdir}/SUMMARY \ ${tcdir}/trace_counts.* /bin/rm ${tcdir}/trace_counts.* fi done cd "${root}" fi fi #-----------------------------------------------------------------------------# # Run the tests in the extras/* directories. extras_status=0 if "${extras}" then cd "${root}"/extras if test -f Mmake.params then mv Mmake.params Mmake.params.$$ fi if test -f "${root}"/Mmake.stage.params then cp "${root}"/Mmake.stage.params Mmake.params elif test -f "${root}"/Mmake.params then cp "${root}"/Mmake.params Mmake.params else cp /dev/null Mmake.params fi if test "${test_grade}" != "" then echo "GRADE = ${test_grade}" >> Mmake.params elif test "${grade}" != "" then echo "GRADE = ${grade}" >> Mmake.params fi for testdir in * do if test -f "${testdir}"/Mmakefile -a ! -f "${testdir}"/NOBOOTTEST then (cd "${testdir}"; mmake ${mmake_opts} ${mmake_jobs} realclean; mmake ${mmake_opts} ${mmake_jobs} depend && mmake ${mmake_opts} ${mmake_jobs} && mmake ${mmake_opts} ${mmake_jobs} check && mmake ${mmake_opts} ${mmake_jobs} realclean ) || extras_status=1 fi done if test -f Mmake.params.$$ then mv Mmake.params.$$ Mmake.params else /bin/rm Mmake.params fi cd "${root}" fi cd "${root}" if ${delete_deep_data} then # NOTE You need the parentheses for the -print action to apply # to the file name matches for *all* the patterns. # # The mmc and mandelbrot subdirectories of tests/feedback contain # .data and .procrep files that are under version control, and which # we do therefore do NOT want to delete. (We *could* delete them, # and then do "git co" to get them back, but that would not work # in non-version-controlled copies of workspaces.) # # Note that we *could* just stop deleting files named Deep.{data,procrep}. # The code here serves to clean up such files left by deep profiling # bootchecks before the naming change, but that won't be needed forever. find stage2 tests \ \( -name Deep.data \ -o -name Deep.procrep \ -o -name 'mercury_compile_on_*_at_*.data' \ -o -name 'mercury_compile_on_*_at_*.procrep' \ \) -print \ | sed \ -e '/tests\/feedback\/mmc/d' \ -e '/tests\/feedback\/mandelbrot/d' \ | xargs /bin/rm -f fi #-----------------------------------------------------------------------------# if test "${type_stats}" != "" then mv "${type_stats}".save.$$ "${type_stats}" fi tests_dir="${root}/tests" cat /dev/null > "${tests_dir}"/EXPECT_FAIL_TESTS if test -s "${tests_dir}"/FAILED_TESTS_SUMMARY then ${SED} -e 's/ .*//' < "${tests_dir}"/FAILED_TESTS_SUMMARY \ > "${tests_dir}"/FAIL_TESTS if test -f "${tests_dir}"/EXPECT_FAIL_TESTS.all_grades then cat "${tests_dir}"/EXPECT_FAIL_TESTS.all_grades >> \ "${tests_dir}"/EXPECT_FAIL_TESTS fi if test -f "${tests_dir}"/EXPECT_FAIL_TESTS."${test_grade}" then cat "${tests_dir}"/EXPECT_FAIL_TESTS."${test_grade}" >> \ "${tests_dir}"/EXPECT_FAIL_TESTS fi sort "${tests_dir}"/EXPECT_FAIL_TESTS \ > "${tests_dir}"/EXPECT_FAIL_TESTS.sort mv "${tests_dir}"/EXPECT_FAIL_TESTS.sort "${tests_dir}"/EXPECT_FAIL_TESTS sort "${tests_dir}"/FAIL_TESTS > "${tests_dir}"/FAIL_TESTS.sort mv "${tests_dir}"/FAIL_TESTS.sort "${tests_dir}"/FAIL_TESTS comm -23 "${tests_dir}"/FAIL_TESTS \ "${tests_dir}"/EXPECT_FAIL_TESTS \ > "${tests_dir}"/UNEXPECTED_FAILED_TESTS comm -12 "${tests_dir}"/FAIL_TESTS \ "${tests_dir}"/EXPECT_FAIL_TESTS \ > "${tests_dir}"/EXPECTED_FAILED_TESTS if ${expect_listed_failures} then if test ! -s "${tests_dir}"/UNEXPECTED_FAILED_TESTS then test_status=0 fi fi fi echo "-----------------------------------------------------------------------" exitstatus=0 if test "${diff_status}" != 0 then echo "ERROR EXIT: stages 2 and 3 have unexpected differences" exitstatus=1 fi if test "${mdb_command_test_inp_status}" != 0 then echo "ERROR EXIT: unexpected change in" \ "tests/debugger/mdb_command_test.inp" exitstatus=1 fi if test "${test_status}" != 0 then echo "ERROR EXIT: some tests failed" exitstatus=1 fi if test "${extras_status}" != 0 then echo "ERROR EXIT: some tests failed in extras" exitstatus=1 fi if test "${check_namespace_status}" != 0 then echo "ERROR EXIT: some namespace isn't clean" exitstatus=1 fi if test "${check_stdlib_modules_status}" != 0 then echo "ERROR EXIT: mismatch in list of stdlib modules" exitstatus=1 fi if test -s "${tests_dir}"/NOMAKE_DIRS then echo "ERROR EXIT: some test directories were left out" cat "${tests_dir}"/NOMAKE_DIRS exitstatus=1 fi if test -s "${tests_dir}"/FAILED_TESTS_SUMMARY then num_expected_failures=$(wc -l < "${tests_dir}"/EXPECTED_FAILED_TESTS) case "${num_expected_failures}" in 0) ;; 1) echo "one expected test case failure:" echo ${SED} -e 's/^/ /' < "${tests_dir}"/EXPECTED_FAILED_TESTS echo ;; *) echo "${num_expected_failures} expected test case failures:" echo ${SED} -e 's/^/ /' < "${tests_dir}"/EXPECTED_FAILED_TESTS echo ;; esac num_unexpected_failures=$(wc -l < "${tests_dir}"/UNEXPECTED_FAILED_TESTS) case "${num_unexpected_failures}" in 0) ;; 1) echo "one unexpected test case failure:" echo ${SED} -e 's/^/ /' < "${tests_dir}"/UNEXPECTED_FAILED_TESTS echo ;; *) echo "${num_unexpected_failures} unexpected test case failures:" echo ${SED} -e 's/^/ /' < "${tests_dir}"/UNEXPECTED_FAILED_TESTS echo ;; esac if test -d TEST_FAILS then datestr=$(date +%F_time_%2H_%2M) cp "${tests_dir}"/UNEXPECTED_FAILED_TESTS \ TEST_FAILS/"${test_grade}_${datestr}" fi fi if test "${exitstatus}" = "0" then echo "SUCCESSFUL EXIT" fi echo "-----------------------------------------------------------------------" echo "finishing at $(date ${date_opts})" exit ${exitstatus} #-----------------------------------------------------------------------------#