Check In tool source code based on Build tool project revision r1655.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
217
BaseTools/Source/Python/Common/ToolDefClassObject.py
Normal file
217
BaseTools/Source/Python/Common/ToolDefClassObject.py
Normal file
@ -0,0 +1,217 @@
|
||||
## @file
|
||||
# This file is used to define each component of tools_def.txt file
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
import os
|
||||
import re
|
||||
import EdkLogger
|
||||
|
||||
from Dictionary import *
|
||||
from BuildToolError import *
|
||||
from TargetTxtClassObject import *
|
||||
|
||||
##
|
||||
# Static vailabes used for pattern
|
||||
#
|
||||
gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))')
|
||||
gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))')
|
||||
gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)")
|
||||
gDefaultToolsDefFile = "Conf/tools_def.txt"
|
||||
|
||||
## ToolDefClassObject
|
||||
#
|
||||
# This class defined content used in file tools_def.txt
|
||||
#
|
||||
# @param object: Inherited from object class
|
||||
# @param Filename: Input value for full path of tools_def.txt
|
||||
#
|
||||
# @var ToolsDefTxtDictionary: To store keys and values defined in target.txt
|
||||
# @var MacroDictionary: To store keys and values defined in DEFINE statement
|
||||
#
|
||||
class ToolDefClassObject(object):
|
||||
def __init__(self, FileName = None):
|
||||
self.ToolsDefTxtDictionary = {}
|
||||
self.MacroDictionary = {}
|
||||
for Env in os.environ:
|
||||
self.MacroDictionary["ENV(%s)" % Env] = os.environ[Env]
|
||||
|
||||
if FileName != None:
|
||||
self.LoadToolDefFile(FileName)
|
||||
|
||||
## LoadToolDefFile
|
||||
#
|
||||
# Load target.txt file and parse it, return a set structure to store keys and values
|
||||
#
|
||||
# @param Filename: Input value for full path of tools_def.txt
|
||||
#
|
||||
def LoadToolDefFile(self, FileName):
|
||||
FileContent = []
|
||||
if os.path.isfile(FileName):
|
||||
try:
|
||||
F = open(FileName,'r')
|
||||
FileContent = F.readlines()
|
||||
except:
|
||||
EdkLogger.error("tools_def.txt parser", FILE_OPEN_FAILURE, ExtraData=FileName)
|
||||
else:
|
||||
EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName)
|
||||
|
||||
self.ToolsDefTxtDatabase = {
|
||||
TAB_TOD_DEFINES_TARGET : [],
|
||||
TAB_TOD_DEFINES_TOOL_CHAIN_TAG : [],
|
||||
TAB_TOD_DEFINES_TARGET_ARCH : [],
|
||||
TAB_TOD_DEFINES_COMMAND_TYPE : []
|
||||
}
|
||||
|
||||
for Index in range(len(FileContent)):
|
||||
Line = FileContent[Index].strip()
|
||||
if Line == "" or Line[0] == '#':
|
||||
continue
|
||||
NameValuePair = Line.split("=", 1)
|
||||
if len(NameValuePair) != 2:
|
||||
EdkLogger.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index + 1))
|
||||
continue
|
||||
|
||||
Name = NameValuePair[0].strip()
|
||||
Value = NameValuePair[1].strip()
|
||||
|
||||
if Name == "IDENTIFIER":
|
||||
EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found identifier statement, skipped: %s" % ((Index + 1), Value))
|
||||
continue
|
||||
|
||||
MacroDefinition = gMacroDefPattern.findall(Name)
|
||||
if MacroDefinition != []:
|
||||
Done, Value = self.ExpandMacros(Value)
|
||||
if not Done:
|
||||
EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE,
|
||||
"Macro or Environment has not been defined",
|
||||
ExtraData=Value[4:-1], File=FileName, Line=Index+1)
|
||||
|
||||
MacroName = MacroDefinition[0].strip()
|
||||
self.MacroDictionary["DEF(%s)" % MacroName] = Value
|
||||
EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found macro: %s = %s" % ((Index + 1), MacroName, Value))
|
||||
continue
|
||||
|
||||
Done, Value = self.ExpandMacros(Value)
|
||||
if not Done:
|
||||
EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE,
|
||||
"Macro or Environment has not been defined",
|
||||
ExtraData=Value[4:-1], File=FileName, Line=Index+1)
|
||||
|
||||
List = Name.split('_')
|
||||
if len(List) != 5:
|
||||
EdkLogger.verbose("Line %d: Not a valid name of definition: %s" % ((Index + 1), Name))
|
||||
continue
|
||||
elif List[4] == '*':
|
||||
EdkLogger.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index + 1), Name))
|
||||
continue
|
||||
else:
|
||||
self.ToolsDefTxtDictionary[Name] = Value
|
||||
if List[0] != '*':
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] += [List[0]]
|
||||
if List[1] != '*':
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] += [List[1]]
|
||||
if List[2] != '*':
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] += [List[2]]
|
||||
if List[3] != '*':
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] += [List[3]]
|
||||
if List[4] == TAB_TOD_DEFINES_FAMILY and List[2] == '*' and List[3] == '*':
|
||||
if TAB_TOD_DEFINES_FAMILY not in self.ToolsDefTxtDatabase:
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {}
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value
|
||||
elif List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value
|
||||
elif self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] != Value:
|
||||
EdkLogger.verbose("Line %d: No override allowed for the family of a tool chain: %s" % ((Index + 1), Name))
|
||||
if List[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY and List[2] == '*' and List[3] == '*':
|
||||
if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolsDefTxtDatabase \
|
||||
or List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
|
||||
EdkLogger.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index + 1), Name))
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value
|
||||
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET]))
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]))
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH]))
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE]))
|
||||
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort()
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort()
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()
|
||||
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()
|
||||
|
||||
KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]
|
||||
for Index in range(3,-1,-1):
|
||||
for Key in dict(self.ToolsDefTxtDictionary):
|
||||
List = Key.split('_')
|
||||
if List[Index] == '*':
|
||||
for String in self.ToolsDefTxtDatabase[KeyList[Index]]:
|
||||
List[Index] = String
|
||||
NewKey = '%s_%s_%s_%s_%s' % tuple(List)
|
||||
if NewKey not in self.ToolsDefTxtDictionary:
|
||||
self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]
|
||||
continue
|
||||
del self.ToolsDefTxtDictionary[Key]
|
||||
elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:
|
||||
del self.ToolsDefTxtDictionary[Key]
|
||||
|
||||
## ExpandMacros
|
||||
#
|
||||
# Replace defined macros with real value
|
||||
#
|
||||
# @param Value: The string with unreplaced macros
|
||||
#
|
||||
# @retval Value: The string which has been replaced with real value
|
||||
#
|
||||
def ExpandMacros(self, Value):
|
||||
EnvReference = gEnvRefPattern.findall(Value)
|
||||
for Ref in EnvReference:
|
||||
if Ref not in self.MacroDictionary:
|
||||
return False, Ref
|
||||
Value = Value.replace(Ref, self.MacroDictionary[Ref])
|
||||
|
||||
MacroReference = gMacroRefPattern.findall(Value)
|
||||
for Ref in MacroReference:
|
||||
if Ref not in self.MacroDictionary:
|
||||
return False, Ref
|
||||
Value = Value.replace(Ref, self.MacroDictionary[Ref])
|
||||
|
||||
return True, Value
|
||||
|
||||
## ToolDefDict
|
||||
#
|
||||
# Load tools_def.txt in input workspace dir
|
||||
#
|
||||
# @param WorkSpace: Workspace dir
|
||||
#
|
||||
# @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt
|
||||
#
|
||||
def ToolDefDict(WorkSpace):
|
||||
Target = TargetTxtDict(WorkSpace)
|
||||
ToolDef = ToolDefClassObject()
|
||||
if DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary:
|
||||
gDefaultToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
|
||||
ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(WorkSpace, gDefaultToolsDefFile)))
|
||||
return ToolDef
|
||||
|
||||
##
|
||||
#
|
||||
# This acts like the main() function for the script, unless it is 'import'ed into another
|
||||
# script.
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
ToolDef = ToolDefDict(os.getenv("WORKSPACE"))
|
||||
pass
|
Reference in New Issue
Block a user