build: unify verbosity handling

This change introduces a few helper variables for dealing with verbose
and silent build modes: `silent`, `verbose`, `q` and `s`.

The `silent` and `verbose` variables are boolean values determining
whether the build system has been configured to run silently or
verbosely respectively (i.e. with `--silent` or `V=1`).

These two modes cannot be used together - if `silent` is truthy then
`verbose` is always falsy. As such:

    make --silent V=1

... results in a silent build.

In addition to these boolean variables, we also introduce two new
variables - `s` and `q` - for use in rule recipes to conditionally
suppress the output of commands.

When building silently, `s` expands to a value which disables the
command that follows, and `q` expands to a value which supppresses
echoing of the command:

    $(s)echo 'This command is neither echoed nor executed'
    $(q)echo 'This command is executed but not echoed'

When building verbosely, `s` expands to a value which disables the
command that follows, and `q` expands to nothing:

    $(s)echo 'This command is neither echoed nor executed'
    $(q)echo 'This command is executed and echoed'

In all other cases, both `s` and `q` expand to a value which suppresses
echoing of the command that follows:

    $(s)echo 'This command is executed but not echoed'
    $(q)echo 'This command is executed but not echoed'

The `s` variable is predominantly useful for `echo` commands, where you
always want to suppress echoing of the command itself, whilst `q` is
more useful for all other commands.

Change-Id: I8d8ff6ed714d3cb401946c52955887ed7dca602b
Signed-off-by: Chris Kay <chris.kay@arm.com>
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 9eb9d1e..d27408c 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -148,8 +148,8 @@
 #   $(2) = output encrypted firmware binary
 define ENCRYPT_FW
 $(2): $(1) enctool
