X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FCommon%2FToolDefClassObject.py;h=5d692ea13cfcc014a293afd02bab92711df4f9cf;hb=2e351cbe8e190271b3716284fc1076551d005472;hp=549f76cee98ca7741cca1e2f49a392914952ba31;hpb=40d841f6a8f84e75409178e19e69b95e01bada0f;p=mirror_edk2.git
diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py
index 549f76cee9..5d692ea13c 100644
--- a/BaseTools/Source/Python/Common/ToolDefClassObject.py
+++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py
@@ -1,34 +1,39 @@
## @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.
+# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
# Import Modules
#
-import os
+from __future__ import absolute_import
+import Common.LongFilePathOs as os
import re
-import EdkLogger
+from . import EdkLogger
+
+from .BuildToolError import *
+from Common.TargetTxtClassObject import TargetTxtDict
+from Common.LongFilePathSupport import OpenLongFilePath as open
+from Common.Misc import PathClass
+from Common.StringUtils import NormPath
+import Common.GlobalData as GlobalData
+from Common import GlobalData
+from Common.MultipleWorkspace import MultipleWorkspace as mws
+from .DataType import TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG,\
+ TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE\
+ , TAB_TOD_DEFINES_FAMILY, TAB_TOD_DEFINES_BUILDRULEFAMILY,\
+ TAB_STAR, TAB_TAT_DEFINES_TOOL_CHAIN_CONF
-from Dictionary import *
-from BuildToolError import *
-from TargetTxtClassObject import *
##
-# Static vailabes used for pattern
+# Static variables used for pattern
#
gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))')
gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))')
gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)")
-gDefaultToolsDefFile = "Conf/tools_def.txt"
+gDefaultToolsDefFile = "tools_def.txt"
## ToolDefClassObject
#
@@ -41,43 +46,122 @@ gDefaultToolsDefFile = "Conf/tools_def.txt"
# @var MacroDictionary: To store keys and values defined in DEFINE statement
#
class ToolDefClassObject(object):
- def __init__(self, FileName = None):
+ 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:
+ if FileName is not None:
self.LoadToolDefFile(FileName)
## LoadToolDefFile
#
- # Load target.txt file and parse it, return a set structure to store keys and values
+ # Load target.txt file and parse it
#
# @param Filename: Input value for full path of tools_def.txt
#
def LoadToolDefFile(self, FileName):
+ # set multiple workspace
+ PackagesPath = os.getenv("PACKAGES_PATH")
+ mws.setWs(GlobalData.gWorkspace, PackagesPath)
+
+ self.ToolsDefTxtDatabase = {
+ TAB_TOD_DEFINES_TARGET : [],
+ TAB_TOD_DEFINES_TOOL_CHAIN_TAG : [],
+ TAB_TOD_DEFINES_TARGET_ARCH : [],
+ TAB_TOD_DEFINES_COMMAND_TYPE : []
+ }
+
+ self.IncludeToolDefFile(FileName)
+
+ 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):
+ # make a copy of the keys to enumerate over to prevent issues when
+ # adding/removing items from the original dict.
+ for Key in list(self.ToolsDefTxtDictionary.keys()):
+ List = Key.split('_')
+ if List[Index] == TAB_STAR:
+ 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]
+ del self.ToolsDefTxtDictionary[Key]
+ elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:
+ del self.ToolsDefTxtDictionary[Key]
+
+
+ ## IncludeToolDefFile
+ #
+ # Load target.txt file and parse it as if it's contents were inside the main file
+ #
+ # @param Filename: Input value for full path of tools_def.txt
+ #
+ def IncludeToolDefFile(self, FileName):
FileContent = []
if os.path.isfile(FileName):
try:
- F = open(FileName,'r')
+ 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
+
+ if Line.startswith("!include"):
+ IncFile = Line[8:].strip()
+ Done, IncFile = self.ExpandMacros(IncFile)
+ if not Done:
+ EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE,
+ "Macro or Environment has not been defined",
+ ExtraData=IncFile[4:-1], File=FileName, Line=Index+1)
+ IncFile = NormPath(IncFile)
+
+ if not os.path.isabs(IncFile):
+ #
+ # try WORKSPACE
+ #
+ IncFileTmp = PathClass(IncFile, GlobalData.gWorkspace)
+ ErrorCode = IncFileTmp.Validate()[0]
+ if ErrorCode != 0:
+ #
+ # try PACKAGES_PATH
+ #
+ IncFileTmp = mws.join(GlobalData.gWorkspace, IncFile)
+ if not os.path.exists(IncFileTmp):
+ #
+ # try directory of current file
+ #
+ IncFileTmp = PathClass(IncFile, os.path.dirname(FileName))
+ ErrorCode = IncFileTmp.Validate()[0]
+ if ErrorCode != 0:
+ EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=IncFile)
+
+ if isinstance(IncFileTmp, PathClass):
+ IncFile = IncFileTmp.Path
+ else:
+ IncFile = IncFileTmp
+
+ self.IncludeToolDefFile(IncFile)
+ continue
+
NameValuePair = Line.split("=", 1)
if len(NameValuePair) != 2:
EdkLogger.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index + 1))
@@ -113,20 +197,20 @@ class ToolDefClassObject(object):
if len(List) != 5:
EdkLogger.verbose("Line %d: Not a valid name of definition: %s" % ((Index + 1), Name))
continue
- elif List[4] == '*':
+ elif List[4] == TAB_STAR:
EdkLogger.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index + 1), Name))
continue
else:
self.ToolsDefTxtDictionary[Name] = Value
- if List[0] != '*':
+ if List[0] != TAB_STAR:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] += [List[0]]
- if List[1] != '*':
+ if List[1] != TAB_STAR:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] += [List[1]]
- if List[2] != '*':
+ if List[2] != TAB_STAR:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] += [List[2]]
- if List[3] != '*':
+ if List[3] != TAB_STAR:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] += [List[3]]
- if List[4] == TAB_TOD_DEFINES_FAMILY and List[2] == '*' and List[3] == '*':
+ if List[4] == TAB_TOD_DEFINES_FAMILY and List[2] == TAB_STAR and List[3] == TAB_STAR:
if TAB_TOD_DEFINES_FAMILY not in self.ToolsDefTxtDatabase:
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value
@@ -137,37 +221,12 @@ class ToolDefClassObject(object):
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 List[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY and List[2] == TAB_STAR and List[3] == TAB_STAR:
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
@@ -177,12 +236,16 @@ class ToolDefClassObject(object):
# @retval Value: The string which has been replaced with real value
#
def ExpandMacros(self, Value):
+ # os.environ contains all environment variables uppercase on Windows which cause the key in the self.MacroDictionary is uppercase, but Ref may not
EnvReference = gEnvRefPattern.findall(Value)
for Ref in EnvReference:
- if Ref not in self.MacroDictionary:
- return False, Ref
- Value = Value.replace(Ref, self.MacroDictionary[Ref])
-
+ if Ref not in self.MacroDictionary and Ref.upper() not in self.MacroDictionary:
+ Value = Value.replace(Ref, "")
+ else:
+ if Ref in self.MacroDictionary:
+ Value = Value.replace(Ref, self.MacroDictionary[Ref])
+ else:
+ Value = Value.replace(Ref, self.MacroDictionary[Ref.upper()])
MacroReference = gMacroRefPattern.findall(Value)
for Ref in MacroReference:
if Ref not in self.MacroDictionary:
@@ -193,18 +256,23 @@ class ToolDefClassObject(object):
## ToolDefDict
#
-# Load tools_def.txt in input workspace dir
+# Load tools_def.txt in input Conf dir
#
-# @param WorkSpace: Workspace dir
+# @param ConfDir: Conf dir
#
# @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt
#
-def ToolDefDict(WorkSpace):
- Target = TargetTxtDict(WorkSpace)
+def ToolDefDict(ConfDir):
+ Target = TargetTxtDict(ConfDir)
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)))
+ if TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary:
+ ToolsDefFile = Target.TargetTxtDictionary[TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
+ if ToolsDefFile:
+ ToolDef.LoadToolDefFile(os.path.normpath(ToolsDefFile))
+ else:
+ ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile)))
+ else:
+ ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile)))
return ToolDef
##