#
# Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.  Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#

###
### Global targets for printing help etc.
###

# Helper macro to allow $(info) to properly print strings beginning with spaces.
_:=

help:
	$(info )
	$(info OpenJDK Makefile help)
	$(info =====================)
	$(info )
	$(info Common make targets)
	$(info $(_) make [default]         # Compile all modules and create a runnable "exploded")
	$(info $(_)                        # image (alias for jdk or exploded-image))
	$(info $(_) make all               # Create all images: product, test, docs)
	$(info $(_)                        # (alias for all-images))
	$(info $(_) make images            # Create a complete jdk image)
	$(info $(_)                        # (alias for product-images))
	$(info $(_) make <name>-image      # Build just the image for any of: )
	$(info $(_)                        # jdk, test, docs, symbols, legacy-jre, static-libs)
	$(info $(_) make <phase>           # Build the specified phase and everything it depends on)
	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata))
	$(info $(_) make *-only            # Applies to most targets and disables building the)
	$(info $(_)                        # dependencies for that target. This is faster but may)
	$(info $(_)                        # result in incorrect build results!)
	$(info $(_) make docs              # Create all docs)
	$(info $(_) make docs-jdk-api      # Create just JDK javadocs)
	$(info $(_) make bootcycle-images  # Build images twice, second time with newly built JDK)
	$(info $(_) make install           # Install the generated images locally)
	$(info $(_) make check             # Run basic testing (currently tier1))
	$(info $(_) make test-<test>       # Run test, e.g. test-tier1)
	$(info $(_) make test TEST=<t>     # Run test(s) given by TEST specification)
	$(info $(_) make exploded-test TEST=<t> # Run test(s) on the exploded image instead of)
	$(info $(_)                        # the full jdk image)
	$(info )
	$(info Targets for troubleshooting)
	$(info $(_) make help              # Give some help on using make)
	$(info $(_) make doctor            # Diagnose build environment problems)
	$(info $(_) make reconfigure       # Rerun configure with the same arguments as last time)
	$(info )
	$(info Targets for cleaning)
	$(info $(_) make clean             # Remove all files generated by make, but not those)
	$(info $(_)                        # generated by configure)
	$(info $(_) make dist-clean        # Remove all files, including configuration)
	$(info $(_) make clean-<outputdir> # Remove the subdir in the output dir with the name)
	$(info $(_) make clean-<phase>     # Remove all build results related to a certain build)
	$(info $(_)                        # phase (gensrc, java, libs, launchers))
	$(info $(_) make clean-<module>    # Remove all build results related to a certain module)
	$(info $(_) make clean-<module>-<phase> # Remove all build results related to a certain)
	$(info $(_)                        # module and phase)
	$(info )
	$(info Targets for Hotspot)
	$(info $(_) make hotspot           # Build all of hotspot)
	$(info $(_) make hotspot-<variant> # Build just the specified jvm variant)
	$(info $(_) make hotspot-gensrc    # Only build the gensrc part of hotspot)
	$(info $(_) make hotspot-<variant>-<phase> # Build the specified phase for the variant)
	$(info )
	$(info Targets for specific modules)
	$(info $(_) make <module>          # Build <module> and everything it depends on)
	$(info $(_) make <module>-<phase>  # Compile the specified phase for the specified module)
	$(info $(_)                        # and everything it depends on)
	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata))
	$(info )
	$(info Make control variables)
	$(info $(_) CONF=                  # Build all configurations (note, assignment is empty))
	$(info $(_) CONF=<substring>       # Build the configuration(s) with a name matching)
	$(info $(_)                        # <substring>)
	$(info $(_) CONF_NAME=<string>     # Build the configuration with exactly the <string>)
	$(info $(_) SPEC=<spec file>       # Build the configuration given by the spec file)
	$(info $(_) LOG=<loglevel>         # Change the log level from warn to <loglevel>)
	$(info $(_)                        # Available log levels are:)
	$(info $(_)                        # 'warn' (default), 'info', 'debug' and 'trace')
	$(info $(_)                        # To see executed command lines, use LOG=debug)
	$(info $(_) JOBS=<n>               # Run <n> parallel make jobs)
	$(info $(_)                        # Note that -jN does not work as expected!)
	$(info $(_) TEST_JOBS=<n>          # Run <n> parallel test jobs)
	$(info $(_) CONF_CHECK=<method>    # What to do if spec file is out of date)
	$(info $(_)                        # method is 'auto', 'ignore' or 'fail' (default))
	$(info $(_) TEST="test1 ..."       # Use the given test descriptor(s) for testing, e.g.)
	$(info $(_)                        # make test TEST="jdk_lang gtest:all")
	$(info $(_) JTREG="OPT1=x;OPT2=y"  # Control the JTREG test harness, use 'help' to list)
	$(info $(_) GTEST="OPT1=x;OPT2=y"  # Control the GTEST test harness, use 'help' to list)
	$(info $(_) MICRO="OPT1=x;OPT2=y"  # Control the MICRO test harness, use 'help' to list)
	$(info $(_) TEST_OPTS="OPT1=x;..." # Generic control of all test harnesses)
	$(info $(_) TEST_VM_OPTS="ARG ..." # Same as setting TEST_OPTS to VM_OPTIONS="ARG ...")
	$(info )
	$(if $(all_confs), $(info Available configurations in $(build_dir):) $(foreach var,$(all_confs),$(info * $(var))),\
	    $(info No configurations were found in $(build_dir).) $(info Run 'bash configure' to create a configuration.))
        # We need a dummy rule otherwise make will complain
	@true

print-configurations:
	$(foreach var, $(all_confs), $(info $(var)))
        # We need a dummy rule otherwise make will complain
	@true

test-prebuilt:
	@( cd $(topdir) && \
	    $(MAKE) --no-print-directory -r -R -I make/common/ -f make/RunTestsPrebuilt.gmk \
	    test-prebuilt CUSTOM_MAKE_DIR=$(CUSTOM_MAKE_DIR) TEST="$(TEST)" )

test-prebuilt-with-exit-code:
	@( cd $(topdir) && \
	    $(MAKE) --no-print-directory -r -R -I make/common/ -f make/RunTestsPrebuilt.gmk \
	    test-prebuilt-with-exit-code CUSTOM_MAKE_DIR=$(CUSTOM_MAKE_DIR) TEST="$(TEST)" )

# Alias for backwards compatibility
run-test-prebuilt: test-prebuilt

ALL_GLOBAL_TARGETS := help print-configurations test-prebuilt run-test-prebuilt

.PHONY: $(ALL_GLOBAL_TARGETS)
