Merge pull request #578 from EvanLloyd/ejll/woa_make2

Make improvements for host environment portability
diff --git a/.gitignore b/.gitignore
index cc5cbfb..7447227 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,12 @@
 # Ignore build products from tools
 tools/**/*.o
 tools/fip_create/fip_create
+tools/fip_create/fip_create.exe
 tools/cert_create/src/*.o
 tools/cert_create/src/**/*.o
 tools/cert_create/cert_create
+tools/cert_create/cert_create.exe
+
+# Ignore header files copied.
+tools/fip_create/firmware_image_package.h
+tools/fip_create/uuid.h
diff --git a/Makefile b/Makefile
index d7a7a36..b2ca916 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,9 @@
 # Default goal is build all images
 .DEFAULT_GOAL			:= all
 
-include make_helpers/build_macros.mk
+MAKE_HELPERS_DIRECTORY := make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
 ################################################################################
 # Default values for build configurations
@@ -111,9 +113,10 @@
 CHECKPATCH_ARGS		:=	--no-tree --no-signoff ${CHECK_IGNORE}
 CHECKCODE_ARGS		:=	--no-patch --no-tree --no-signoff ${CHECK_IGNORE}
 # Do not check the coding style on C library files
-CHECK_PATHS		:=	$(shell ls -I include -I lib) \
-				$(addprefix include/,$(shell ls -I stdlib include)) \
-				$(addprefix lib/,$(shell ls -I stdlib lib))
+INCLUDE_DIRS_TO_CHECK	:=	$(sort $(filter-out include/stdlib, $(wildcard include/*)))
+LIB_DIRS_TO_CHECK	:=	$(sort $(filter-out lib/stdlib, $(wildcard lib/*)))
+ROOT_DIRS_TO_CHECK	:=	$(sort $(filter-out lib include, $(wildcard *))))
+CHECK_PATHS		:=	${ROOT_DIRS_TO_CHECK} ${INCLUDE_DIRS_TO_CHECK} ${LIB_DIRS_TO_CHECK}
 
 
 ################################################################################
@@ -122,10 +125,10 @@
 
 # Verbose flag
 ifeq (${V},0)
-        Q=@
+        Q:=@
         CHECKCODE_ARGS	+=	--no-summary --terse
 else
-        Q=
+        Q:=
 endif
 export Q
 
@@ -234,17 +237,12 @@
 # Generic definitions
 ################################################################################
 
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
 BUILD_BASE		:=	./build
 BUILD_PLAT		:=	${BUILD_BASE}/${PLAT}/${BUILD_TYPE}
 
-PLAT_MAKEFILE		:=	platform.mk
-# Generate the platforms list by recursively searching for all directories
-# under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
-# char and strip out the final '|'.
-PLATFORMS		:=	$(shell find plat/ -name '${PLAT_MAKEFILE}' -print0 |			\
-					sed -r 's%[^\x00]*\/([^/]*)\/${PLAT_MAKEFILE}\x00%\1|%g' |	\
-					sed -r 's/\|$$//')
-SPDS			:=	$(shell ls -I none services/spd)
+SPDS			:=	$(sort $(filter-out none, $(patsubst services/spd/%,%,$(wildcard services/spd/*))))
 
 # Platforms providing their own TBB makefile may override this value
 INCLUDE_TBBR_MK		:=	1
@@ -260,7 +258,7 @@
         $(warning "The SPD and its BL32 companion will be present but ignored.")
 endif
         # We expect to locate an spd.mk under the specified SPD directory
-        SPD_MAKE	:=	$(shell m="services/spd/${SPD}/${SPD}.mk"; [ -f "$$m" ] && echo "$$m")
+        SPD_MAKE	:=	$(wildcard services/spd/${SPD}/${SPD}.mk)
 
         ifeq (${SPD_MAKE},)
                 $(error Error: No services/spd/${SPD}/${SPD}.mk located)
@@ -285,14 +283,6 @@
 # makefile may use all previous definitions in this file)
 ################################################################################
 
-ifeq (${PLAT},)
-        $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
-endif
-PLAT_MAKEFILE_FULL	:=	$(shell find plat/ -wholename '*/${PLAT}/${PLAT_MAKEFILE}')
-ifeq ($(PLAT_MAKEFILE_FULL),)
-        $(error "Error: Invalid platform. The following platforms are available: ${PLATFORMS}")
-endif
-
 include ${PLAT_MAKEFILE_FULL}
 
 # If the platform has not defined ENABLE_PLAT_COMPAT, then enable it by default
@@ -386,11 +376,11 @@
 
 # Variables for use with Certificate Generation Tool
 CRTTOOLPATH		?=	tools/cert_create
-CRTTOOL			?=	${CRTTOOLPATH}/cert_create
+CRTTOOL			?=	${CRTTOOLPATH}/cert_create${BIN_EXT}
 
 # Variables for use with Firmware Image Package
 FIPTOOLPATH		?=	tools/fip_create
-FIPTOOL			?=	${FIPTOOLPATH}/fip_create
+FIPTOOL			?=	${FIPTOOLPATH}/fip_create${BIN_EXT}
 
 
 ################################################################################
@@ -545,14 +535,14 @@
 
 clean:
 	@echo "  CLEAN"
-	${Q}rm -rf ${BUILD_PLAT}
+	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
 	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
 
 realclean distclean:
 	@echo "  REALCLEAN"
-	${Q}rm -rf ${BUILD_BASE}
-	${Q}rm -f ${CURDIR}/cscope.*
+	$(call SHELL_REMOVE_DIR,${BUILD_BASE})
+	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
 	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
 
@@ -573,24 +563,24 @@
 .PHONY: ${CRTTOOL}
 ${CRTTOOL}:
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH}
-	@echo
+	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
-	@echo
+	@${ECHO_BLANK_LINE}
 
 ifneq (${GENERATE_COT},0)
 certificates: ${CRT_DEPS} ${CRTTOOL}
 	${Q}${CRTTOOL} ${CRT_ARGS}
-	@echo
+	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@echo "Certificates can be found in ${BUILD_PLAT}"
-	@echo
+	@${ECHO_BLANK_LINE}
 endif
 
 ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL}
 	${Q}${FIPTOOL} --dump ${FIP_ARGS} $@
-	@echo
+	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
-	@echo
+	@${ECHO_BLANK_LINE}
 
 ifneq (${GENERATE_COT},0)
 fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL}
