#
# Copyright (c) 2012, 2023, 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.
#

################################################################################
# This is the bootstrapping part of the build. This file is included from the
# top level Makefile, and is responsible for launching the Main.gmk file with
# the proper make and the proper make arguments.
################################################################################

# This must be the first rule
default:
.PHONY: default

# Inclusion of this pseudo-target will cause make to execute this file
# serially, regardless of -j.
.NOTPARALLEL:

ifeq ($(HAS_SPEC),)
  ##############################################################################
  # This is the default mode. We have not been recursively called with a SPEC.
  ##############################################################################

  # Include our helper functions.
  include $(topdir)/make/InitSupport.gmk

  # Here are "global" targets, i.e. targets that can be executed without having
  # a configuration. This will define ALL_GLOBAL_TARGETS.
  include $(topdir)/make/Global.gmk

  # Targets provided by Init.gmk.
  ALL_INIT_TARGETS := print-modules print-targets print-configuration \
      print-tests reconfigure pre-compare-build post-compare-build

  # CALLED_TARGETS is the list of targets that the user provided,
  # or "default" if unspecified.
  CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default)

  # Extract non-global targets that require a spec file.
  CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS))

  # If we have only global targets, or if we are called with -qp (assuming an
  # external part, e.g. bash completion, is trying to understand our targets),
  # we will skip SPEC location and the sanity checks.
  ifeq ($(CALLED_SPEC_TARGETS), )
    ONLY_GLOBAL_TARGETS := true
  endif
  ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq)
    ONLY_GLOBAL_TARGETS := true
  endif

  ifeq ($(ONLY_GLOBAL_TARGETS), true)
    ############################################################################
    # We have only global targets, or are called with -pq.
    ############################################################################

    ifeq ($(wildcard $(SPEC)), )
      # If we have no SPEC provided, we will just make a "best effort" target list.
      # First try to grab any available pre-existing main-targets.gmk.
      main_targets_file := $(firstword $(wildcard $(build_dir)/*/make-support/main-targets.gmk))
      ifneq ($(main_targets_file), )
        # Extract the SPEC that corresponds to this main-targets.gmk file.
        SPEC := $(patsubst %/make-support/main-targets.gmk, %/spec.gmk, $(main_targets_file))
      else
        # None found, pick an arbitrary SPEC for which to generate a file
        SPEC := $(firstword $(all_spec_files))
      endif
    endif

    ifneq ($(wildcard $(SPEC)), )
      $(eval $(call DefineMainTargets, LAZY, $(SPEC)))
    else
      # If we have no configurations we can not provide any main targets.
      ALL_MAIN_TARGETS :=
    endif

    ALL_TARGETS := $(sort $(ALL_GLOBAL_TARGETS) $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS))

    # Just list all our targets.
    $(ALL_TARGETS):

    .PHONY: $(ALL_TARGETS)

  else
    ############################################################################
    # This is the normal case, we have been called from the command line by the
    # user and we need to call ourself back with a proper SPEC.
    # We have at least one non-global target, so we need to find a spec file.
    ############################################################################

    # Basic checks on environment and command line.
    $(eval $(call CheckControlVariables))
    $(eval $(call CheckDeprecatedEnvironment))
    $(eval $(call CheckInvalidMakeFlags))

    # Check that CONF_CHECK is valid.
    $(eval $(call ParseConfCheckOption))

    # Check that the LOG given is valid, and set LOG_LEVEL, LOG_NOFILE, MAKE_LOG_VARS and MAKE_LOG_FLAGS.
    $(eval $(call ParseLogLevel))

    # After this SPECS contain 1..N spec files (otherwise ParseConfAndSpec fails).
    $(eval $(call ParseConfAndSpec))

    # Extract main targets from Main.gmk using the spec(s) provided. In theory,
    # with multiple specs, we should find the intersection of targets provided
    # by all specs, but we approximate this by an arbitrary spec from the list.
    # This will setup ALL_MAIN_TARGETS.
    $(eval $(call DefineMainTargets, FORCE, $(firstword $(SPECS))))

    # Separate called targets depending on type.
    INIT_TARGETS := $(filter $(ALL_INIT_TARGETS), $(CALLED_SPEC_TARGETS))
    MAIN_TARGETS := $(filter $(ALL_MAIN_TARGETS), $(CALLED_SPEC_TARGETS))
    SEQUENTIAL_TARGETS := $(filter dist-clean clean%, $(MAIN_TARGETS))
    PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_TARGETS))

    # The spec files depend on the autoconf source code. This check makes sure
    # the configuration is up to date after changes to configure.
    $(SPECS): $(wildcard $(topdir)/make/autoconf/*) \
            $(if $(CUSTOM_CONFIG_DIR), $(wildcard $(CUSTOM_CONFIG_DIR)/*)) \
            $(addprefix $(topdir)/make/conf/, version-numbers.conf branding.conf) \
            $(if $(CUSTOM_CONF_DIR), $(wildcard $(addprefix $(CUSTOM_CONF_DIR)/, \
                version-numbers.conf branding.conf)))
        ifeq ($(CONF_CHECK), fail)
	  @echo Error: The configuration is not up to date for \
	      "'$(lastword $(subst /, , $(dir $@)))'."
	  $(call PrintConfCheckFailed)
	  @exit 2
        else ifeq ($(CONF_CHECK), auto)
	  @echo Note: The configuration is not up to date for \
	      "'$(lastword $(subst /, , $(dir $@)))'."
	  @( cd $(topdir) && \
	      $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \
	      SPEC=$@ HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
	      reconfigure )
        else ifeq ($(CONF_CHECK), ignore)
          # Do nothing
        endif

    # Do not let make delete spec files even if aborted while doing a reconfigure
    .PRECIOUS: $(SPECS)

    # Unless reconfigure is explicitly called, let all main targets depend on
    # the spec files to be up to date.
    ifeq ($(findstring reconfigure, $(INIT_TARGETS)), )
      $(MAIN_TARGETS): $(SPECS)
    endif

    make-info:
        ifneq ($(findstring $(LOG_LEVEL),info debug trace),)
	  $(info Running make as '$(strip $(MAKE) $(MFLAGS) \
	      $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))')
        endif

    MAKE_INIT_WITH_SPEC_ARGUMENTS := ACTUAL_TOPDIR=$(topdir) \
        USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \
        $(MAKE_LOG_VARS) \
        INIT_TARGETS="$(INIT_TARGETS)" \
        SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \
        PARALLEL_TARGETS="$(PARALLEL_TARGETS)"

    # Now the init and main targets will be called, once for each SPEC. The
    # recipe will be run once for every target specified, but we only want to
    # execute the recipe a single time, hence the TARGET_DONE with a dummy
    # command if true.
    # The COMPARE_BUILD part implements special support for makefile development.
    $(ALL_INIT_TARGETS) $(ALL_MAIN_TARGETS): make-info
	@$(if $(TARGET_DONE), \
	  true \
	, \
	  ( cd $(topdir) && \
	  $(foreach spec, $(SPECS), \
	    $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \
	        SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \
	        main && \
	    $(if $(and $(COMPARE_BUILD), $(PARALLEL_TARGETS)), \
	        $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \
	            SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
	            COMPARE_BUILD="$(COMPARE_BUILD)" pre-compare-build && \
	        $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \
	            SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \
	            COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" main && \
	        $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \
	            SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
	            COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" post-compare-build && \
	    ) \
	  ) true ) \
	  $(eval TARGET_DONE=true) \
	)

    .PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS)

  endif # $(ONLY_GLOBAL_TARGETS)!=true

else # HAS_SPEC=true

  ##############################################################################
  # Now we have a spec. This part provides the "main" target that acts as a
  # trampoline to call the Main.gmk with the value of $(MAKE) found in the spec
  # file.
  ##############################################################################

  include $(SPEC)

  # Our helper functions.
  include $(TOPDIR)/make/InitSupport.gmk

  # Parse COMPARE_BUILD (for makefile development)
  $(eval $(call ParseCompareBuild))

  # Setup reproducible build environment
  $(eval $(call SetupReproducibleBuild))

  # If no LOG= was given on command line, but we have a non-standard default
  # value, use that instead and re-parse log level.
  ifeq ($(LOG), )
    ifneq ($(DEFAULT_LOG), )
      override LOG := $(DEFAULT_LOG)
      $(eval $(call ParseLogLevel))
    endif
  endif

  ifeq ($(LOG_NOFILE), true)
    # Disable build log if LOG=[level,]nofile was given
    override BUILD_LOG_PIPE :=
    override BUILD_LOG_PIPE_SIMPLE :=
  endif

  ifeq ($(filter dist-clean, $(SEQUENTIAL_TARGETS)), dist-clean)
    # We can't have a log file if we're about to remove it.
    override BUILD_LOG_PIPE :=
    override BUILD_LOG_PIPE_SIMPLE :=
  endif

  ifeq ($(OUTPUT_SYNC_SUPPORTED), true)
    OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC)
  endif

  ##############################################################################
  # Init targets
  ##############################################################################

  print-modules:
	( cd $(TOPDIR) && \
	    $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
	    NO_RECIPES=true print-modules )

  print-targets:
	( cd $(TOPDIR) && \
	    $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
	    NO_RECIPES=true print-targets )

  print-tests:
	( cd $(TOPDIR) && \
	    $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
	    NO_RECIPES=true print-tests )

  print-configuration:
	  $(ECHO) $(CONFIGURE_COMMAND_LINE)

  reconfigure:
        ifneq ($(REAL_CONFIGURE_COMMAND_EXEC_FULL), )
	  $(ECHO) "Re-running configure using original command line '$(REAL_CONFIGURE_COMMAND_EXEC_SHORT) $(REAL_CONFIGURE_COMMAND_LINE)'"
	  $(eval RECONFIGURE_COMMAND := $(REAL_CONFIGURE_COMMAND_EXEC_FULL) $(REAL_CONFIGURE_COMMAND_LINE))
        else ifneq ($(CONFIGURE_COMMAND_LINE), )
	  $(ECHO) "Re-running configure using arguments '$(CONFIGURE_COMMAND_LINE)'"
	  $(eval RECONFIGURE_COMMAND := $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE))
        else
	  $(ECHO) "Re-running configure using default settings"
	  $(eval RECONFIGURE_COMMAND := $(BASH) $(TOPDIR)/configure)
        endif
	( cd $(CONFIGURE_START_DIR) && PATH="$(ORIGINAL_PATH)" AUTOCONF="$(AUTOCONF)" \
	    CUSTOM_ROOT="$(CUSTOM_ROOT)" \
	    CUSTOM_CONFIG_DIR="$(CUSTOM_CONFIG_DIR)" \
	    $(RECONFIGURE_COMMAND) )

  ##############################################################################
  # The main target, for delegating into Main.gmk
  ##############################################################################

  MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE)
  # If building the default target, add what they are to the description.
  DESCRIPTION_TARGETS := $(strip $(MAIN_TARGETS))
  ifeq ($(DESCRIPTION_TARGETS), default)
    DESCRIPTION_TARGETS += ($(DEFAULT_MAKE_TARGET))
  endif
  TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \
      '$(strip $(DESCRIPTION_TARGETS))' in configuration '$(CONF_NAME)'

  # MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls.
  # We need to clear it of the init-specific variables. The user-specified
  # variables are explicitly propagated using $(USER_MAKE_VARS).
  main: MAKEOVERRIDES :=

  main: $(INIT_TARGETS)
        ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), )
	  $(call RotateLogFiles)
	  $(PRINTF) "Building $(TARGET_DESCRIPTION)\n" $(BUILD_LOG_PIPE_SIMPLE)
          ifneq ($(SEQUENTIAL_TARGETS), )
            # Don't touch build output dir since we might be cleaning. That
            # means no log pipe.
	    ( cd $(TOPDIR) && \
	        $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \
	        $(SEQUENTIAL_TARGETS) )
          endif
          ifneq ($(PARALLEL_TARGETS), )
	    $(call PrepareFailureLogs)
	    $(call StartGlobalTimer)
	    $(call PrepareJavacServer)
            # JOBS will only be empty for a bootcycle-images recursive call
            # or if specified via a make argument directly. In those cases
            # treat it as NOT using jobs at all.
	    ( cd $(TOPDIR) && \
	        $(NICE) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \
                    $(if $(JOBS), -j $(JOBS)) \
	            -f make/Main.gmk $(USER_MAKE_VARS) \
	            $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) $(BUILD_LOG_PIPE) || \
	        ( exitcode=$$? && \
	        $(PRINTF) "\nERROR: Build failed for $(TARGET_DESCRIPTION) (exit code $$exitcode) \n" \
	            $(BUILD_LOG_PIPE_SIMPLE) && \
	        cd $(TOPDIR) && $(MAKE) $(MAKE_ARGS) -j 1 -f make/Init.gmk \
	            HAS_SPEC=true on-failure ; \
	        exit $$exitcode ) )
	    $(call CleanupJavacServer)
	    $(call StopGlobalTimer)
	    $(call ReportBuildTimes)
          endif
	  if test -f $(MAKESUPPORT_OUTPUTDIR)/exit-with-error ; then \
	    exit 1 ; \
	  fi
	  $(PRINTF) "Finished building $(TARGET_DESCRIPTION)\n" $(BUILD_LOG_PIPE_SIMPLE)
	  $(call ReportProfileTimes)
        endif

    on-failure:
	$(call CleanupJavacServer)
	$(call StopGlobalTimer)
	$(call ReportBuildTimes)
	$(call PrintFailureReports)
	$(call PrintBuildLogFailures)
	$(call ReportProfileTimes)
	$(PRINTF) "HELP: Run 'make doctor' to diagnose build problems.\n\n"
        ifneq ($(COMPARE_BUILD), )
	  $(call CleanupCompareBuild)
        endif

    # Support targets for COMPARE_BUILD, used for makefile development
    pre-compare-build:
	$(call WaitForJavacServerFinish)
	$(call PrepareCompareBuild)

    post-compare-build:
	$(call WaitForJavacServerFinish)
	$(call CleanupCompareBuild)
	$(call CompareBuildDoComparison)

  .PHONY: print-targets print-modules reconfigure main on-failure
endif
