+++ /dev/null
-/** @file\r
- This file is ANT task FpdParserTask. \r
- \r
- Copyright (c) 2006, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
- **/\r
-package org.tianocore.build.fpd;\r
-\r
-import java.io.File;\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.LinkedHashMap;\r
-import java.util.LinkedHashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.apache.tools.ant.BuildException;\r
-import org.apache.tools.ant.taskdefs.Ant;\r
-import org.apache.xmlbeans.XmlObject;\r
-\r
-import org.tianocore.build.global.GenBuildLogger;\r
-import org.tianocore.build.global.GlobalData;\r
-import org.tianocore.build.global.OutputManager;\r
-import org.tianocore.build.id.FpdModuleIdentification;\r
-import org.tianocore.build.id.ModuleIdentification;\r
-import org.tianocore.build.FrameworkBuildTask;\r
-import org.tianocore.build.GenBuildThread;\r
-import org.tianocore.common.exception.EdkException;\r
-import org.tianocore.common.logger.EdkLog;\r
-\r
-/**\r
-\r
- @since GenBuild 1.0\r
-**/\r
-public class FpdParserForThread extends FpdParserTask {\r
- \r
- public static Map<FpdModuleIdentification, GenBuildThread> allThreads = new LinkedHashMap<FpdModuleIdentification, GenBuildThread>();\r
- \r
- List<String> queueList = new ArrayList<String>();\r
- \r
- public final static Object deamonSemaphore = new Object();\r
- \r
- private final static Object countSemaphore = new Object();\r
- \r
- public static int STATUS_DEPENDENCY_NOT_READY = 1;\r
- \r
- public static int STATUS_DEPENDENCY_READY = 2;\r
- \r
- public static int STATUS_START_RUN = 3;\r
- \r
- public static int STATUS_END_RUN = 4;\r
- \r
- private int currentQueueCode = 0;\r
- \r
- public static int currentRunNumber = 0;\r
- \r
- public static int totalNumber = 0;\r
- \r
- public static int remainNumber = 0;\r
- \r
- public static ThreadGroup tg = new ThreadGroup("Framework");\r
- \r
- public static FpdModuleIdentification errorModule = null;\r
- \r
- /**\r
- Public construct method. It is necessary for ANT task.\r
- **/\r
- public FpdParserForThread() {\r
- }\r
-\r
- /**\r
- \r
-\r
- **/\r
- public void execute() throws BuildException {\r
- \r
- this.setTaskName(".........");\r
- //\r
- // Parse FPD file\r
- //\r
- parseFpdFile();\r
-\r
- //\r
- // Prepare BUILD_DIR\r
- //\r
- isUnified = OutputManager.getInstance().prepareBuildDir(getProject());\r
- String buildDir = getProject().getProperty("BUILD_DIR");\r
- \r
- //\r
- // For every Target and ToolChain\r
- //\r
- String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
- for (int i = 0; i < targetList.length; i++) {\r
- String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
- for(int j = 0; j < toolchainList.length; j++) {\r
- //\r
- // Prepare FV_DIR\r
- //\r
- String ffsCommonDir = buildDir + File.separatorChar\r
- + targetList[i] + "_"\r
- + toolchainList[j];\r
- File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
- fvDir.mkdirs();\r
- getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
-\r
- //\r
- // Gen Fv.inf files\r
- //\r
- genFvInfFiles(ffsCommonDir);\r
- }\r
- }\r
-\r
- //\r
- // Gen build.xml\r
- //\r
- String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";\r
- PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile, aprioriType);\r
- fileGenerator.genBuildFile();\r
- \r
- //\r
- // Prepare Queue\r
- //\r
- queueList.add("libqueue");\r
- \r
- String[] validFv = saq.getFpdValidImageNames();\r
- \r
- for (int i = 0; i < validFv.length; i++) {\r
- queueList.add(validFv[i]);\r
- }\r
- \r
- Iterator<String> fvsNameIter = fvs.keySet().iterator();\r
- \r
- while (fvsNameIter.hasNext()) {\r
- String fvName = fvsNameIter.next();\r
- if (!isContain(validFv, fvName)) {\r
- queueList.add(fvName);\r
- }\r
- }\r
- \r
- //\r
- // Ant call ${PLATFORM}_build.xml\r
- //\r
- Ant ant = new Ant();\r
- ant.setProject(getProject());\r
- ant.setAntfile(platformBuildFile);\r
- ant.setTarget("prebuild");\r
- ant.setInheritAll(true);\r
- ant.init();\r
- ant.execute();\r
- \r
- remainNumber = totalNumber = allThreads.size();\r
- \r
- EdkLog.log(this, EdkLog.EDK_ALWAYS, "Total thread number is " + totalNumber);\r
- GenBuildLogger.setCacheEnable(true);\r
- //\r
- // Waiting for all thread over, or time out\r
- //\r
- synchronized (deamonSemaphore) {\r
-\r
- while (true) {\r
- //\r
- // If all modules are already built\r
- //\r
- if (currentQueueCode >= queueList.size()) {\r
- break ;\r
- }\r
- \r
- int percentage = (totalNumber - remainNumber) * 100 / totalNumber;\r
- updateTaskName(percentage);\r
- EdkLog.log(this, EdkLog.EDK_ALWAYS, percentage + "% finished. Has built " + (totalNumber - remainNumber) + " modules of " + totalNumber + " total. ");\r
-\r
- Set<FpdModuleIdentification> currentQueueModules = fvs.get(queueList.get(currentQueueCode));\r
- \r
- if (currentQueueModules == null) {\r
- ++currentQueueCode;\r
- continue ;\r
- }\r
- Iterator<FpdModuleIdentification> currentIter = currentQueueModules.iterator();\r
-\r
- GenBuildThread a = null;\r
-\r
- boolean existNoneReady = false;\r
-\r
- while (currentIter.hasNext()) {\r
- GenBuildThread item = allThreads.get(currentIter.next()); \r
- if (item.getStatus() == STATUS_DEPENDENCY_NOT_READY) {\r
- existNoneReady = true;\r
- } else if (item.getStatus() == STATUS_DEPENDENCY_READY) {\r
- a = item;\r
- addCount();\r
- a.start();\r
- if (currentRunNumber == FrameworkBuildTask.MAX_CONCURRENT_THREAD_NUMBER) {\r
- break ;\r
- }\r
- }\r
- }\r
-\r
- if (a != null) {\r
- //\r
- // Exist ready thread\r
- //\r
- EdkLog.log(this, EdkLog.EDK_DEBUG, "Exist ready thread");\r
-\r
- } else if (existNoneReady && currentRunNumber == 0) {\r
- //\r
- // No active thread, but still have dependency not read thread\r
- //\r
- throw new BuildException("Existing some modules can't resolve depedencies. ");\r
- } else if (!existNoneReady && currentRunNumber == 0) {\r
- //\r
- // Current queue build finish, move to next\r
- //\r
- EdkLog.log(this, EdkLog.EDK_DEBUG, "Current queue build finish, move to next");\r
- ++currentQueueCode;\r
- continue ;\r
- } else {\r
- //\r
- // active thread exist, but no ready thread\r
- //\r
- EdkLog.log(this, EdkLog.EDK_DEBUG, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber);\r
- }\r
-\r
- try {\r
- deamonSemaphore.wait();\r
- \r
- //\r
- // if find error. Waiting running threads to finish\r
- //\r
- if (errorModule != null) {\r
- while (currentRunNumber > 0) {\r
- deamonSemaphore.wait();\r
- }\r
- \r
- GenBuildLogger.setCacheEnable(false);\r
- \r
- GenBuildLogger.flushErrorModuleLog(errorModule);\r
- \r
- EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log"));\r
- \r
- throw new BuildException(errorModule + " build error. ");\r
- }\r
- } catch (InterruptedException ex) {\r
- BuildException e = new BuildException("Thread wait Error. \n" + ex.getMessage());\r
- e.setStackTrace(ex.getStackTrace());\r
- throw e;\r
- }\r
- }\r
- }\r
- \r
- GenBuildLogger.setCacheEnable(false);\r
- //\r
- // call fvs, postbuild\r
- //\r
- ant = new Ant();\r
- ant.setProject(getProject());\r
- ant.setAntfile(platformBuildFile);\r
- ant.setTarget("fvs");\r
- ant.setInheritAll(true);\r
- ant.init();\r
- ant.execute();\r
- \r
- ant = new Ant();\r
- ant.setProject(getProject());\r
- ant.setAntfile(platformBuildFile);\r
- ant.setTarget("postbuild");\r
- ant.setInheritAll(true);\r
- ant.init();\r
- ant.execute();\r
- \r
- EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log"));\r
- }\r
-\r
- \r
- /**\r
- Parse all modules listed in FPD file. \r
- **/\r
- void parseModuleSAFiles() throws EdkException{\r
- \r
- Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();\r
-\r
- //\r
- // For every Module lists in FPD file.\r
- //\r
- Set<FpdModuleIdentification> keys = moduleSAs.keySet();\r
- Iterator<FpdModuleIdentification> iter = keys.iterator();\r
- while (iter.hasNext()) {\r
- FpdModuleIdentification fpdModuleId = iter.next();\r
- \r
- //\r
- // Generate GenBuildThread\r
- //\r
- GenBuildThread genBuildThread = new GenBuildThread(fpdModuleId.getModule(), fpdModuleId.getArch());\r
- genBuildThread.setParentModuleId(null);\r
- genBuildThread.setProject(getProject());\r
- \r
- Set<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();\r
- \r
- GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));\r
- \r
- //\r
- // Add all dependent Library Instance\r
- //\r
- saq.push(GlobalData.getDoc(fpdModuleId));\r
-\r
- ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
- saq.pop();\r
- \r
- for (int i = 0; i < libinstances.length; i++) {\r
- FpdModuleIdentification libFpdModuleId = new FpdModuleIdentification(libinstances[i], fpdModuleId.getArch());\r
- //\r
- // Add to dependencies\r
- //\r
- dependencies.add(libFpdModuleId);\r
- \r
- //\r
- // Create thread for library instances\r
- //\r
- GenBuildThread liBuildThread = new GenBuildThread(libinstances[i], fpdModuleId.getArch());\r
- liBuildThread.setParentModuleId(fpdModuleId.getModule());\r
- liBuildThread.setProject(getProject());\r
- liBuildThread.setStatus(STATUS_DEPENDENCY_READY);\r
- liBuildThread.setHighPriority(true);\r
- allThreads.put(libFpdModuleId, liBuildThread);\r
- \r
- updateFvs("libqueue", libFpdModuleId);\r
- \r
- saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));\r
- GlobalData.addMsaBuildOption(libinstances[i], parseMsaBuildOptions(false));\r
- GlobalData.addMsaFamilyBuildOption(libinstances[i], parseMsaBuildOptions(true));\r
- saq.pop();\r
- }\r
- \r
- genBuildThread.setDependencies(dependencies);\r
- \r
-// if (dependencies.size() == 0) {\r
- genBuildThread.setStatus(STATUS_DEPENDENCY_READY);\r
-// }\r
- \r
- allThreads.put(fpdModuleId, genBuildThread);\r
- \r
- //\r
- // Put fpdModuleId to the corresponding FV\r
- //\r
- saq.push(GlobalData.getDoc(fpdModuleId));\r
- String fvBinding = saq.getModuleFvBindingKeyword();\r
-\r
- fpdModuleId.setFvBinding(fvBinding);\r
- updateFvs(fvBinding, fpdModuleId);\r
-\r
- //\r
- // Prepare for out put file name\r
- //\r
- ModuleIdentification moduleId = fpdModuleId.getModule();\r
-\r
- String baseName = saq.getModuleOutputFileBasename();\r
- \r
- if (baseName == null) {\r
- baseName = moduleId.getName();\r
- }\r
- outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar\r
- + moduleId.getGuid() + "-" + baseName\r
- + getSuffix(moduleId.getModuleType()));\r
-\r
- //\r
- // parse module build options, if any\r
- //\r
- GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));\r
- GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));\r
- \r
- //\r
- // parse MSA build options\r
- //\r
- GlobalData.addMsaBuildOption(moduleId, parseMsaBuildOptions(false));\r
- GlobalData.addMsaFamilyBuildOption(moduleId, parseMsaBuildOptions(true));\r
-\r
- saq.pop();\r
- }\r
- }\r
- \r
- private boolean isContain(String[] list, String item) {\r
- for (int i = 0; i < list.length; i++) {\r
- if (list[i].equalsIgnoreCase(item)) {\r
- return true;\r
- }\r
- }\r
- return false;\r
- }\r
- \r
- public synchronized static void addCount() {\r
- synchronized (countSemaphore) {\r
- ++currentRunNumber;\r
- }\r
- }\r
- \r
- public synchronized static void subCount() {\r
- synchronized (countSemaphore) {\r
- --currentRunNumber;\r
- --remainNumber;\r
- }\r
- }\r
- \r
- private void updateTaskName(int percentage){\r
- int number = percentage/10;\r
- StringBuffer str = new StringBuffer(9);\r
- for(int i = 0; i < 9; i++) {\r
- if (i < number) {\r
- str.append('>');\r
- } else {\r
- str.append('.');\r
- }\r
- }\r
- this.setTaskName(str.toString());\r
- }\r
-}\r