@@ -621,7 +611,7 @@
 	${Q}cscope -b -q -k
 
 help:
-	@echo "usage: ${MAKE} PLAT=<${PLATFORMS}> [OPTIONS] [TARGET]"
+	@echo "usage: ${MAKE} PLAT=<${PLATFORM_LIST}> [OPTIONS] [TARGET]"
 	@echo ""
 	@echo "PLAT is used to specify which platform you wish to build."
 	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index 9919fe4..a502428 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -52,8 +52,8 @@
 # Include the platform-specific TSP Makefile
 # If no platform-specific TSP Makefile exists, it means TSP is not supported
 # on this platform.
-TSP_PLAT_MAKEFILE := $(shell find plat/ -wholename '*/${PLAT}/tsp/tsp-${PLAT}.mk')
-ifeq (,$(wildcard ${TSP_PLAT_MAKEFILE}))
+TSP_PLAT_MAKEFILE := $(wildcard ${PLAT_DIR}/tsp/tsp-${PLAT}.mk)
+ifeq (,${TSP_PLAT_MAKEFILE})
   $(error TSP is not supported on platform ${PLAT})
 else
   include ${TSP_PLAT_MAKEFILE}
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 37e2034..8d7376d 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -42,6 +42,9 @@
 building the software were installed from that distribution unless otherwise
 specified.
 
