2 # This file is used to define each component of tools_def.txt file
4 # Copyright (c) 2007 - 2014, 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.
17 import Common
.LongFilePathOs
as os
21 from Dictionary
import *
22 from BuildToolError
import *
23 from TargetTxtClassObject
import *
24 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
27 # Static variables used for pattern
29 gMacroRefPattern
= re
.compile('(DEF\([^\(\)]+\))')
30 gEnvRefPattern
= re
.compile('(ENV\([^\(\)]+\))')
31 gMacroDefPattern
= re
.compile("DEFINE\s+([^\s]+)")
32 gDefaultToolsDefFile
= "tools_def.txt"
36 # This class defined content used in file tools_def.txt
38 # @param object: Inherited from object class
39 # @param Filename: Input value for full path of tools_def.txt
41 # @var ToolsDefTxtDictionary: To store keys and values defined in target.txt
42 # @var MacroDictionary: To store keys and values defined in DEFINE statement
44 class ToolDefClassObject(object):
45 def __init__(self
, FileName
= None):
46 self
.ToolsDefTxtDictionary
= {}
47 self
.MacroDictionary
= {}
48 for Env
in os
.environ
:
49 self
.MacroDictionary
["ENV(%s)" % Env
] = os
.environ
[Env
]
52 self
.LoadToolDefFile(FileName
)
56 # Load target.txt file and parse it, return a set structure to store keys and values
58 # @param Filename: Input value for full path of tools_def.txt
60 def LoadToolDefFile(self
, FileName
):
62 if os
.path
.isfile(FileName
):
64 F
= open(FileName
,'r')
65 FileContent
= F
.readlines()
67 EdkLogger
.error("tools_def.txt parser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
69 EdkLogger
.error("tools_def.txt parser", FILE_NOT_FOUND
, ExtraData
=FileName
)
71 self
.ToolsDefTxtDatabase
= {
72 TAB_TOD_DEFINES_TARGET
: [],
73 TAB_TOD_DEFINES_TOOL_CHAIN_TAG
: [],
74 TAB_TOD_DEFINES_TARGET_ARCH
: [],
75 TAB_TOD_DEFINES_COMMAND_TYPE
: []
78 for Index
in range(len(FileContent
)):
79 Line
= FileContent
[Index
].strip()
80 if Line
== "" or Line
[0] == '#':
82 NameValuePair
= Line
.split("=", 1)
83 if len(NameValuePair
) != 2:
84 EdkLogger
.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index
+ 1))
87 Name
= NameValuePair
[0].strip()
88 Value
= NameValuePair
[1].strip()
90 if Name
== "IDENTIFIER":
91 EdkLogger
.debug(EdkLogger
.DEBUG_8
, "Line %d: Found identifier statement, skipped: %s" % ((Index
+ 1), Value
))
94 MacroDefinition
= gMacroDefPattern
.findall(Name
)
95 if MacroDefinition
!= []:
96 Done
, Value
= self
.ExpandMacros(Value
)
98 EdkLogger
.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE
,
99 "Macro or Environment has not been defined",
100 ExtraData
=Value
[4:-1], File
=FileName
, Line
=Index
+1)
102 MacroName
= MacroDefinition
[0].strip()
103 self
.MacroDictionary
["DEF(%s)" % MacroName
] = Value
104 EdkLogger
.debug(EdkLogger
.DEBUG_8
, "Line %d: Found macro: %s = %s" % ((Index
+ 1), MacroName
, Value
))
107 Done
, Value
= self
.ExpandMacros(Value
)
109 EdkLogger
.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE
,
110 "Macro or Environment has not been defined",
111 ExtraData
=Value
[4:-1], File
=FileName
, Line
=Index
+1)
113 List
= Name
.split('_')
115 EdkLogger
.verbose("Line %d: Not a valid name of definition: %s" % ((Index
+ 1), Name
))
118 EdkLogger
.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index
+ 1), Name
))
121 self
.ToolsDefTxtDictionary
[Name
] = Value
123 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
] += [List
[0]]
125 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
] += [List
[1]]
127 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
] += [List
[2]]
129 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
] += [List
[3]]
130 if List
[4] == TAB_TOD_DEFINES_FAMILY
and List
[2] == '*' and List
[3] == '*':
131 if TAB_TOD_DEFINES_FAMILY
not in self
.ToolsDefTxtDatabase
:
132 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
] = {}
133 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
][List
[1]] = Value
134 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] = {}
135 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][List
[1]] = Value
136 elif List
[1] not in self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
]:
137 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
][List
[1]] = Value
138 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][List
[1]] = Value
139 elif self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
][List
[1]] != Value
:
140 EdkLogger
.verbose("Line %d: No override allowed for the family of a tool chain: %s" % ((Index
+ 1), Name
))
141 if List
[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY
and List
[2] == '*' and List
[3] == '*':
142 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in self
.ToolsDefTxtDatabase \
143 or List
[1] not in self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_FAMILY
]:
144 EdkLogger
.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index
+ 1), Name
))
145 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][List
[1]] = Value
147 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
]))
148 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
]))
149 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
]))
150 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
] = list(set(self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
]))
152 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET
].sort()
153 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TOOL_CHAIN_TAG
].sort()
154 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_TARGET_ARCH
].sort()
155 self
.ToolsDefTxtDatabase
[TAB_TOD_DEFINES_COMMAND_TYPE
].sort()
157 KeyList
= [TAB_TOD_DEFINES_TARGET
, TAB_TOD_DEFINES_TOOL_CHAIN_TAG
, TAB_TOD_DEFINES_TARGET_ARCH
, TAB_TOD_DEFINES_COMMAND_TYPE
]
158 for Index
in range(3,-1,-1):
159 for Key
in dict(self
.ToolsDefTxtDictionary
):
160 List
= Key
.split('_')
161 if List
[Index
] == '*':
162 for String
in self
.ToolsDefTxtDatabase
[KeyList
[Index
]]:
164 NewKey
= '%s_%s_%s_%s_%s' % tuple(List
)
165 if NewKey
not in self
.ToolsDefTxtDictionary
:
166 self
.ToolsDefTxtDictionary
[NewKey
] = self
.ToolsDefTxtDictionary
[Key
]
168 del self
.ToolsDefTxtDictionary
[Key
]
169 elif List
[Index
] not in self
.ToolsDefTxtDatabase
[KeyList
[Index
]]:
170 del self
.ToolsDefTxtDictionary
[Key
]
174 # Replace defined macros with real value
176 # @param Value: The string with unreplaced macros
178 # @retval Value: The string which has been replaced with real value
180 def ExpandMacros(self
, Value
):
181 EnvReference
= gEnvRefPattern
.findall(Value
)
182 for Ref
in EnvReference
:
183 if Ref
not in self
.MacroDictionary
:
184 Value
= Value
.replace(Ref
, "")
186 Value
= Value
.replace(Ref
, self
.MacroDictionary
[Ref
])
189 MacroReference
= gMacroRefPattern
.findall(Value
)
190 for Ref
in MacroReference
:
191 if Ref
not in self
.MacroDictionary
:
193 Value
= Value
.replace(Ref
, self
.MacroDictionary
[Ref
])
199 # Load tools_def.txt in input Conf dir
201 # @param ConfDir: Conf dir
203 # @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt
205 def ToolDefDict(ConfDir
):
206 Target
= TargetTxtDict(ConfDir
)
207 ToolDef
= ToolDefClassObject()
208 if DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
in Target
.TargetTxtDictionary
:
209 ToolsDefFile
= Target
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
211 ToolDef
.LoadToolDefFile(os
.path
.normpath(ToolsDefFile
))
213 ToolDef
.LoadToolDefFile(os
.path
.normpath(os
.path
.join(ConfDir
, gDefaultToolsDefFile
)))
215 ToolDef
.LoadToolDefFile(os
.path
.normpath(os
.path
.join(ConfDir
, gDefaultToolsDefFile
)))
220 # This acts like the main() function for the script, unless it is 'import'ed into another
223 if __name__
== '__main__':
224 ToolDef
= ToolDefDict(os
.getenv("WORKSPACE"))