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 ##