+++ /dev/null
-/** @file FrameworkBuildTask.java\r
- \r
- The file is ANT task to find MSA or FPD file and build them. \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;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.util.Hashtable;\r
-import java.util.Iterator;\r
-import java.util.LinkedHashSet;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.apache.tools.ant.BuildException;\r
-import org.apache.tools.ant.Task;\r
-import org.tianocore.build.exception.AutoGenException;\r
-import org.tianocore.build.exception.GenBuildException;\r
-import org.tianocore.build.exception.PcdAutogenException;\r
-import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;\r
-import org.tianocore.build.fpd.FpdParserForThread;\r
-import org.tianocore.build.fpd.FpdParserTask;\r
-import org.tianocore.build.global.GenBuildLogger;\r
-import org.tianocore.build.global.GlobalData;\r
-import org.tianocore.build.toolchain.ConfigReader;\r
-import org.tianocore.build.toolchain.ToolChainInfo;\r
-import org.tianocore.common.definitions.ToolDefinitions;\r
-import org.tianocore.common.exception.EdkException;\r
-import org.tianocore.common.logger.EdkLog;\r
-\r
-/**\r
- <p>\r
- <code>FrameworkBuildTask</code> is an Ant task. The main function is finding\r
- and processing a FPD or MSA file, then building a platform or stand-alone \r
- module. \r
- \r
- <p>\r
- The task search current directory and find out all MSA and FPD files by file\r
- extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a\r
- stand-alone module. The ACTIVE_PLATFORM policy is: \r
- \r
- <pre>\r
- 1. More than one MSA files, report error; \r
- 2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;\r
- 3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;\r
- 4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;\r
- 5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;\r
- 6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;\r
- 7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, Report Error!\r
- </pre>\r
- \r
- <p>\r
- Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].\r
- And load all system environment variables to Ant properties. \r
- \r
- <p>\r
- The usage for this task is : \r
- \r
- <pre>\r
- <FrameworkBuild type="cleanall" />\r
- </pre>\r
- \r
- @since GenBuild 1.0\r
-**/\r
-public class FrameworkBuildTask extends Task{\r
-\r
- private Set<File> fpdFiles = new LinkedHashSet<File>();\r
- \r
- private Set<File> msaFiles = new LinkedHashSet<File>();\r
- \r
- ///\r
- /// This is only for none-multi-thread build to reduce overriding message\r
- ///\r
- public static Hashtable<String, String> originalProperties = new Hashtable<String, String>();\r
- \r
- String toolsDefFilename = ToolDefinitions.DEFAULT_TOOLS_DEF_FILE_PATH;\r
- \r
- String targetFilename = ToolDefinitions.TARGET_FILE_PATH;\r
- \r
- String dbFilename = ToolDefinitions.FRAMEWORK_DATABASE_FILE_PATH;\r
- \r
- String activePlatform = null;\r
-\r
- ///\r
- /// The flag to present current is multi-thread enabled\r
- ///\r
- public static boolean multithread = false;\r
-\r
- ///\r
- /// The concurrent thread number\r
- ///\r
- public static int MAX_CONCURRENT_THREAD_NUMBER = 2;\r
-\r
- ///\r
- /// there are three type: all (build), clean and cleanall\r
- ///\r
- private String type = "all";\r
- \r
- public void execute() throws BuildException {\r
- //\r
- // set Logger\r
- //\r
- GenBuildLogger logger = new GenBuildLogger(getProject());\r
- EdkLog.setLogLevel(EdkLog.EDK_DEBUG);\r
- EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL"));\r
- EdkLog.setLogger(logger);\r
- \r
- try {\r
- processFrameworkBuild();\r
- }catch (BuildException e) {\r
- //\r
- // Add more logic process here\r
- //\r
- BuildException buildException = new BuildException(e.getMessage());\r
- buildException.setStackTrace(e.getStackTrace());\r
- throw buildException;\r
- } catch (PcdAutogenException e) {\r
- //\r
- // Add more logic process here\r
- //\r
- BuildException buildException = new BuildException(e.getMessage());\r
- buildException.setStackTrace(e.getStackTrace());\r
- throw buildException;\r
- } catch (AutoGenException e) {\r
- //\r
- // Add more logic process here\r
- //\r
- BuildException buildException = new BuildException(e.getMessage());\r
- buildException.setStackTrace(e.getStackTrace());\r
- throw buildException;\r
- } catch (PlatformPcdPreprocessBuildException e) {\r
- //\r
- // Add more logic process here\r
- //\r
- BuildException buildException = new BuildException(e.getMessage());\r
- buildException.setStackTrace(e.getStackTrace());\r
- throw buildException;\r
- } catch (GenBuildException e) {\r
- //\r
- // Add more logic process here\r
- //\r
- BuildException buildException = new BuildException(e.getMessage());\r
- buildException.setStackTrace(e.getStackTrace());\r
- throw buildException;\r
- } catch (EdkException e) {\r
- //\r
- // Add more logic process here\r
- //\r
- BuildException buildException = new BuildException(e.getMessage());\r
- buildException.setStackTrace(e.getStackTrace());\r
- throw buildException;\r
- }\r
- }\r
- \r
- private void processFrameworkBuild() throws EdkException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException {\r
- try {\r
- //\r
- // Get current working dir\r
- //\r
- File dummyFile = new File(".");\r
- File cwd = dummyFile.getCanonicalFile();\r
- File[] files = cwd.listFiles();\r
- \r
- //\r
- // Scan current dir, and find out all .FPD and .MSA files\r
- //\r
- for (int i = 0; i < files.length; i++) {\r
- if (files[i].isFile()) {\r
- if (files[i].getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {\r
- //\r
- // Found FPD file\r
- //\r
- fpdFiles.add(files[i]);\r
- } else if (files[i].getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {\r
- //\r
- // Found MSA file\r
- //\r
- msaFiles.add(files[i]);\r
- }\r
- }\r
- }\r
- } catch (IOException ex) {\r
- BuildException buildException = new BuildException("Scanning current directory error. \n" + ex.getMessage());\r
- buildException.setStackTrace(ex.getStackTrace());\r
- throw buildException;\r
- }\r
- \r
- //\r
- // Import all system environment variables to ANT properties\r
- //\r
- importSystemEnvVariables();\r
- \r
- //\r
- // Read target.txt file\r
- //\r
- readTargetFile();\r
-\r
- //\r
- // Global Data initialization\r
- //\r
- File workspacePath = new File(getProject().getProperty("WORKSPACE"));\r
- getProject().setProperty("WORKSPACE_DIR", workspacePath.getPath().replaceAll("(\\\\)", "/"));\r
- GlobalData.initInfo(getProject(), dbFilename, workspacePath.getPath(), toolsDefFilename);\r
- \r
- //\r
- // If find MSA file and ACTIVE_PLATFORM is set, build the module; \r
- // else fail build. \r
- // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM. \r
- // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform; \r
- // If find more than one FPD files, report error. \r
- //\r
- File buildFile = null;\r
- if (msaFiles.size() > 0) {\r
- if (activePlatform == null) {\r
- throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename + "]. ");\r
- }\r
- //\r
- // Build the single module\r
- //\r
- buildFile = msaFiles.toArray(new File[1])[0];\r
- } else if (activePlatform != null) {\r
- buildFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);\r
- } else if (fpdFiles.size() == 1) {\r
- buildFile = fpdFiles.toArray(new File[1])[0];\r
- } else if (fpdFiles.size() > 1) {\r
- throw new BuildException("Found " + fpdFiles.size() + " FPD files in current dir. ");\r
- }\r
- \r
- //\r
- // If there is no build files or FPD files or MSA files, stop build\r
- //\r
- else {\r
- throw new BuildException("Can't find any FPD or MSA files in the current directory. ");\r
- }\r
-\r
- //\r
- // Build every FPD files (PLATFORM build)\r
- //\r
- if (buildFile.getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {\r
- EdkLog.log(this, "Processing the FPD file [" + buildFile.getPath() + "] ..>> ");\r
- //\r
- // Iff for platform build will enable the multi-thread if set in target.txt\r
- //\r
- if (multithread && type.equalsIgnoreCase("all")) {\r
- EdkLog.log(this, "Multi-thread build is enabled. ");\r
- FpdParserForThread fpdParserForThread = new FpdParserForThread();\r
- fpdParserForThread.setType(type);\r
- fpdParserForThread.setProject(getProject());\r
- fpdParserForThread.setFpdFile(buildFile);\r
- fpdParserForThread.perform();\r
- return ;\r
- }\r
- \r
- FpdParserTask fpdParserTask = new FpdParserTask();\r
- fpdParserTask.setType(type);\r
- fpdParserTask.setProject(getProject());\r
- fpdParserTask.setFpdFile(buildFile);\r
- fpdParserTask.perform();\r
- \r
- //\r
- // If cleanall delete the Platform_build.xml\r
- //\r
- if (type.compareTo("cleanall") == 0) {\r
- File platformBuildFile = \r
- new File(getProject().getProperty("BUILD_DIR") \r
- + File.separatorChar \r
- + getProject().getProperty("PLATFORM") \r
- + "_build.xml");\r
- platformBuildFile.deleteOnExit();\r
- }\r
- }\r
- \r
- //\r
- // Build every MSA files (SINGLE MODULE BUILD)\r
- //\r
- else if (buildFile.getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {\r
- if (multithread) {\r
- EdkLog.log(this, EdkLog.EDK_WARNING, "Multi-Thead do not take effect on Stand-Alone (Single) module build. ");\r
- multithread = false;\r
- }\r
- File tmpFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);\r
- EdkLog.log(this, "Using the FPD file [" + tmpFile.getPath() + "] for the active platform. ");\r
-\r
- File[] moduleFiles = msaFiles.toArray(new File[msaFiles.size()]);\r
- for (int i = 0; i < moduleFiles.length; ++i) {\r
- EdkLog.log(this, "Processing the MSA file [" + moduleFiles[i].getPath() + "] ..>> ");\r
- GenBuildTask genBuildTask = new GenBuildTask();\r
- genBuildTask.setSingleModuleBuild(true);\r
- genBuildTask.setType(type);\r
- getProject().setProperty("PLATFORM_FILE", activePlatform);\r
- if( !multithread) {\r
- originalProperties.put("PLATFORM_FILE", activePlatform);\r
- }\r
- genBuildTask.setProject(getProject());\r
- genBuildTask.setMsaFile(moduleFiles[i]);\r
- genBuildTask.perform();\r
- }\r
- }\r
- }\r
- \r
- /**\r
- Import system environment variables to ANT properties. If system variable \r
- already exiests in ANT properties, skip it.\r
- \r
- **/\r
- private void importSystemEnvVariables() {\r
- Map<String, String> sysProperties = System.getenv();\r
- Iterator<String> iter = sysProperties.keySet().iterator();\r
- while (iter.hasNext()) {\r
- String name = iter.next();\r
- \r
- //\r
- // If system environment variable is not in ANT properties, add it\r
- //\r
- if (getProject().getProperty(name) == null) {\r
- getProject().setProperty(name, sysProperties.get(name));\r
- }\r
- }\r
- \r
- Hashtable allProperties = getProject().getProperties();\r
- Iterator piter = allProperties.keySet().iterator();\r
- while (piter.hasNext()) {\r
- String name = (String)piter.next();\r
- originalProperties.put(new String(name), new String((String)allProperties.get(name)));\r
- }\r
- }\r
-\r
- public void setType(String type) {\r
- this.type = type.toLowerCase();\r
- }\r
- \r
- private void readTargetFile() throws EdkException{\r
- String targetFile = getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + targetFilename;\r
- \r
- String[][] targetFileInfo = ConfigReader.parse(getProject(), targetFile);\r
- \r
- //\r
- // Get ToolChain Info from target.txt\r
- //\r
- ToolChainInfo envToolChainInfo = new ToolChainInfo(); \r
- String str = getValue(ToolDefinitions.TARGET_KEY_TARGET, targetFileInfo);\r
- if (str == null || str.trim().equals("")) {\r
- envToolChainInfo.addTargets("*");\r
- } else {\r
- envToolChainInfo.addTargets(str);\r
- }\r
- str = getValue(ToolDefinitions.TARGET_KEY_TOOLCHAIN, targetFileInfo);\r
- if (str == null || str.trim().equals("")) {\r
- envToolChainInfo.addTagnames("*");\r
- } else {\r
- envToolChainInfo.addTagnames(str);\r
- }\r
- str = getValue(ToolDefinitions.TARGET_KEY_ARCH, targetFileInfo);\r
- if (str == null || str.trim().equals("")) {\r
- envToolChainInfo.addArchs("*");\r
- } else {\r
- envToolChainInfo.addArchs(str);\r
- }\r
- GlobalData.setToolChainEnvInfo(envToolChainInfo);\r
- \r
- str = getValue(ToolDefinitions.TARGET_KEY_TOOLS_DEF, targetFileInfo);\r
- if (str != null && str.trim().length() > 0) {\r
- toolsDefFilename = str;\r
- }\r
- \r
- str = getValue(ToolDefinitions.TARGET_KEY_ACTIVE_PLATFORM, targetFileInfo);\r
- if (str != null && ! str.trim().equals("")) {\r
- if ( ! str.endsWith(".fpd")) {\r
- throw new BuildException("FPD file's extension must be \"" + ToolDefinitions.FPD_EXTENSION + "\"!");\r
- }\r
- activePlatform = str;\r
- }\r
- \r
- str = getValue(ToolDefinitions.TARGET_KEY_MULTIPLE_THREAD, targetFileInfo);\r
- if (str != null && str.trim().equalsIgnoreCase("Enable")) {\r
- multithread = true;\r
- }\r
-\r
- str = getValue(ToolDefinitions.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER, targetFileInfo);\r
- //\r
- // Need to check the # of threads iff multithread is enabled.\r
- //\r
- if ((multithread) && (str != null )) {\r
- try {\r
- int threadNum = Integer.parseInt(str);\r
- if (threadNum > 0) {\r
- MAX_CONCURRENT_THREAD_NUMBER = threadNum;\r
- }\r
- } catch (Exception ex) {\r
- //\r
- // Give a warning message, and keep the default value\r
- //\r
- EdkLog.log(this, EdkLog.EDK_WARNING, "Incorrent number specified for MAX_CONCURRENT_THREAD_NUMBER in file [" + targetFilename + "]");\r
- }\r
- }\r
- }\r
- \r
- private String getValue(String key, String[][] map) {\r
- for (int i = 0; i < map[0].length; i++){\r
- if (key.equalsIgnoreCase(map[0][i])) {\r
- return map[1][i];\r
- }\r
- }\r
- return null;\r
- }\r
-}\r