-	$$(ECHO) "  ENC     $$<"
-	$$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+	$$(s)echo "  ENC     $$<"
+	$$(q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
 endef
 
 # TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
@@ -267,8 +267,8 @@
 # GZIP
 define GZIP_RULE
 $(1): $(2)
-	$(ECHO) "  GZIP    $$@"
-	$(Q)gzip -n -f -9 $$< --stdout > $$@
+	$(s)echo "  GZIP    $$@"
+	$(q)gzip -n -f -9 $$< --stdout > $$@
 endef
 
 GZIP_SUFFIX := .gz
@@ -290,8 +290,8 @@
 $(eval LIB := $(call uppercase, $(notdir $(1))))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -306,8 +306,8 @@
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  AS      $$<"
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -329,8 +329,8 @@
 $(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -352,8 +352,8 @@
 $(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(s)echo "  AS      $$<"
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -373,8 +373,8 @@
 $(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
 
 $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  PP      $$<"
-	$$(Q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
+	$$(s)echo "  PP      $$<"
+	$$(q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
 
 -include $(DEP)
 
@@ -466,8 +466,8 @@
 all: ${LIB_DIR}/lib$(1).a
 
 ${LIB_DIR}/lib$(1).a: $(OBJS)
-	$$(ECHO) "  AR      $$@"
-	$$(Q)$($(ARCH)-ar) cr $$@ $$?
+	$$(s)echo "  AR      $$@"
+	$$(q)$($(ARCH)-ar) cr $$@ $$?
 endef
 
 # Generate the path to one or more preprocessed linker scripts given the paths
@@ -540,38 +540,38 @@
 $(eval OBJS += $(MODULE_OBJS))
 
 $(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
-	$$(ECHO) "  LD      $$@"
+	$$(s)echo "  LD      $$@"
 ifeq ($($(ARCH)-ld-id),arm-link)
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
 		--predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
 		--predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
 		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
 		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
 else ifeq ($($(ARCH)-ld-id),gnu-gcc)
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
 		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
-	$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
 		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 endif
 
 $(DUMP): $(ELF)
-	$${ECHO} "  OD      $$@"
-	$${Q}$($(ARCH)-od) -dx $$< > $$@
+	$$(s)echo "  OD      $$@"
+	$$(q)$($(ARCH)-od) -dx $$< > $$@
 
 $(BIN): $(ELF)
-	$${ECHO} "  BIN     $$@"
-	$$(Q)$($(ARCH)-oc) -O binary $$< $$@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+	$$(s)echo "  BIN     $$@"
+	$$(q)$($(ARCH)-oc) -O binary $$< $$@
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 
 .PHONY: $(1)
 ifeq ($(DISABLE_BIN_GENERATION),1)
@@ -629,13 +629,13 @@
 $(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
 
 $(DPRE): $(2) | fdt_dirs
-	$${ECHO} "  CPP     $$<"
+	$$(s)echo "  CPP     $$<"
 	$(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-	$$(Q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+	$$(q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
 
 $(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
-	$${ECHO} "  DTC     $$<"
-	$$(Q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
+	$$(s)echo "  DTC     $$<"
+	$$(q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
 
 -include $(DTBDEP)
 -include $(DTSDEP)
diff --git a/make_helpers/common.mk b/make_helpers/common.mk
new file mode 100644
index 0000000..75d9f71
--- /dev/null
+++ b/make_helpers/common.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifndef common-mk
+        common-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(common-mk))utilities.mk
+
+        silent = $(call bool,$(findstring s,$(firstword ~$(MAKEFLAGS))))
+        verbose = $(if $(silent),,$(call bool,$(V)))
+
+        s = @$(if $(or $(verbose),$(silent)),: )
+        q = $(if $(verbose),,@)
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index a5c78ae..368d26d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -294,9 +294,6 @@
 # Use tbbr_oid.h instead of platform_oid.h
 USE_TBBR_DEFS			:= 1
 
-# Build verbosity
-V				:= 0
-
 # Whether to enable D-Cache early during warm boot. This is usually
 # applicable for platforms wherein interconnect programming is not
 # required to enable cache coherency after warm reset (eg: single cluster
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
index 93e1fcc..4fd819a 100644
--- a/make_helpers/unix.mk
+++ b/make_helpers/unix.mk
@@ -9,9 +9,6 @@
 ifndef UNIX_MK
     UNIX_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := echo
-    ECHO_QUIET := @\#
-
     DIR_DELIM := /
     PATH_SEP := :
 
@@ -21,24 +18,24 @@
     # ${1} is the file to be copied.
     # ${2} is the destination file name.
     define SHELL_COPY
-	${Q}cp -f  "${1}"  "${2}"
+	$(q)cp -f  "${1}"  "${2}"
     endef
 
     # ${1} is the directory to be copied.
     # ${2} is the destination directory path.
     define SHELL_COPY_TREE
-	${Q}cp -rf  "${1}"  "${2}"
+	$(q)cp -rf  "${1}"  "${2}"
     endef
 
     # ${1} is the file to be deleted.
     define SHELL_DELETE
-	-${Q}rm -f  "${1}"
+	-$(q)rm -f  "${1}"
     endef
 
     # ${1} is a space delimited list of files to be deleted.
     # Note that we do not quote ${1}, as multiple parameters may be passed.
     define SHELL_DELETE_ALL
-	-${Q}rm -rf  ${1}
+	-$(q)rm -rf  ${1}
     endef
 
     # ${1} is the directory to be generated.
@@ -48,13 +45,13 @@
         ifneq (${1},${2})
 
 ${1} : ${2}
-	${Q}mkdir -p  "${1}"
+	$(q)mkdir -p  "${1}"
 
         endif
     endef
 
     define SHELL_REMOVE_DIR
-	-${Q}rm -rf  "${1}"
+	-$(q)rm -rf  "${1}"
     endef
 
     nul := /dev/null
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index de34eaf..2f5d51b 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -12,8 +12,6 @@
 ifndef WINDOWS_MK
     WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := @cmd /c echo.
-    ECHO_QUIET := @rem
     DIR_DELIM := $(strip \)
     BIN_EXT   := .exe
     PATH_SEP  := ;