+++ /dev/null
-/** @file\r
- ToolChainFactory class.\r
- \r
- ToolChainFactory class parse all config files and get STD_FLAGS, GLOBAL_FLAGS,\r
- and also command path + name.\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
-**/\r
-package org.tianocore.build.toolchain;\r
-\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.StringTokenizer;\r
-import java.io.File;\r
-\r
-import org.apache.tools.ant.Project;\r
-\r
-\r
-/**\r
- This class parse all config files and get STD_FLAGS, GLOBAL_FLAGS, and also \r
- command path + name.\r
- \r
- @since GenBuild 1.0\r
-**/\r
-public class ToolChainFactory {\r
- ///\r
- /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC\r
- ///\r
- public final static String[] arch = { "EBC", "ARM", "IA32", "X64", "IPF",\r
- "PPC"};\r
-\r
- ///\r
- /// list of OS: Linux, Windows\r
- ///\r
- public final static String[] os = { "WINDOWS", "LINUX" };\r
-\r
- ///\r
- /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP\r
- ///\r
- public final static String[] commandType = { "CC", "LIB", "LINK", "ASL",\r
- "ASM", "ASMLINK", "PP" };\r
-\r
- ///\r
- /// default command name for every command\r
- ///\r
- public final static String[][] defaultCmdName = { { "CC", "cl" },\r
- { "LIB", "lib" }, { "LINK", "link" }, { "ASL", "iasl" },\r
- { "ASM", "ml" }, { "ASMLINK", "link" }, { "PP", "cl" } };\r
-\r
- private String confPath = ".";\r
- \r
- private String toolChainName = "MSFT";\r
-\r
- private String sTargetFilename = "target.txt";\r
-\r
- private String sToolsdefFilename = "tools_def.txt";\r
-\r
- private String sWorkspaceTarget = "WORKSPACE_TARGET";\r
-\r
- private String sTargetArch = "TARGET_ARCH";\r
-\r
- private HashMap<String,String[][]> filesMap = new HashMap<String,String[][]>();\r
- \r
- private HashMap<String,String> globalFlagsMap = new HashMap<String,String>();\r
- \r
- private String[][] globalFlagTable;\r
- \r
- private String currentTarget = "RELEASE";\r
-\r
- ///\r
- /// toolchain array list all results by parsing config files\r
- ///\r
- public static String[][] toolchain = null;\r
- \r
- /**\r
- Public construct method.\r
- **/\r
- public ToolChainFactory () {\r
- }\r
-\r
- /**\r
- Public construct method.\r
- \r
- @param project current ANT Project.\r
- **/\r
- public ToolChainFactory (Project project) {\r
- this.confPath = project.replaceProperties("${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Conf");\r
- }\r
- \r
- /**\r
- Public construct method.\r
- \r
- @param confPath the path of config files\r
- @param toolChainName TOOL_CHAIN name\r
- **/\r
- public ToolChainFactory (String confPath, String toolChainName) {\r
- this.confPath = confPath;\r
- //\r
- // If set tool used the set one, otherwise use default one.\r
- // toolChain used to define open tools define txt file.\r
- //\r
- if (toolChainName != null && toolChainName.length() > 0){\r
- this.toolChainName = toolChainName;\r
- }\r
- }\r
-\r
- /**\r
- Parse all config files, following are the detail steps:\r
- \r
- <ul>\r
- <li>Parse target.txt file. This file define the current build TARGET \r
- and supported ARCH list. </li>\r
- <li>Parse tools_def.txt file. This file define every command name, path\r
- and vendor. </li>\r
- <li>For every supported ARCH and Command Type, find out STD_FLAGS, \r
- GLOBAL_ADD_FLAGS, GLOBAL_SUB_FLAGS. </li>\r
- </ul>\r
- \r
- <p>Note that this method will be called only once during the whole build\r
- process. </p>\r
- **/\r
- public void setupToolChain() {\r
- if (toolchain != null) {\r
- return ;\r
- }\r
- Map<String, String> map = new HashMap<String, String>(40);\r
- //\r
- // parse target.txt\r
- //\r
- String[][] target = ConfigReader.parse(confPath, sTargetFilename);\r
- //\r
- // get workspace_target and initialize global flags setting\r
- //\r
- currentTarget = getValue(sWorkspaceTarget, target);\r
- parseGlobalSetting(currentTarget);\r
- String[] archList = getArchs(getValue(sTargetArch, target));\r
- \r
- //\r
- // If user write the ${toolChain}_Tools_Def.txt use this one,\r
- // otherwise used "tools_def.txt" file.\r
- //\r
- File tempFile = new File (confPath + File.separator + toolChainName.toLowerCase() + "_tools_def.txt");\r
- if (tempFile.exists()){\r
- sToolsdefFilename = toolChainName.toLowerCase() + "_tools_def.txt";\r
- }\r
- \r
- System.out.println("Tools definition file is: " + sToolsdefFilename);\r
- //\r
- // parse tools_def.txt\r
- //\r
- String[][] tools_def = ConfigReader.parse(confPath, sToolsdefFilename);\r
- //\r
- // for each arch find all command's path&name and flags\r
- //\r
- for (int i = 0; i < archList.length; i++) {\r
- for (int j = 0; j < commandType.length; j++) {\r
- //\r
- // Path & Name\r
- //\r
- map.put(archList[i] + "_" + commandType[j], getAbsoluteCmdPath(\r
- archList[i], commandType[j], tools_def));\r
- //\r
- // Flags: CMD_STD_FLAGS + CMD_GLOBAL_FLAGS + CMD_PROJ_FLAGS\r
- // ARCH_CMD_STD_FLAGS\r
- //\r
- map.put(archList[i] + "_" + commandType[j] + "_STD_FLAGS",\r
- getStdFlags(archList[i], commandType[j],\r
- tools_def));\r
- //\r
- // Flags:ARCH_CMD_VENDOR or ARCH_VENDOR\r
- //\r
- map.put(archList[i]+ "_"+commandType[j]+"_VENDOR", getVendorFlag(archList[i],\r
- commandType[j], tools_def));\r
- //\r
- // ARCH_CMD_GLOBAL_FLAGS\r
- //\r
- String[] globalFlags = getGlobalFlags(archList[i], commandType[j],\r
- tools_def);\r
- map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_ADD_FLAGS",\r
- globalFlags[0]);\r
- map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_SUB_FLAGS",\r
- globalFlags[1]);\r
- //\r
- // ARCH_CMD_GLOBAL_FLAGS, default is "".\r
- //\r
- map.put(archList[i] + "_" + commandType[j] + "_PROJ_FLAGS", "");\r
- }\r
- map.put(archList[i]+"_VENDOR", getVendorFlag(archList[i], null, tools_def));\r
- }\r
- Set keyset = map.keySet();\r
- Iterator iter = keyset.iterator();\r
- String[][] result = new String[map.size()][2];\r
- int i = 0;\r
- while (iter.hasNext()) {\r
- String key = (String) iter.next();\r
- result[i][0] = key;\r
- result[i++][1] = (String) map.get(key);\r
- }\r
- toolchain = result;\r
- }\r
-\r
- /**\r
- Get the standard flags (STD_FLAGS) for specified arch and command type. \r
- \r
- <ul>\r
- <li>Find out Vendor that cmd Command Type with arch ARCH used. The \r
- search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here\r
- we suppose default Vendor is MSFT.</li>\r
- <li>Search ${Vendor}_tools.txt file, and get the corrsponding flags. \r
- </li>\r
- </ul>\r
- \r
- @param arch the ARCH\r
- @param cmd the command type\r
- @param map detail flags information of tools_def.txt\r
- @return the standard flags of arch ARCH and cmd Command Type \r
- **/\r
- private String getStdFlags(String arch, String cmd, String[][] map) {\r
- //\r
- // first is to find out its Vendor in map\r
- // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"\r
- // Here we suppose default Vendor is MSFT.\r
- //\r
- String vendor = "MSFT";\r
- String str;\r
- if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {\r
- vendor = str;\r
- } else if ((str = getValue(arch + "_VENDOR", map)) != null) {\r
- vendor = str;\r
- }\r
- //\r
- // change to low letter\r
- //\r
- vendor = vendor.toLowerCase();\r
- //\r
- // parse the corresponding file and get arch_cmd value\r
- //\r
- String filename = vendor + "_tools.txt";\r
- String[][] flagsMap;\r
- if (filesMap.containsKey(filename)) {\r
- flagsMap = (String[][]) filesMap.get(filename);\r
- } else {\r
- //\r
- // read file and store in filesMap\r
- //\r
- flagsMap = ConfigReader.parse(confPath, vendor + "_tools.txt");\r
- filesMap.put(filename, flagsMap);\r
- }\r
- if ((str = getValue(arch + "_" + cmd, flagsMap)) != null) {\r
- return str;\r
- }\r
- return "";\r
- }\r
-\r
- /**\r
- Get the global flags (GLOBAL_ADD_FLAGS & GLOBAL_SUB_FLAGS) for specified \r
- arch and command type. \r
- \r
- <ul>\r
- <li>Find out Vendor that cmd Command Type with arch ARCH used. The \r
- search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here\r
- we suppose default Vendor is MSFT.</li>\r
- <li>Search efi_flags_table.txt file, and get the corrsponding flags. \r
- </li>\r
- </ul>\r
- \r
- @param arch the ARCH\r
- @param cmd the command type\r
- @param map detail flags information of tools_def.txt\r
- @return two values, first is GLOBAL_ADD_FLAGS and another value is \r
- GLOBAL_SUB_FLAGS\r
- **/\r
- private String[] getGlobalFlags(String arch, String cmd, String[][] map) {\r
- String addStr = "";\r
- String subStr = "";\r
- //\r
- // first is to find out its Vendor in map\r
- // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"\r
- // Here we suppose default Vendor is MSFT.\r
- //\r
- String vendor = "MSFT";\r
- String str;\r
- if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {\r
- vendor = str;\r
- } else if ((str = getValue(arch + "_VENDOR", map)) != null) {\r
- vendor = str;\r
- }\r
- //\r
- // parse global flags table\r
- //\r
- if (globalFlagTable == null) {\r
- globalFlagTable = ConfigReader.parseTable(confPath, "efi_flags_table.txt");\r
- }\r
- for (int i=0; i < globalFlagTable.length; i++){\r
- String[] item = globalFlagTable[i];\r
- if (item[2].equalsIgnoreCase(vendor + "_" + arch + "_" + cmd)){\r
- //\r
- // if item[0] == item[1] is existed in globalFlagsMap\r
- //\r
- if (globalFlagsMap.containsKey(item[0])){\r
- if( item[1].equalsIgnoreCase((String)globalFlagsMap.get(item[0]))){\r
- addStr += item[3] + " ";\r
- subStr += item[4] + " ";\r
- }\r
- }\r
- }\r
- }\r
- \r
- return new String[]{addStr, subStr};\r
- }\r
-\r
- /**\r
- Find out command path and command name. \r
- \r
- <pre>\r
- Command path searching sequence in tools_def.txt file:\r
- Path: ARCH_CMD_PATH -> ARCH_PATH -> Set to "".\r
- \r
- Command name searching sequence in tools_def.txt file:\r
- Name: ARCH_CMD_NAME -> CMD_NAME -> Default Value.\r
- </pre>\r
- \r
- @param arch the ARCH\r
- @param cmd the Command Type\r
- @param map detail flags information of tools_def.txt\r
- @return the absolute command path and name\r
- **/\r
- private String getAbsoluteCmdPath(String arch, String cmd, String[][] map) {\r
- String path = "";\r
- String name = "";\r
- String str;\r
- //\r
- // find Path\r
- //\r
- if ((str = getValue(arch + "_" + cmd + "_PATH", map)) != null) {\r
- path = str;\r
- } else if ((str = getValue(arch + "_PATH", map)) != null) {\r
- path = str;\r
- }\r
- //\r
- // find Name\r
- //\r
- if ((str = getValue(arch + "_" + cmd + "_NAME", map)) != null) {\r
- name = str;\r
- } else if ((str = getValue(cmd + "_NAME", map)) != null) {\r
- name = str;\r
- } else {\r
- name = getValue(cmd, defaultCmdName);\r
- }\r
- if (path.equalsIgnoreCase("")) {\r
- return name;\r
- }\r
- return path + File.separatorChar + name;\r
- }\r
-\r
- /**\r
- Find out all global flags value, such as EFI_DEBUG equal YES or NO. Here \r
- are three type files: global_efi_flags.txt, ${TARGET}_efi_flags.txt, \r
- my_efi_flags.txt. global_efi_flags.txt with the highest priority while \r
- my_efi_flags.txt with the lowest priority. \r
- \r
- <p>All global flags value will store in <code>globalFlagsMap</code> for \r
- getGlobalFlags using. </p> \r
- \r
- @param target current build TARGET value\r
- **/\r
- private void parseGlobalSetting(String target){\r
- //\r
- // parse global_efi_flags -> ${TARGET}_efi_flags -> my_efi_flags\r
- // parse global_efi_flags\r
- //\r
- String[][] map = ConfigReader.parse(confPath, "global_efi_flags.txt");\r
- for (int i = 0; i < map.length; i++){\r
- if(globalFlagsMap.containsKey(map[i][0])){\r
- globalFlagsMap.remove(map[i][0]);\r
- }\r
- globalFlagsMap.put(map[i][0], map[i][1]);\r
- }\r
- //\r
- // parse ${TARGET}_efi_flags\r
- //\r
- map = ConfigReader.parse(confPath, target.toLowerCase() + "_efi_flags.txt");\r
- for (int i = 0; i < map.length; i++){\r
- if(globalFlagsMap.containsKey(map[i][0])){\r
- globalFlagsMap.remove(map[i][0]);\r
- }\r
- globalFlagsMap.put(map[i][0], map[i][1]);\r
- }\r
- //\r
- // parse my_efi_flags.txt\r
- //\r
- map = ConfigReader.parse(confPath, "my_efi_flags.txt");\r
- for (int i = 0; i < map.length; i++){\r
- if(globalFlagsMap.containsKey(map[i][0])){\r
- globalFlagsMap.remove(map[i][0]);\r
- }\r
- globalFlagsMap.put(map[i][0], map[i][1]);\r
- }\r
- }\r
- \r
- /**\r
- Find value with key from map. If not found, return null. \r
- \r
- <p>Note that default is case-insensitive</p>\r
- \r
- @param key key value\r
- @param map mapping information\r
- @return the related value of key\r
- **/\r
- private String getValue(String key, String[][] map) {\r
- return getValue(key, map, false);\r
- }\r
-\r
- /**\r
- Find value with key from map. If not found, return null. \r
- \r
- @param key key value\r
- @param map mapping information\r
- @param caseSensitive whether case sesitive or not\r
- @return the related value of key\r
- **/\r
- private String getValue(String key, String[][] map, boolean caseSensitive) {\r
- for (int i = 0; i < map.length; i++) {\r
- if (caseSensitive) {\r
- if (key.compareTo(map[i][0]) == 0) {\r
- return map[i][1];\r
- }\r
- } else {\r
- if (key.compareToIgnoreCase(map[i][0]) == 0) {\r
- return map[i][1];\r
- }\r
- }\r
- }\r
- return null;\r
- }\r
-\r
- /**\r
- Find value with key from <code>toolchain</code>. If not found, return null. \r
- \r
- @param key key value\r
- @return the related value of key\r
- **/\r
- public static String getValue(String key){\r
- for (int i = 0; i < toolchain.length; i++) {\r
- if (key.compareToIgnoreCase(toolchain[i][0]) == 0) {\r
- return toolchain[i][1];\r
- }\r
- }\r
- return null;\r
- }\r
- \r
- /**\r
- Get Arch list from a string separated with comma. \r
- \r
- <pre>\r
- For example:\r
- If the arch string is "IA32, X64, EBC".\r
- Then the result is {"IA32", "X64", "EBC"}. \r
- </pre>\r
- \r
- @param arch string separated with comma\r
- @return Arch list\r
- **/\r
- public String[] getArchs(String arch) {\r
- if (arch == null) {\r
- return new String[0];\r
- }\r
- StringTokenizer st = new StringTokenizer(arch, " \t,");\r
- String[] archs = new String[st.countTokens()];\r
- int i = 0;\r
- while (st.hasMoreTokens()) {\r
- archs[i++] = st.nextToken().toUpperCase();\r
- }\r
- return archs;\r
- }\r
-\r
- /**\r
- Get current target value.\r
- \r
- @return current target value\r
- **/\r
- public String getCurrentTarget() {\r
- return currentTarget;\r
- }\r
-\r
- /**\r
- Find out Vendor that cmd Command Type with arch ARCH used. The \r
- search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here\r
- we suppose default Vendor is MSFT.\r
- \r
- @param arch the ARCH\r
- @param cmd the Command Type\r
- @param map detail flags information of tools_def.txt\r
- @return the related vendor name\r
- **/\r
- public String getVendorFlag (String arch, String cmdType, String[][] map){\r
- //\r
- // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"\r
- // Here we suppose default Vendor is MSFT.\r
- //\r
- String str;\r
- String vendor = "";\r
- if (cmdType != null){\r
- if ((str = getValue(arch + "_" + cmdType + "_VENDOR", map)) != null) {\r
- vendor = str; \r
- }else {\r
- vendor = "";\r
- }\r
- }else if (arch != null){\r
- if ((str = getValue(arch + "_VENDOR", map)) != null) {\r
- vendor = str; \r
- }else {\r
- vendor = "";\r
- }\r
- }\r
- return vendor;\r
- }\r
- \r
-}\r