* [Patch] BaseTools: Improve build performance
@ 2018-02-07 7:03 BobCF
0 siblings, 0 replies; 2+ messages in thread
From: BobCF @ 2018-02-07 7:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Yonghong Zhu, Liming Gao
Add cache for building PcdValueInit.c.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
BaseTools/Source/Python/Workspace/DscBuildData.py | 140 +++++++++++-----------
1 file changed, 71 insertions(+), 69 deletions(-)
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 0da3efbb43..6d8486aa19 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -35,10 +35,11 @@ from Common.Misc import ProcessDuplicatedInf
import re
from Common.Parsing import IsValidWord
from Common.VariableAttributes import VariableAttributes
import Common.GlobalData as GlobalData
import subprocess
+from Common.Misc import SaveFileOnChange
from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
#
# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
#
@@ -1815,13 +1816,11 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + PcdMainCEntry + '\n'
if not os.path.exists(self.OutputPath):
os.makedirs(self.OutputPath)
CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
- File = open (CAppBaseFileName + '.c', 'w')
- File.write(CApp)
- File.close()
+ SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
MakeApp = PcdMakefileHeader
if sys.platform == "win32":
MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
else:
@@ -1897,92 +1896,95 @@ class DscBuildData(PlatformBuildClassObject):
MakeApp += CC_FLAGS
if sys.platform == "win32":
MakeApp = MakeApp + PcdMakefileEnd
MakeFileName = os.path.join(self.OutputPath, 'Makefile')
- File = open (MakeFileName, 'w')
- File.write(MakeApp)
- File.close()
+ SaveFileOnChange(MakeFileName, MakeApp, False)
InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
- File = open (InputValueFile, 'w')
- File.write(InitByteValue)
- File.close()
-
- Messages = ''
- if sys.platform == "win32":
- MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)
- returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
- Messages = StdOut
- else:
- MakeCommand = 'make clean & make -f %s' % (MakeFileName)
- returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
- Messages = StdErr
- Messages = Messages.split('\n')
- MessageGroup = []
- if returncode <>0:
- CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
- File = open (CAppBaseFileName + '.c', 'r')
- FileData = File.readlines()
- File.close()
- for Message in Messages:
- if " error" in Message or "warning" in Message:
- FileInfo = Message.strip().split('(')
- if len (FileInfo) > 1:
- FileName = FileInfo [0]
- FileLine = FileInfo [1].split (')')[0]
- else:
- FileInfo = Message.strip().split(':')
- FileName = FileInfo [0]
- FileLine = FileInfo [1]
- if FileLine.isdigit():
- error_line = FileData[int (FileLine) - 1]
- if r"//" in error_line:
- c_line,dsc_line = error_line.split(r"//")
- else:
- dsc_line = error_line
- message_itmes = Message.split(":")
- Index = 0
- if "PcdValueInit.c" not in Message:
- break
- else:
- for item in message_itmes:
- if "PcdValueInit.c" in item:
- Index = message_itmes.index(item)
- message_itmes[Index] = dsc_line.strip()
- break
- MessageGroup.append(":".join(message_itmes[Index:]).strip())
- continue
- else:
- MessageGroup.append(Message)
- if MessageGroup:
- EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
- else:
- EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
+ SaveFileOnChange(InputValueFile, InitByteValue, False)
PcdValueInitExe = PcdValueInitName
if not sys.platform == "win32":
PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
-
- Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
- returncode, StdOut, StdErr = self.ExecuteCommand (Command)
- if returncode <> 0:
- EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
- FileBuffer = []
else:
- File = open (OutputValueFile, 'r')
- FileBuffer = File.readlines()
- File.close()
+ PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
+ if not os.path.exists(PcdValueInitExe) or self.NeedUpdateOutput(OutputValueFile, CAppBaseFileName + '.c'):
+ Messages = ''
+ if sys.platform == "win32":
+ MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)
+ returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
+ Messages = StdOut
+ else:
+ MakeCommand = 'make clean & make -f %s' % (MakeFileName)
+ returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
+ Messages = StdErr
+ Messages = Messages.split('\n')
+ MessageGroup = []
+ if returncode <>0:
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ File = open (CAppBaseFileName + '.c', 'r')
+ FileData = File.readlines()
+ File.close()
+ for Message in Messages:
+ if " error" in Message or "warning" in Message:
+ FileInfo = Message.strip().split('(')
+ if len (FileInfo) > 1:
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1].split (')')[0]
+ else:
+ FileInfo = Message.strip().split(':')
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1]
+ if FileLine.isdigit():
+ error_line = FileData[int (FileLine) - 1]
+ if r"//" in error_line:
+ c_line,dsc_line = error_line.split(r"//")
+ else:
+ dsc_line = error_line
+ message_itmes = Message.split(":")
+ Index = 0
+ if "PcdValueInit.c" not in Message:
+ break
+ else:
+ for item in message_itmes:
+ if "PcdValueInit.c" in item:
+ Index = message_itmes.index(item)
+ message_itmes[Index] = dsc_line.strip()
+ break
+ MessageGroup.append(":".join(message_itmes[Index:]).strip())
+ continue
+ else:
+ MessageGroup.append(Message)
+ if MessageGroup:
+ EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
+ else:
+ EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
+ Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
+ returncode, StdOut, StdErr = self.ExecuteCommand (Command)
+ if returncode <> 0:
+ EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
+
+ File = open (OutputValueFile, 'r')
+ FileBuffer = File.readlines()
+ File.close()
StructurePcdSet = []
for Pcd in FileBuffer:
PcdValue = Pcd.split ('|')
PcdInfo = PcdValue[0].split ('.')
StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
return StructurePcdSet
+ def NeedUpdateOutput(self,OutputFile, ValueCFile):
+ if not os.path.exists(OutputFile):
+ return True
+ if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
+ return True
+ return False
+
## Retrieve dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
--
2.14.3.windows.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [Patch] BaseTools: Improve build performance
@ 2018-02-09 5:17 BobCF
0 siblings, 0 replies; 2+ messages in thread
From: BobCF @ 2018-02-09 5:17 UTC (permalink / raw)
To: edk2-devel; +Cc: Bob Feng, Liming Gao
Add cache for building PcdValueInit.c.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
BaseTools/Source/Python/GenFds/GenFds.py | 1 +
BaseTools/Source/Python/Workspace/DscBuildData.py | 150 +++++++++++-----------
2 files changed, 78 insertions(+), 73 deletions(-)
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index dcba9f24cb..cd705630a3 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -324,10 +324,11 @@ def main():
EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)
else:
FvObj.FvRegionInFD = RegionObj.Size
RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)
+ GlobalData.BuildOptionPcd = Options.OptionPcd if Options.OptionPcd else {}
"""Call GenFds"""
GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)
"""Generate GUID cross reference file"""
GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 0da3efbb43..70dd83cfbc 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -35,10 +35,11 @@ from Common.Misc import ProcessDuplicatedInf
import re
from Common.Parsing import IsValidWord
from Common.VariableAttributes import VariableAttributes
import Common.GlobalData as GlobalData
import subprocess
+from Common.Misc import SaveFileOnChange
from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
#
# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
#
@@ -154,12 +155,14 @@ class DscBuildData(PlatformBuildClassObject):
self._Target = Target
self._Toolchain = Toolchain
self._ToolChainFamily = None
self._Clear()
self._HandleOverridePath()
+ self.WorkspaceDir = ""
if os.getenv("WORKSPACE"):
self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)
+ self.WorkspaceDir = os.getenv("WORKSPACE")
else:
self.OutputPath = os.path.dirname(self.DscFile)
self.DefaultStores = None
self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
@@ -1289,11 +1292,11 @@ class DscBuildData(PlatformBuildClassObject):
str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
else:
str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
for str_pcd_data in StrPcdSet[str_pcd]:
if str_pcd_data[3] in SkuIds:
- str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File,LineNo=str_pcd_data[5])
+ str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],LineNo=str_pcd_data[5])
S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
else:
EdkLogger.error('build', PARSER_ERROR,
"Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
@@ -1781,14 +1784,14 @@ class DscBuildData(PlatformBuildClassObject):
for IncludeFile in Pcd.StructuredPcdIncludeFile:
if IncludeFile not in Includes:
Includes[IncludeFile] = True
CApp = CApp + '#include <%s>\n' % (IncludeFile)
CApp = CApp + '\n'
-
for PcdName in StructuredPcds:
Pcd = StructuredPcds[PcdName]
- if not Pcd.SkuOverrideValues:
+ if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)
else:
for SkuName in self.SkuIdMgr.SkuOverrideOrder():
if SkuName not in Pcd.SkuOverrideValues:
continue
@@ -1800,11 +1803,11 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + 'PcdEntryPoint(\n'
CApp = CApp + ' VOID\n'
CApp = CApp + ' )\n'
CApp = CApp + '{\n'
for Pcd in StructuredPcds.values():
- if not Pcd.SkuOverrideValues:
+ if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
else:
for SkuName in self.SkuIdMgr.SkuOverrideOrder():
if SkuName not in Pcd.SkuOverrideValues:
continue
@@ -1815,13 +1818,11 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + PcdMainCEntry + '\n'
if not os.path.exists(self.OutputPath):
os.makedirs(self.OutputPath)
CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
- File = open (CAppBaseFileName + '.c', 'w')
- File.write(CApp)
- File.close()
+ SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
MakeApp = PcdMakefileHeader
if sys.platform == "win32":
MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
else:
@@ -1897,92 +1898,95 @@ class DscBuildData(PlatformBuildClassObject):
MakeApp += CC_FLAGS
if sys.platform == "win32":
MakeApp = MakeApp + PcdMakefileEnd
MakeFileName = os.path.join(self.OutputPath, 'Makefile')
- File = open (MakeFileName, 'w')
- File.write(MakeApp)
- File.close()
+ SaveFileOnChange(MakeFileName, MakeApp, False)
InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
- File = open (InputValueFile, 'w')
- File.write(InitByteValue)
- File.close()
-
- Messages = ''
- if sys.platform == "win32":
- MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)
- returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
- Messages = StdOut
- else:
- MakeCommand = 'make clean & make -f %s' % (MakeFileName)
- returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
- Messages = StdErr
- Messages = Messages.split('\n')
- MessageGroup = []
- if returncode <>0:
- CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
- File = open (CAppBaseFileName + '.c', 'r')
- FileData = File.readlines()
- File.close()
- for Message in Messages:
- if " error" in Message or "warning" in Message:
- FileInfo = Message.strip().split('(')
- if len (FileInfo) > 1:
- FileName = FileInfo [0]
- FileLine = FileInfo [1].split (')')[0]
- else:
- FileInfo = Message.strip().split(':')
- FileName = FileInfo [0]
- FileLine = FileInfo [1]
- if FileLine.isdigit():
- error_line = FileData[int (FileLine) - 1]
- if r"//" in error_line:
- c_line,dsc_line = error_line.split(r"//")
- else:
- dsc_line = error_line
- message_itmes = Message.split(":")
- Index = 0
- if "PcdValueInit.c" not in Message:
- break
- else:
- for item in message_itmes:
- if "PcdValueInit.c" in item:
- Index = message_itmes.index(item)
- message_itmes[Index] = dsc_line.strip()
- break
- MessageGroup.append(":".join(message_itmes[Index:]).strip())
- continue
- else:
- MessageGroup.append(Message)
- if MessageGroup:
- EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
- else:
- EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
+ SaveFileOnChange(InputValueFile, InitByteValue, False)
PcdValueInitExe = PcdValueInitName
if not sys.platform == "win32":
PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
-
- Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
- returncode, StdOut, StdErr = self.ExecuteCommand (Command)
- if returncode <> 0:
- EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
- FileBuffer = []
else:
- File = open (OutputValueFile, 'r')
- FileBuffer = File.readlines()
- File.close()
+ PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
+ if not os.path.exists(PcdValueInitExe) or self.NeedUpdateOutput(OutputValueFile, CAppBaseFileName + '.c'):
+ Messages = ''
+ if sys.platform == "win32":
+ MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)
+ returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
+ Messages = StdOut
+ else:
+ MakeCommand = 'make clean & make -f %s' % (MakeFileName)
+ returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
+ Messages = StdErr
+ Messages = Messages.split('\n')
+ MessageGroup = []
+ if returncode <>0:
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ File = open (CAppBaseFileName + '.c', 'r')
+ FileData = File.readlines()
+ File.close()
+ for Message in Messages:
+ if " error" in Message or "warning" in Message:
+ FileInfo = Message.strip().split('(')
+ if len (FileInfo) > 1:
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1].split (')')[0]
+ else:
+ FileInfo = Message.strip().split(':')
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1]
+ if FileLine.isdigit():
+ error_line = FileData[int (FileLine) - 1]
+ if r"//" in error_line:
+ c_line,dsc_line = error_line.split(r"//")
+ else:
+ dsc_line = error_line
+ message_itmes = Message.split(":")
+ Index = 0
+ if "PcdValueInit.c" not in Message:
+ break
+ else:
+ for item in message_itmes:
+ if "PcdValueInit.c" in item:
+ Index = message_itmes.index(item)
+ message_itmes[Index] = dsc_line.strip()
+ break
+ MessageGroup.append(":".join(message_itmes[Index:]).strip())
+ continue
+ else:
+ MessageGroup.append(Message)
+ if MessageGroup:
+ EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
+ else:
+ EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
+ Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
+ returncode, StdOut, StdErr = self.ExecuteCommand (Command)
+ if returncode <> 0:
+ EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
+
+ File = open (OutputValueFile, 'r')
+ FileBuffer = File.readlines()
+ File.close()
StructurePcdSet = []
for Pcd in FileBuffer:
PcdValue = Pcd.split ('|')
PcdInfo = PcdValue[0].split ('.')
StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
return StructurePcdSet
+ def NeedUpdateOutput(self,OutputFile, ValueCFile):
+ if not os.path.exists(OutputFile):
+ return True
+ if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
+ return True
+ return False
+
## Retrieve dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
--
2.14.3.windows.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-02-09 5:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-07 7:03 [Patch] BaseTools: Improve build performance BobCF
-- strict thread matches above, loose matches on Subject: below --
2018-02-09 5:17 BobCF
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox