2 # This file is used to define each component of tools_def.txt file
4 # Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 from Dictionary
import *
22 from BuildToolError
import *
23 from TargetTxtClassObject
import *
26 # Static variables used for pattern
28 gMacroRefPattern
= re
.compile('(DEF\([^\(\)]+\))')
29 gEnvRefPattern
= re
.compile('(ENV\([^\(\)]+\))')
30 gMacroDefPattern
= re
.compile("DEFINE\s+([^\s]+)")
31 gDefaultToolsDefFile
= "Conf/tools_def.txt"
35 # This class defined content used in file tools_def.txt
37 # @param object: Inherited from object class
38 # @param Filename: Input value for full path of tools_def.txt
40 # @var ToolsDefTxtDictionary: To store keys and values defined in target.txt
41 # @var MacroDictionary: To store keys and values defined in DEFINE statement
43 class ToolDefClassObject(object):
44 def __init__(self
, FileName
= None):
45 self
.ToolsDefTxtDictionary
= {}
46 self
.MacroDictionary
= {}
47 for Env
in os
.environ
:
48 self
.MacroDictionary
["ENV(%s)" % Env
] = os
.environ
[Env
]
51 self
.LoadToolDefFile(FileName
)
55 # Load target.txt file and parse it, return a set structure to store keys and values
57 # @param Filename: Input value for full path of tools_def.txt
59 def LoadToolDefFile(self
, FileName
):
61 if os
.path
.isfile(FileName
):
63 F
= open(FileName
,'r')
64 FileContent
= F
.readlines()
66 EdkLogger
.error("tools_def.txt parser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
68 EdkLogger
.error("tools_def.txt parser", FILE_NOT_FOUND
, ExtraData
=FileName
)
70 self
.ToolsDefTxtDatabase
= {
71 TAB_TOD_DEFINES_TARGET
: [],
72 TAB_TOD_DEFINES_TOOL_CHAIN_TAG
: [],
73 TAB_TOD_DEFINES_TARGET_ARCH
: [],
74 TAB_TOD_DEFINES_COMMAND_TYPE
: []
77 for Index
in range(len(FileContent
)):
78 Line
= FileContent
[Index
].strip()
79 if Line
== "" or Line
[0] == '#':
81 NameValuePair
= Line
.split("=", 1)
82 if len(NameValuePair
) != 2:
83 EdkLogger
.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index
+ 1))
86 Name
= NameValuePair
[0].strip()
87 Value
= NameValuePair
[1].strip()
89 if Name
== "IDENTIFIER":
90 EdkLogger
.debug(EdkLogger
.DEBUG_8
, "Line %d: Found identifier statement, skipped: %s" % ((Index
+ 1), Value
))
93 MacroDefinition
= gMacroDefPattern
.findall(Name
)
94 if MacroDefinition
!= []:
95 Done
, Value
= self
.ExpandMacros(Value
)
97 EdkLogger
.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE
,
98 "Macro or Environment has not been defined",
99 ExtraData
=Value
[4:-1], File
=FileName
, Line
=Index
+1)
101 MacroName
= MacroDefinition
[0].strip()
102 self
.MacroDictionary
["DEF(%s)" % MacroName
] = Value
103 EdkLogger
.debug(EdkLogger
.DEBUG_8
, "Line %d: Found macro: %s = %s" % ((Index
+ 1), MacroName
, Value
))
106 Done
, Value
= self
.ExpandMacros(Value
)
108 EdkLogger
.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE
,
109 "Macro or Environment has not been defined",
110 ExtraData
=Value
[4:-1], File
=FileName
, Line
=Index
+1)
112 List
= Name
.split('_')
114 EdkLogger
.verbose("Line %d: Not a valid name of definition: %s" % ((Index
+ 1), Name
))
117 EdkLogger
.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index
+ 1), Name
))
120 self
.ToolsDefTxtDictionary
[Name
] = Value
122 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
] += [List
[0]]
124 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
] += [List
[1]]
126 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
] += [List
[2]]
128 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
] += [List
[3]]
129 if List
[4] == TAB_TOD_DEFINES_FAMILY
and List
[2] == '*' and List
[3] == '*':
130 if TAB_TOD_DEFINES_FAMILY
not in self
.ToolsDefTxtDatabase
:
131 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
] = {}
132 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
][List
[1]] = Value
133 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] = {}
134 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][List
[1]] = Value
135 elif List
[1] not in self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
]:
136 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
][List
[1]] = Value
137 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][List
[1]] = Value
138 elif self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
][List
[1]] != Value
:
139 EdkLogger
.verbose("Line %d: No override allowed for the family of a tool chain: %s" % ((Index
+ 1), Name
))
140 if List
[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY
and List
[2] == '*' and List
[3] == '*':
141 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in self
.ToolsDefTxtDatabase \
142 or List
[1] not in self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
]:
143 EdkLogger
.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index
+ 1), Name
))
144 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][List
[1]] = Value
146 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
]))
147 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
]))
148 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
]))
149 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
]))
151 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
].sort()
152 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
].sort()
153 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
].sort()
154 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
].sort()
156 KeyList
= [TAB_TOD_DEFINES_TARGET
, TAB_TOD_DEFINES_TOOL_CHAIN_TAG
, TAB_TOD_DEFINES_TARGET_ARCH
, TAB_TOD_DEFINES_COMMAND_TYPE
]
157 for Index
in range(3,-1,-1):
158 for Key
in dict(self
.ToolsDefTxtDictionary
):
159 List
= Key
.split('_')
160 if List
[Index
] == '*':
161 for String
in self
.ToolsDefTxtDatabase
[KeyList
[Index
]]:
163 NewKey
= '%s_%s_%s_%s_%s' % tuple(List
)
164 if NewKey
not in self
.ToolsDefTxtDictionary
:
165 self
.ToolsDefTxtDictionary
[NewKey
] = self
.ToolsDefTxtDictionary
[Key
]
167 del self
.ToolsDefTxtDictionary
[Key
]
168 elif List
[Index
] not in self
.ToolsDefTxtDatabase
[KeyList
[Index
]]:
169 del self
.ToolsDefTxtDictionary
[Key
]
173 # Replace defined macros with real value
175 # @param Value: The string with unreplaced macros
177 # @retval Value: The string which has been replaced with real value
179 def ExpandMacros(self
, Value
):
180 EnvReference
= gEnvRefPattern
.findall(Value
)
181 for Ref
in EnvReference
:
182 if Ref
not in self
.MacroDictionary
:
184 Value
= Value
.replace(Ref
, self
.MacroDictionary
[Ref
])
186 MacroReference
= gMacroRefPattern
.findall(Value
)
187 for Ref
in MacroReference
:
188 if Ref
not in self
.MacroDictionary
:
190 Value
= Value
.replace(Ref
, self
.MacroDictionary
[Ref
])
196 # Load tools_def.txt in input workspace dir
198 # @param WorkSpace: Workspace dir
200 # @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt
202 def ToolDefDict(WorkSpace
):
203 Target
= TargetTxtDict(WorkSpace
)
204 ToolDef
= ToolDefClassObject()
205 if DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
in Target
.TargetTxtDictionary
:
206 gDefaultToolsDefFile
= Target
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
207 ToolDef
.LoadToolDefFile(os
.path
.normpath(os
.path
.join(WorkSpace
, gDefaultToolsDefFile
)))
212 # This acts like the main() function for the script, unless it is 'import'ed into another
215 if __name__
== '__main__':
216 ToolDef
= ToolDefDict(os
.getenv("WORKSPACE"))