--- /dev/null
+This patch fixes various things which make the build more reproducible. Some changes
+here only change intermediate artefacts but that means when you have two build trees
+giving differing results, the differences can be isolated more easily. The issues here
+usually become apparent with longer paths.
+
+This was all debugged with:
+TMPDIR = "${TOPDIR}/tmp"
+vs.
+TMPDIR = "${TOPDIR}/tmp-inital-mylongpath-mylongpath-mylongpath-mylongpath-mylongpath-mylongpath-mylongpath-mylongpath-mylongpath"
+
+The patch specifically:
+
+ * Sorts output in GNUmakefile
+ * Always generates indirect flags files used to avoid pathlength issues else the
+ compile commands suddenly change when using longer paths
+ * Sorts the AutoGenTimeStamp file contents
+ * Makes the TargetDescBlock objects from BuildEngine sortable to allow the makefile fix
+ * Fix ElfConvert within GenFw so that only the basename of the binary being converted
+ is used, else the output from "GenFw XXX.bin" differs from "GenFw /long/path/XXX.bin"
+ with sufficiently long paths
+
+Upstream-Status: Pending [At least some of this might be interesting to upstream]
+Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
+
+Index: git/BaseTools/Source/Python/AutoGen/GenMake.py
+===================================================================
+--- git.orig/BaseTools/Source/Python/AutoGen/GenMake.py
++++ git/BaseTools/Source/Python/AutoGen/GenMake.py
+@@ -571,7 +571,7 @@ cleanlib:
+ os.remove(RespFileList)\r
+ \r
+ # convert source files and binary files to build targets\r
+- self.ResultFileList = [str(T.Target) for T in MyAgo.CodaTargetList]\r
++ self.ResultFileList = sorted([str(T.Target) for T in MyAgo.CodaTargetList])\r
+ if len(self.ResultFileList) == 0 and len(MyAgo.SourceFileList) != 0:\r
+ EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",\r
+ ExtraData="[%s]" % str(MyAgo))\r
+@@ -722,7 +722,7 @@ cleanlib:
+ OutputFile = ''\r
+ DepsFileList = []\r
+ \r
+- for Cmd in self.GenFfsList:\r
++ for Cmd in sorted(self.GenFfsList):\r
+ if Cmd[2]:\r
+ for CopyCmd in Cmd[2]:\r
+ Src, Dst = CopyCmd\r
+@@ -755,7 +755,7 @@ cleanlib:
+ self.BuildTargetList.append('\t%s' % CmdString)\r
+ \r
+ self.ParseSecCmd(DepsFileList, Cmd[1])\r
+- for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :\r
++ for SecOutputFile, SecDepsFile, SecCmd in sorted(self.FfsOutputFileList):\r
+ self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))\r
+ self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))\r
+ self.FfsOutputFileList = []\r
+@@ -794,13 +794,13 @@ cleanlib:
+ \r
+ def CommandExceedLimit(self):\r
+ FlagDict = {\r
+- 'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : False},\r
+- 'PP' : { 'Macro' : '$(PP_FLAGS)', 'Value' : False},\r
+- 'APP' : { 'Macro' : '$(APP_FLAGS)', 'Value' : False},\r
+- 'ASLPP' : { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},\r
+- 'VFRPP' : { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},\r
+- 'ASM' : { 'Macro' : '$(ASM_FLAGS)', 'Value' : False},\r
+- 'ASLCC' : { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},\r
++ 'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : True},\r
++ 'PP' : { 'Macro' : '$(PP_FLAGS)', 'Value' : True},\r
++ 'APP' : { 'Macro' : '$(APP_FLAGS)', 'Value' : True},\r
++ 'ASLPP' : { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : True},\r
++ 'VFRPP' : { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : True},\r
++ 'ASM' : { 'Macro' : '$(ASM_FLAGS)', 'Value' : True},\r
++ 'ASLCC' : { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : True},\r
+ }\r
+ \r
+ RespDict = {}\r
+@@ -1003,9 +1003,9 @@ cleanlib:
+ if not self.ObjTargetDict.get(T.Target.SubDir):\r
+ self.ObjTargetDict[T.Target.SubDir] = set()\r
+ self.ObjTargetDict[T.Target.SubDir].add(NewFile)\r
+- for Type in self._AutoGenObject.Targets:\r
++ for Type in sorted(self._AutoGenObject.Targets):\r
+ resp_file_number = 0\r
+- for T in self._AutoGenObject.Targets[Type]:\r
++ for T in sorted(self._AutoGenObject.Targets[Type]):\r
+ # Generate related macros if needed\r
+ if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:\r
+ self.FileListMacros[T.FileListMacro] = []\r
+Index: git/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
+===================================================================
+--- git.orig/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
++++ git/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
+@@ -1484,6 +1484,9 @@ class ModuleAutoGen(AutoGen):
+ for File in Files:\r
+ if File.lower().endswith('.pdb'):\r
+ AsBuiltInfDict['binary_item'].append('DISPOSABLE|' + File)\r
++\r
++ AsBuiltInfDict['binary_item'] = sorted(AsBuiltInfDict['binary_item'])\r
++\r
+ HeaderComments = self.Module.HeaderComments\r
+ StartPos = 0\r
+ for Index in range(len(HeaderComments)):\r
+@@ -1759,7 +1762,7 @@ class ModuleAutoGen(AutoGen):
+ if os.path.exists (self.TimeStampPath):\r
+ os.remove (self.TimeStampPath)\r
+ \r
+- SaveFileOnChange(self.TimeStampPath, "\n".join(FileSet), False)\r
++ SaveFileOnChange(self.TimeStampPath, "\n".join(sorted(FileSet)), False)\r
+ \r
+ # Ignore generating makefile when it is a binary module\r
+ if self.IsBinaryModule:\r
+Index: git/BaseTools/Source/Python/AutoGen/BuildEngine.py
+===================================================================
+--- git.orig/BaseTools/Source/Python/AutoGen/BuildEngine.py
++++ git/BaseTools/Source/Python/AutoGen/BuildEngine.py
+@@ -70,6 +70,9 @@ class TargetDescBlock(object):
+ else:\r
+ return str(Other) == self.Target.Path\r
+ \r
++ def __lt__(self, other):\r
++ return str(self) < str(other)\r
++\r
+ def AddInput(self, Input):\r
+ if Input not in self.Inputs:\r
+ self.Inputs.append(Input)\r
+Index: git/BaseTools/Source/C/GenFw/Elf64Convert.c
+===================================================================
+--- git.orig/BaseTools/Source/C/GenFw/Elf64Convert.c
++++ git/BaseTools/Source/C/GenFw/Elf64Convert.c
+@@ -14,6 +14,8 @@ SPDX-License-Identifier: BSD-2-Clause-Pa
+ #ifndef __GNUC__\r
+ #include <windows.h>\r
+ #include <io.h>\r
++#else\r
++#define _GNU_SOURCE\r
+ #endif\r
+ #include <assert.h>\r
+ #include <stdio.h>\r
+@@ -770,7 +772,7 @@ ScanSections64 (
+ }\r
+ mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +\r
+ sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +\r
+- strlen(mInImageName) + 1;\r
++ strlen(basename(mInImageName)) + 1;\r
+ \r
+ mCoffOffset = CoffAlign(mCoffOffset);\r
+ if (SectionCount == 0) {\r
+@@ -1609,7 +1611,7 @@ WriteDebug64 (
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;\r
+ EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
+ \r
+- Len = strlen(mInImageName) + 1;\r
++ Len = strlen(basename(mInImageName)) + 1;\r
+ \r
+ Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);\r
+ Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
+@@ -1619,7 +1621,7 @@ WriteDebug64 (
+ \r
+ Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
+ Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
+- strcpy ((char *)(Nb10 + 1), mInImageName);\r
++ strcpy ((char *)(Nb10 + 1), basename(mInImageName));\r
+ \r
+ \r
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r