+The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
+Cygwin, and Msys (MinGW) shells, using version 4.9.1 of the GNU toolchain.
+
 3.  Tools
 ---------
 
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
new file mode 100644
index 0000000..62c7f68
--- /dev/null
+++ b/make_helpers/build_env.mk
@@ -0,0 +1,96 @@
+#
+#  Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions are met:
+#
+#  Redistributions of source code must retain the above copyright notice, this
+#  list of conditions and the following disclaimer.
+#
+#  Redistributions in binary form must reproduce the above copyright notice,
+#  this list of conditions and the following disclaimer in the documentation
+#  and/or other materials provided with the distribution.
+#
+#  Neither the name of ARM nor the names of its contributors may be used
+#  to endorse or promote products derived from this software without specific
+#  prior written permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#  POSSIBILITY OF SUCH DAMAGE.
+#
+
+# This file contains the logic to identify and include any relevant
+# build environment specific make include files.
+
+ifndef BUILD_ENV_MK
+    BUILD_ENV_MK        :=      $(lastword $(MAKEFILE_LIST))
+
+    # Block possible built-in command definitions that are not fully portable.
+    # This traps occurences that need replacing with our OS portable macros
+    COPY                :=      $$(error "Replace COPY with call to SHELL_COPY or SHELL_COPY_TREE.")
+    CP                  :=      $$(error "Replace CP with call to SHELL_COPY or SHELL_COPY_TREE.")
+    DEL                 :=      $$(error "Replace DEL with call to SHELL_DELETE.")
+    MD                  :=      $$(error "Replace MD with call to MAKE_PREREQ_DIR.")
+    MKDIR               :=      $$(error "Replace MKDIR with call to MAKE_PREREQ_DIR.")
+    RD                  :=      $$(error "Replace RD with call to SHELL_REMOVE_DIR.")
+    RM                  :=      $$(error "Replace RM with call to SHELL_DELETE.")
+    RMDIR               :=      $$(error "Replace RMDIR with call to SHELL_REMOVE_DIR.")
+
+    ENV_FILE_TO_INCLUDE := unix.mk
+    ifdef OSTYPE
+        ifneq ($(findstring ${OSTYPE}, cygwin),)
+            ENV_FILE_TO_INCLUDE := cygwin.mk
+        else
+            ifneq ($(findstring ${OSTYPE}, MINGW32 mingw msys),)
+                ENV_FILE_TO_INCLUDE := msys.mk
+            endif
+        endif
+    else
+        ifdef MSYSTEM
+            # Although the MINGW MSYS shell sets OSTYPE as msys in its environment,
+            # it does not appear in the GNU make view of environment variables.
+            # We use MSYSTEM as an alternative, as that is seen by make
+            ifneq ($(findstring ${MSYSTEM}, MINGW32 mingw msys),)
+                OSTYPE ?= msys
+                ENV_FILE_TO_INCLUDE := msys.mk
+            endif
+        else
+            ifdef OS
+                ifneq ($(findstring ${OS}, Windows_NT),)
+                    ENV_FILE_TO_INCLUDE := windows.mk
+                endif
+            endif
+        endif
+    endif
+    include ${MAKE_HELPERS_DIRECTORY}${ENV_FILE_TO_INCLUDE}
+    ENV_FILE_TO_INCLUDE :=
+
+    ifndef SHELL_COPY
+        $(error "SHELL_COPY not defined for build environment.")
+    endif
+    ifndef SHELL_COPY_TREE
+        $(error "SHELL_COPY_TREE not defined for build environment.")
+    endif
+    ifndef SHELL_DELETE_ALL
+        $(error "SHELL_DELETE_ALL not defined for build environment.")
+    endif
+    ifndef SHELL_DELETE
+        $(error "SHELL_DELETE not defined for build environment.")
+    endif
+    ifndef MAKE_PREREQ_DIR
+        $(error "MAKE_PREREQ_DIR not defined for build environment.")
+    endif
+    ifndef SHELL_REMOVE_DIR
+        $(error "SHELL_REMOVE_DIR not defined for build environment.")
+    endif
+
+endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index b22eaf9..5171ff0 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -28,6 +28,23 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
+# Report an error if the eval make function is not available.
+$(eval eval_available := T)
+ifneq (${eval_available},T)
+    $(error This makefile only works with a Make program that supports $$(eval))
+endif
+
+# Some utility macros for manipulating awkward (whitespace) characters.
+blank			:=
+space			:=${blank} ${blank}
+
+# A user defined function to recursively search for a filename below a directory
+#    $1 is the directory root of the recursive search (blank for current directory).
+#    $2 is the file name to search for.
+define rwildcard
+$(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
+endef
+
 # This table is used in converting lower case to upper case.
 uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
 
@@ -193,10 +210,8 @@
 	@echo "  CC      $$<"
 	$$(Q)$$(CC) $$(CFLAGS) -D$(IMAGE) -c $$< -o $$@
 
-
-$(PREREQUISITES): $(2)
+$(PREREQUISITES): $(2) | bl$(3)_dirs
 	@echo "  DEPS    $$@"
-	@mkdir -p $(1)
 	$$(Q)$$(CC) $$(CFLAGS) -M -MT $(OBJ) -MF $$@ $$<
 
 ifdef IS_ANYTHING_TO_BUILD
@@ -220,9 +235,8 @@
 	@echo "  AS      $$<"
 	$$(Q)$$(AS) $$(ASFLAGS) -D$(IMAGE) -c $$< -o $$@
 
-$(PREREQUISITES): $(2)
+$(PREREQUISITES): $(2) | bl$(3)_dirs
 	@echo "  DEPS    $$@"
-	@mkdir -p $(1)
 	$$(Q)$$(AS) $$(ASFLAGS) -M -MT $(OBJ) -MF $$@ $$<
 
 ifdef IS_ANYTHING_TO_BUILD
@@ -243,9 +257,8 @@
 	@echo "  PP      $$<"
 	$$(Q)$$(AS) $$(ASFLAGS) -P -E -D__LINKER__ -o $$@ $$<
 
-$(PREREQUISITES): $(2)
+$(PREREQUISITES): $(2) | $(dir ${1})
 	@echo "  DEPS    $$@"
-	@mkdir -p $$(dir $$@)
 	$$(Q)$$(AS) $$(ASFLAGS) -M -MT $(1) -MF $$@ $$<
 
 ifdef IS_ANYTHING_TO_BUILD
@@ -274,7 +287,7 @@
 
 # NOTE: The line continuation '\' is required in the next define otherwise we
 # end up with a line-feed characer at the end of the last c filename.
-# Also bare this issue in mind if extending the list of supported filetypes.
+# Also bear this issue in mind if extending the list of supported filetypes.
 define SOURCES_TO_OBJS
         $(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
         $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
@@ -310,18 +323,36 @@
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
         $(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
+        # We use sort only to get a list of unique object directory names.
+        # ordering is not relevant but sort removes duplicates.
+        $(eval TEMP_OBJ_DIRS := $(sort $(BUILD_DIR)/ $(dir ${OBJS})))
+        # The $(dir ) function leaves a trailing / on the directory names
+        # We append a . then strip /. from each, to remove the trailing / characters
+        # This gives names suitable for use as make rule targets.
+        $(eval OBJ_DIRS   := $(subst /.,,$(addsuffix .,$(TEMP_OBJ_DIRS))))
+
+# Create generators for object directory structure
 
-        $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
-        $(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE)))
+$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},)))
 
