1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
#
# Copyright (c) 2012, 2025, 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 file is the earliest part of the build bootstrap process (not counting
# Makefile that includes it). Its main responsibility is to figure out what
# configuration to use and pick up the corresponding SPEC file. It will then
# call Init.gmk with this SPEC for further bootstrapping.
################################################################################
# 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:
IS_PREINIT_ENV := true
# Include our helper functions.
include $(TOPDIR)/make/PreInitSupport.gmk
include $(TOPDIR)/make/common/LogUtils.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 \
create-make-helpers
# 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), )
SKIP_SPEC := true
endif
ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq)
SKIP_SPEC := true
endif
ifneq ($(SKIP_SPEC), true)
############################################################################
# This is the common case: we have been called from the command line by the
# user with a target that should be delegated to Main.gmk, so we need to
# figure out a proper SPEC and call Init.gmk with it.
############################################################################
# Basic checks on environment and command line.
$(eval $(call CheckControlVariables))
$(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))
MAKE_INIT_ARGS := $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -I $(TOPDIR)/make/common
# 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) $(MAKE_INIT_ARGS) -f $(TOPDIR)/make/Init.gmk SPEC=$@ \
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_MAIN_TARGET_ARGS := \
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) $(MAKE_INIT_ARGS) -j 1 -f $(TOPDIR)/make/Init.gmk \
SPEC=$(spec) TOPDIR_ALT=$(TOPDIR) \
$(MAKE_INIT_MAIN_TARGET_ARGS) main && \
$(if $(and $(COMPARE_BUILD), $(PARALLEL_TARGETS)), \
$(MAKE) $(MAKE_INIT_ARGS) -f $(TOPDIR)/make/Init.gmk \
SPEC=$(spec) TOPDIR_ALT=$(TOPDIR) \
COMPARE_BUILD="$(COMPARE_BUILD)" \
pre-compare-build && \
$(MAKE) $(MAKE_INIT_ARGS) -j 1 -f $(TOPDIR)/make/Init.gmk \
SPEC=$(spec) TOPDIR_ALT=$(TOPDIR) \
COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" \
$(MAKE_INIT_MAIN_TARGET_ARGS) main && \
$(MAKE) $(MAKE_INIT_ARGS) -f $(TOPDIR)/make/Init.gmk \
SPEC=$(spec) TOPDIR_ALT=$(TOPDIR) \
COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" \
post-compare-build && \
) \
) true ) \
$(eval TARGET_DONE=true) \
)
.PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS)
else # SKIP_SPEC=true
############################################################################
# We have only global targets, or are called with -pq (from command
# completion). In this case we might not even have a configuration at all, but
# still need to handle the situation gracefully even if there is no SPEC file.
############################################################################
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)
endif # $(SKIP_SPEC)!=true
################################################################################
|