+ def InitPreBuild(self):\r
+ self.LoadConfiguration()\r
+ ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc", False)\r
+ if ErrorCode != 0:\r
+ EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)\r
+ if self.BuildTargetList:\r
+ GlobalData.gGlobalDefines['TARGET'] = self.BuildTargetList[0]\r
+ if self.ArchList:\r
+ GlobalData.gGlobalDefines['ARCH'] = self.ArchList[0]\r
+ if self.ToolChainList:\r
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = self.ToolChainList[0]\r
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = self.ToolChainList[0]\r
+ if self.ToolChainFamily:\r
+ GlobalData.gGlobalDefines['FAMILY'] = self.ToolChainFamily[0]\r
+ if 'PREBUILD' in GlobalData.gCommandLineDefines.keys():\r
+ self.Prebuild = GlobalData.gCommandLineDefines.get('PREBUILD')\r
+ else:\r
+ self.Db.InitDatabase()\r
+ self.Db_Flag = True\r
+ Platform = self.Db._MapPlatform(str(self.PlatformFile))\r
+ self.Prebuild = str(Platform.Prebuild)\r
+ if self.Prebuild:\r
+ PrebuildList = []\r
+ #\r
+ # Evaluate all arguments and convert arguments that are WORKSPACE\r
+ # relative paths to absolute paths. Filter arguments that look like\r
+ # flags or do not follow the file/dir naming rules to avoid false\r
+ # positives on this conversion.\r
+ #\r
+ for Arg in self.Prebuild.split():\r
+ #\r
+ # Do not modify Arg if it looks like a flag or an absolute file path\r
+ #\r
+ if Arg.startswith('-') or os.path.isabs(Arg):\r
+ PrebuildList.append(Arg)\r
+ continue\r
+ #\r
+ # Do not modify Arg if it does not look like a Workspace relative\r
+ # path that starts with a valid package directory name\r
+ #\r
+ if not Arg[0].isalpha() or os.path.dirname(Arg) == '':\r
+ PrebuildList.append(Arg)\r
+ continue\r
+ #\r
+ # If Arg looks like a WORKSPACE relative path, then convert to an\r
+ # absolute path and check to see if the file exists.\r
+ #\r
+ Temp = mws.join(self.WorkspaceDir, Arg)\r
+ if os.path.isfile(Temp):\r
+ Arg = Temp\r
+ PrebuildList.append(Arg)\r
+ self.Prebuild = ' '.join(PrebuildList)\r
+ self.Prebuild += self.PassCommandOption(self.BuildTargetList, self.ArchList, self.ToolChainList, self.PlatformFile, self.Target)\r
+\r
+ def InitPostBuild(self):\r
+ if 'POSTBUILD' in GlobalData.gCommandLineDefines.keys():\r
+ self.Postbuild = GlobalData.gCommandLineDefines.get('POSTBUILD')\r
+ else:\r
+ Platform = self.Db._MapPlatform(str(self.PlatformFile))\r
+ self.Postbuild = str(Platform.Postbuild)\r
+ if self.Postbuild:\r
+ PostbuildList = []\r
+ #\r
+ # Evaluate all arguments and convert arguments that are WORKSPACE\r
+ # relative paths to absolute paths. Filter arguments that look like\r
+ # flags or do not follow the file/dir naming rules to avoid false\r
+ # positives on this conversion.\r
+ #\r
+ for Arg in self.Postbuild.split():\r
+ #\r
+ # Do not modify Arg if it looks like a flag or an absolute file path\r
+ #\r
+ if Arg.startswith('-') or os.path.isabs(Arg):\r
+ PostbuildList.append(Arg)\r
+ continue\r
+ #\r
+ # Do not modify Arg if it does not look like a Workspace relative\r
+ # path that starts with a valid package directory name\r
+ #\r
+ if not Arg[0].isalpha() or os.path.dirname(Arg) == '':\r
+ PostbuildList.append(Arg)\r
+ continue\r
+ #\r
+ # If Arg looks like a WORKSPACE relative path, then convert to an\r
+ # absolute path and check to see if the file exists.\r
+ #\r
+ Temp = mws.join(self.WorkspaceDir, Arg)\r
+ if os.path.isfile(Temp):\r
+ Arg = Temp\r
+ PostbuildList.append(Arg)\r
+ self.Postbuild = ' '.join(PostbuildList)\r
+ self.Postbuild += self.PassCommandOption(self.BuildTargetList, self.ArchList, self.ToolChainList, self.PlatformFile, self.Target)\r
+\r
+ def PassCommandOption(self, BuildTarget, TargetArch, ToolChain, PlatformFile, Target):\r
+ BuildStr = ''\r
+ if GlobalData.gCommand and isinstance(GlobalData.gCommand, list):\r
+ BuildStr += ' ' + ' '.join(GlobalData.gCommand)\r
+ TargetFlag = False\r
+ ArchFlag = False\r
+ ToolChainFlag = False\r
+ PlatformFileFlag = False\r
+\r
+ if GlobalData.gOptions and not GlobalData.gOptions.BuildTarget:\r
+ TargetFlag = True\r
+ if GlobalData.gOptions and not GlobalData.gOptions.TargetArch:\r
+ ArchFlag = True\r
+ if GlobalData.gOptions and not GlobalData.gOptions.ToolChain:\r
+ ToolChainFlag = True\r
+ if GlobalData.gOptions and not GlobalData.gOptions.PlatformFile:\r
+ PlatformFileFlag = True\r
+\r
+ if TargetFlag and BuildTarget:\r
+ if isinstance(BuildTarget, list) or isinstance(BuildTarget, tuple):\r
+ BuildStr += ' -b ' + ' -b '.join(BuildTarget)\r
+ elif isinstance(BuildTarget, str):\r
+ BuildStr += ' -b ' + BuildTarget\r
+ if ArchFlag and TargetArch:\r
+ if isinstance(TargetArch, list) or isinstance(TargetArch, tuple):\r
+ BuildStr += ' -a ' + ' -a '.join(TargetArch)\r
+ elif isinstance(TargetArch, str):\r
+ BuildStr += ' -a ' + TargetArch\r
+ if ToolChainFlag and ToolChain:\r
+ if isinstance(ToolChain, list) or isinstance(ToolChain, tuple):\r
+ BuildStr += ' -t ' + ' -t '.join(ToolChain)\r
+ elif isinstance(ToolChain, str):\r
+ BuildStr += ' -t ' + ToolChain\r
+ if PlatformFileFlag and PlatformFile:\r
+ if isinstance(PlatformFile, list) or isinstance(PlatformFile, tuple):\r
+ BuildStr += ' -p ' + ' -p '.join(PlatformFile)\r
+ elif isinstance(PlatformFile, str):\r
+ BuildStr += ' -p' + PlatformFile\r
+ BuildStr += ' --conf=' + GlobalData.gConfDirectory\r
+ if Target:\r
+ BuildStr += ' ' + Target\r
+\r
+ return BuildStr\r
+\r
+ def LaunchPrebuild(self):\r
+ if self.Prebuild:\r
+ EdkLogger.info("\n- Prebuild Start -\n")\r
+ self.LaunchPrebuildFlag = True\r
+ #\r
+ # The purpose of .PrebuildEnv file is capture environment variable settings set by the prebuild script\r
+ # and preserve them for the rest of the main build step, because the child process environment will\r
+ # evaporate as soon as it exits, we cannot get it in build step.\r
+ #\r
+ PrebuildEnvFile = os.path.join(GlobalData.gConfDirectory,'.cache','.PrebuildEnv')\r
+ if os.path.isfile(PrebuildEnvFile):\r
+ os.remove(PrebuildEnvFile)\r
+ if os.path.isfile(self.PlatformBuildPath):\r
+ os.remove(self.PlatformBuildPath)\r
+ if sys.platform == "win32":\r
+ args = ' && '.join((self.Prebuild, 'set > ' + PrebuildEnvFile))\r
+ Process = Popen(args, stdout=PIPE, stderr=PIPE, shell=True)\r
+ else:\r
+ args = ' && '.join((self.Prebuild, 'env > ' + PrebuildEnvFile))\r
+ Process = Popen(args, stdout=PIPE, stderr=PIPE, shell=True)\r
+\r
+ # launch two threads to read the STDOUT and STDERR\r
+ EndOfProcedure = Event()\r
+ EndOfProcedure.clear()\r
+ if Process.stdout:\r
+ StdOutThread = Thread(target=ReadMessage, args=(Process.stdout, EdkLogger.info, EndOfProcedure))\r
+ StdOutThread.setName("STDOUT-Redirector")\r
+ StdOutThread.setDaemon(False)\r
+ StdOutThread.start()\r
+\r
+ if Process.stderr:\r
+ StdErrThread = Thread(target=ReadMessage, args=(Process.stderr, EdkLogger.quiet, EndOfProcedure))\r
+ StdErrThread.setName("STDERR-Redirector")\r
+ StdErrThread.setDaemon(False)\r
+ StdErrThread.start()\r
+ # waiting for program exit\r
+ Process.wait()\r
+\r
+ if Process.stdout:\r
+ StdOutThread.join()\r
+ if Process.stderr:\r
+ StdErrThread.join()\r
+ if Process.returncode != 0 :\r
+ EdkLogger.error("Prebuild", PREBUILD_ERROR, 'Prebuild process is not success!')\r
+\r
+ if os.path.exists(PrebuildEnvFile):\r
+ f = open(PrebuildEnvFile)\r
+ envs = f.readlines()\r
+ f.close()\r
+ envs = itertools.imap(lambda l: l.split('=',1), envs)\r
+ envs = itertools.ifilter(lambda l: len(l) == 2, envs)\r
+ envs = itertools.imap(lambda l: [i.strip() for i in l], envs)\r
+ os.environ.update(dict(envs))\r
+ EdkLogger.info("\n- Prebuild Done -\n")\r
+\r
+ def LaunchPostbuild(self):\r
+ if self.Postbuild:\r
+ EdkLogger.info("\n- Postbuild Start -\n")\r
+ if sys.platform == "win32":\r
+ Process = Popen(self.Postbuild, stdout=PIPE, stderr=PIPE, shell=True)\r
+ else:\r
+ Process = Popen(self.Postbuild, stdout=PIPE, stderr=PIPE, shell=True)\r
+ # launch two threads to read the STDOUT and STDERR\r
+ EndOfProcedure = Event()\r
+ EndOfProcedure.clear()\r
+ if Process.stdout:\r
+ StdOutThread = Thread(target=ReadMessage, args=(Process.stdout, EdkLogger.info, EndOfProcedure))\r
+ StdOutThread.setName("STDOUT-Redirector")\r
+ StdOutThread.setDaemon(False)\r
+ StdOutThread.start()\r
+\r
+ if Process.stderr:\r
+ StdErrThread = Thread(target=ReadMessage, args=(Process.stderr, EdkLogger.quiet, EndOfProcedure))\r
+ StdErrThread.setName("STDERR-Redirector")\r
+ StdErrThread.setDaemon(False)\r
+ StdErrThread.start()\r
+ # waiting for program exit\r
+ Process.wait()\r
+\r
+ if Process.stdout:\r
+ StdOutThread.join()\r
+ if Process.stderr:\r
+ StdErrThread.join()\r
+ if Process.returncode != 0 :\r
+ EdkLogger.error("Postbuild", POSTBUILD_ERROR, 'Postbuild process is not success!')\r
+ EdkLogger.info("\n- Postbuild Done -\n")\r