-$(BUILD_DIR):
-	$$(Q)mkdir -p "$$@"
+.PHONY : bl${1}_dirs
 
-$(ELF): $(OBJS) $(LINKERFILE)
+# We use order-only prerequisites to ensure that directories are created,
+# but do not cause re-builds every time a file is written.
+bl${1}_dirs: | ${OBJ_DIRS}
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE)))
+
+$(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs
 	@echo "  LD      $$@"
+ifdef MAKE_BUILD_STRINGS
+	$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
+else
 	@echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \
 	       const char version_string[] = "${VERSION_STRING}";' | \
 		$$(CC) $$(CFLAGS) -xc - -o $(BUILD_DIR)/build_message.o
+endif
 	$$(Q)$$(LD) -o $$@ $$(LDFLAGS) -Map=$(MAPFILE) --script $(LINKERFILE) \
 					$(BUILD_DIR)/build_message.o $(OBJS)
 
@@ -337,7 +368,7 @@
 	@echo
 
 .PHONY: bl$(1)
-bl$(1): $(BUILD_DIR) $(BIN) $(DUMP)
+bl$(1): $(BIN) $(DUMP)
 
 all: bl$(1)
 
diff --git a/make_helpers/cygwin.mk b/make_helpers/cygwin.mk
new file mode 100644
index 0000000..e69c0b1
--- /dev/null
+++ b/make_helpers/cygwin.mk
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+
+# OS specific definitions for builds in a Cygwin environment.
+# Cygwin allows us to use unix style commands on a windows platform.
+
+ifndef CYGWIN_MK
+    CYGWIN_MK := $(lastword $(MAKEFILE_LIST))
+
+    include ${MAKE_HELPERS_DIRECTORY}unix.mk
+
+    # In cygwin executable files have the Windows .exe extension type.
+    BIN_EXT := .exe
+
+endif
diff --git a/make_helpers/msys.mk b/make_helpers/msys.mk
new file mode 100644
index 0000000..188dc6c
--- /dev/null
+++ b/make_helpers/msys.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+
+# OS specific definitions for builds in a Mingw32 MSYS environment.
+# Mingw32 allows us to use some unix style commands on a windows platform.
+
+ifndef MSYS_MK
+    MSYS_MK := $(lastword $(MAKEFILE_LIST))
+
+    include ${MAKE_HELPERS_DIRECTORY}unix.mk
+
+    # In MSYS executable files have the Windows .exe extension type.
+    BIN_EXT := .exe
+
+endif
+
diff --git a/make_helpers/plat_helpers.mk b/make_helpers/plat_helpers.mk
new file mode 100644
index 0000000..85ba84f
--- /dev/null
+++ b/make_helpers/plat_helpers.mk
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+################################################################################
+# Helpers for finding and referencing platform directories
+################################################################################
+
+ifndef PLAT_HELPERS_MK
+    PLAT_HELPERS_MK := $(lastword $(MAKEFILE_LIST))
+
+    ifeq (${PLAT},)
+        $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
+    endif
+
+    # PLATFORM_ROOT can be overridden for when building tools directly
+    PLATFORM_ROOT               ?= plat/
+    PLAT_MAKEFILE               := platform.mk
+
+    # Generate the platforms list by recursively searching for all directories
+    # under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
+    # char and strip out the final '|'.
+    ALL_PLATFORM_MK_FILES       := $(call rwildcard,${PLATFORM_ROOT},${PLAT_MAKEFILE})
+    ALL_PLATFORM_DIRS           := $(patsubst %/,%,$(dir ${ALL_PLATFORM_MK_FILES}))
+    ALL_PLATFORMS               := $(sort $(notdir ${ALL_PLATFORM_DIRS}))
+
+    PLAT_MAKEFILE_FULL          := $(filter %/${PLAT}/${PLAT_MAKEFILE},${ALL_PLATFORM_MK_FILES})
+    PLATFORM_LIST               := $(subst ${space},|,${ALL_PLATFORMS})
+    ifeq ($(PLAT_MAKEFILE_FULL),)
+        $(error "Error: Invalid platform. The following platforms are available: ${PLATFORM_LIST}")
+    endif
+
+    # Record the directory where the platform make file was found.
+    PLAT_DIR                    := $(dir ${PLAT_MAKEFILE_FULL})
+
+endif
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
new file mode 100644
index 0000000..ab60435
--- /dev/null
+++ b/make_helpers/unix.mk
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+
+# Trusted Firmware shell command definitions for a Unix style environment.
+
+ifndef UNIX_MK
+    UNIX_MK := $(lastword $(MAKEFILE_LIST))
+
+    ECHO_BLANK_LINE := echo
+
+    DIR_DELIM := /
+    PATH_SEP := :
+
+    # These defines provide Unix style equivalents of the shell commands
+    # required by the Trusted Firmware build environment.
+
+    # ${1} is the file to be copied.
+    # ${2} is the destination file name.
+    define SHELL_COPY
+	${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}"
+    endef
+
+    # ${1} is the file to be deleted.
+    define SHELL_DELETE
+	-${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}
+    endef
+
+    # ${1} is the directory to be generated.
+    # ${2} is optional, and allows a prerequisite to be specified.
+    define MAKE_PREREQ_DIR
+
+${1} : ${2}
+	${Q}mkdir -p  "${1}"
+
+    endef
+
+    define SHELL_REMOVE_DIR
+	-${Q}rm -rf  "${1}"
+    endef
+
+endif
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
new file mode 100644
index 0000000..8ac8246
--- /dev/null
+++ b/make_helpers/windows.mk
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+
+# OS specific parts for builds in a Windows_NT environment. The
+# environment variable OS is set to Windows_NT on all modern Windows platforms
+
+# Include generic windows command definitions.
+
+ifndef WINDOWS_MK
+    WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
+
+    ECHO_BLANK_LINE := @cmd /c echo.
+    DIR_DELIM := $(strip \)
+    BIN_EXT   := .exe
+    PATH_SEP  := ;
+
+    # For some Windows native commands there is a problem with the directory delimiter.
+    # Make uses / (slash) and the commands expect \ (backslash)
+    # We have to provide a means of translating these, so we define local functions.
+
+    # ${1} is the file to be copied.
+    # ${2} is the destination file name.
+    define SHELL_COPY
+	$(eval tmp_from_file:=$(subst /,\,${1}))
+	$(eval tmp_to_file:=$(subst /,\,${2}))
+	copy "${tmp_from_file}" "${tmp_to_file}"
+    endef
+
+    # ${1} is the directory to be copied.
+    # ${2} is the destination directory path.
+    define SHELL_COPY_TREE
+	$(eval tmp_from_dir:=$(subst /,\,${1}))
+	$(eval tmp_to_dir:=$(subst /,\,${2}))
+	xcopy /HIVE "${tmp_from_dir}" "${tmp_to_dir}"
+    endef
+
+    # ${1} is the file to be deleted.
+    define SHELL_DELETE
+	$(eval tmp_del_file:=$(subst /,\,${*}))
+	-@if exist $(tmp_del_file)  del /Q $(tmp_del_file)
+    endef
+
+    # ${1} is a space delimited list of files to be deleted.
+    define SHELL_DELETE_ALL
+	$(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
+    endef
+
+    # ${1} is the directory to be generated.
+    # ${2} is optional, and allows prerequisites to be specified.
+    define MAKE_PREREQ_DIR
+
+${1} : ${2}
+	$(eval tmp_dir:=$(subst /,\,${1}))
+	-@if not exist "$(tmp_dir)"  mkdir "${tmp_dir}"
+
+    endef
+
+    # ${1} is the directory to be removed.
+    define SHELL_REMOVE_DIR
+	$(eval tmp_dir:=$(subst /,\,${1}))
+	-@if exist "$(tmp_dir)"  rd /Q /S "$(tmp_dir)"
+    endef
+
+endif
+
+# Because git is not available from CMD.EXE, we need to avoid
+# the BUILD_STRING generation which uses git.
+# For now we use "development build".
+# This can be overridden from the command line or environment.
+BUILD_STRING ?= development build
+
+# The DOS echo shell command does not strip ' characters from the command
+# parameters before printing. We therefore use an alternative method invoked
+# by defining the MAKE_BUILD_STRINGS macro.
+BUILT_TIME_DATE_STRING = const char build_message[] = "Built : "${BUILD_MESSAGE_TIMESTAMP};
+VERSION_STRING_MESSAGE = const char version_string[] = "${VERSION_STRING}";
+define MAKE_BUILD_STRINGS
+	@echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) | \
+		$$(CC) $$(CFLAGS) -x c - -o $1
+endef
+
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 8d7b8a5..27545ba 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -32,7 +32,7 @@
 PLAT		:= none
 V		:= 0
 DEBUG		:= 0
-BINARY		:= ${PROJECT}
+BINARY		:= ${PROJECT}${BIN_EXT}
 OPENSSL_DIR	:= /usr
 
 OBJECTS := src/cert.o \
@@ -47,15 +47,17 @@
 
 CFLAGS := -Wall -std=c99
 
-# Check the platform
-ifeq (${PLAT},none)
-  $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
-endif
-PLAT_MAKEFILE		:=	platform.mk
-PLAT_INCLUDE	:=	$(shell find ../../plat/ -wholename '*/${PLAT}/${PLAT_MAKEFILE}' |	\
-				sed 's/${PLAT_MAKEFILE}/include/')
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+
+PLATFORM_ROOT		:=	../../plat/
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
+PLAT_INCLUDE		:=	$(wildcard ${PLAT_DIR}include)
+
 ifeq ($(PLAT_INCLUDE),)
-  $(error "Error: Invalid platform '${PLAT}'")
+  $(error "Error: Invalid platform '${PLAT}' has no include directory.")
 endif
 
 ifeq (${DEBUG},1)
@@ -76,9 +78,8 @@
 LIB := -lssl -lcrypto
 
 CC := gcc
-RM := rm -rf
 
-.PHONY: all clean
+.PHONY: all clean realclean
 
 all: clean ${BINARY}
 
@@ -94,7 +95,8 @@
 	${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@
 
 clean:
-	${Q}${RM} -f src/build_msg.o ${OBJECTS}
+	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
 
 realclean: clean
-	${Q}${RM} -f ${BINARY}
+	$(call SHELL_DELETE, ${BINARY})
+
diff --git a/tools/fip_create/Makefile b/tools/fip_create/Makefile
index c72bae5..2e367c2 100644
--- a/tools/fip_create/Makefile
+++ b/tools/fip_create/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -28,38 +28,56 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-PROJECT = fip_create
-OBJECTS = fip_create.o
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
-CFLAGS = -Wall -Werror -pedantic -std=c99
+PROJECT := fip_create${BIN_EXT}
+OBJECTS := fip_create.o
+COPIED_H_FILES := uuid.h firmware_image_package.h
+
+CFLAGS := -Wall -Werror -pedantic -std=c99
 ifeq (${DEBUG},1)
   CFLAGS += -g -O0 -DDEBUG
 else
   CFLAGS += -O2
 endif
 
-# Make soft links and include from local directory otherwise wrong headers
-# could get pulled in from firmware tree.
-INCLUDE_PATHS = -I.
+# Only include from local directory (see comment below).
+INCLUDE_PATHS := -I.
 
 CC := gcc
-RM := rm -rf
 
-.PHONY: all clean
+.PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
 	@echo "  LD      $@"
 	${Q}${CC} ${OBJECTS} -o $@
-	@echo
+	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
-	@echo
+	@${ECHO_BLANK_LINE}
 
-%.o: %.c %.h Makefile
+%.o: %.c %.h ${COPIED_H_FILES} Makefile
 	@echo "  CC      $<"
 	${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
+#
+# Copy required library headers to a local directory so they can be included
+# by this project without adding the library directories to the system include
+# path. This avoids conflicts with definitions in the compiler standard
+# include path.
+#
+uuid.h : ../../include/stdlib/sys/uuid.h
+	$(call SHELL_COPY,$<,$@)
+
+firmware_image_package.h : ../../include/common/firmware_image_package.h
+	$(call SHELL_COPY,$<,$@)
+
 clean:
-	${Q}${RM} ${PROJECT}
-	${Q}${RM} ${OBJECTS}
+	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+
+distclean: clean
+	$(call SHELL_DELETE_ALL, ${COPIED_H_FILES})
+
diff --git a/tools/fip_create/firmware_image_package.h b/tools/fip_create/firmware_image_package.h
deleted file mode 120000
index cc61903..0000000
--- a/tools/fip_create/firmware_image_package.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/common/firmware_image_package.h
\ No newline at end of file
diff --git a/tools/fip_create/uuid.h b/tools/fip_create/uuid.h
deleted file mode 120000
index c77762f..0000000
--- a/tools/fip_create/uuid.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/stdlib/sys/uuid.h
\ No newline at end of file