]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Common/ToolDefClassObject.py
BaseTools: use set instead of list for a variable to be used with in
[mirror_edk2.git] / BaseTools / Source / Python / Common / ToolDefClassObject.py
index b5cd5ee435ef153c14e4495359ea01c9169506d2..73ebdaf6b1793646fffcfc3fe06e1835c510fe99 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define each component of tools_def.txt file\r
 #\r
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 ##\r
 # Import Modules\r
 #\r
-import os\r
+import Common.LongFilePathOs as os\r
 import re\r
 import EdkLogger\r
 \r
-from Dictionary import *\r
 from BuildToolError import *\r
 from TargetTxtClassObject import *\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.Misc import PathClass\r
+from Common.String import NormPath\r
+import Common.GlobalData as GlobalData\r
+from Common import GlobalData\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+from DataType import TAB_TOD_DEFINES_TARGET,TAB_TOD_DEFINES_TOOL_CHAIN_TAG,\\r
+                     TAB_TOD_DEFINES_TARGET_ARCH,TAB_TOD_DEFINES_COMMAND_TYPE\\r
+                     ,TAB_TOD_DEFINES_FAMILY,TAB_TOD_DEFINES_BUILDRULEFAMILY\r
+\r
 \r
 ##\r
 # Static variables used for pattern\r
@@ -28,7 +37,7 @@ from TargetTxtClassObject import *
 gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))')\r
 gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))')\r
 gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)")\r
-gDefaultToolsDefFile = "Conf/tools_def.txt"\r
+gDefaultToolsDefFile = "tools_def.txt"\r
 \r
 ## ToolDefClassObject\r
 #\r
@@ -41,43 +50,121 @@ gDefaultToolsDefFile = "Conf/tools_def.txt"
 # @var MacroDictionary:        To store keys and values defined in DEFINE statement\r
 #\r
 class ToolDefClassObject(object):\r
-    def __init__(self, FileName = None):\r
+    def __init__(self, FileName=None):\r
         self.ToolsDefTxtDictionary = {}\r
         self.MacroDictionary = {}\r
         for Env in os.environ:\r
             self.MacroDictionary["ENV(%s)" % Env] = os.environ[Env]\r
 \r
-        if FileName != None:\r
+        if FileName is not None:\r
             self.LoadToolDefFile(FileName)\r
 \r
     ## LoadToolDefFile\r
     #\r
-    # Load target.txt file and parse it, return a set structure to store keys and values\r
+    # Load target.txt file and parse it\r
     #\r
     # @param Filename:  Input value for full path of tools_def.txt\r
     #\r
     def LoadToolDefFile(self, FileName):\r
+        # set multiple workspace\r
+        PackagesPath = os.getenv("PACKAGES_PATH")\r
+        mws.setWs(GlobalData.gWorkspace, PackagesPath)\r
+\r
+        self.ToolsDefTxtDatabase = {\r
+            TAB_TOD_DEFINES_TARGET          :   [],\r
+            TAB_TOD_DEFINES_TOOL_CHAIN_TAG  :   [],\r
+            TAB_TOD_DEFINES_TARGET_ARCH     :   [],\r
+            TAB_TOD_DEFINES_COMMAND_TYPE    :   []\r
+        }\r
+\r
+        self.IncludeToolDefFile(FileName)\r
+\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET]))\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]))\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH]))\r
+\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE]))\r
+\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort()\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort()\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()\r
+        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()\r
+\r
+        KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]\r
+        for Index in range(3, -1, -1):\r
+            for Key in dict(self.ToolsDefTxtDictionary):\r
+                List = Key.split('_')\r
+                if List[Index] == '*':\r
+                    for String in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
+                        List[Index] = String\r
+                        NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
+                        if NewKey not in self.ToolsDefTxtDictionary:\r
+                            self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]\r
+                        continue\r
+                    del self.ToolsDefTxtDictionary[Key]\r
+                elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
+                    del self.ToolsDefTxtDictionary[Key]\r
+\r
+\r
+    ## IncludeToolDefFile\r
+    #\r
+    # Load target.txt file and parse it as if it's contents were inside the main file\r
+    #\r
+    # @param Filename:  Input value for full path of tools_def.txt\r
+    #\r
+    def IncludeToolDefFile(self, FileName):\r
         FileContent = []\r
         if os.path.isfile(FileName):\r
             try:\r
-                F = open(FileName,'r')\r
+                F = open(FileName, 'r')\r
                 FileContent = F.readlines()\r
             except:\r
                 EdkLogger.error("tools_def.txt parser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
         else:\r
             EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName)\r
 \r
-        self.ToolsDefTxtDatabase = {\r
-            TAB_TOD_DEFINES_TARGET          :   [],\r
-            TAB_TOD_DEFINES_TOOL_CHAIN_TAG  :   [],\r
-            TAB_TOD_DEFINES_TARGET_ARCH     :   [],\r
-            TAB_TOD_DEFINES_COMMAND_TYPE    :   []\r
-        }\r
-\r
         for Index in range(len(FileContent)):\r
             Line = FileContent[Index].strip()\r
             if Line == "" or Line[0] == '#':\r
                 continue\r
+\r
+            if Line.startswith("!include"):\r
+                IncFile = Line[8:].strip()\r
+                Done, IncFile = self.ExpandMacros(IncFile)\r
+                if not Done:\r
+                    EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE,\r
+                                    "Macro or Environment has not been defined",\r
+                                ExtraData=IncFile[4:-1], File=FileName, Line=Index+1)\r
+                IncFile = NormPath(IncFile)\r
+\r
+                if not os.path.isabs(IncFile):\r
+                    #\r
+                    # try WORKSPACE\r
+                    #\r
+                    IncFileTmp = PathClass(IncFile, GlobalData.gWorkspace)\r
+                    ErrorCode = IncFileTmp.Validate()[0]\r
+                    if ErrorCode != 0:\r
+                        #\r
+                        # try PACKAGES_PATH\r
+                        #\r
+                        IncFileTmp = mws.join(GlobalData.gWorkspace, IncFile)\r
+                        if not os.path.exists(IncFileTmp):\r
+                            #\r
+                            # try directory of current file\r
+                            #\r
+                            IncFileTmp = PathClass(IncFile, os.path.dirname(FileName))\r
+                            ErrorCode = IncFileTmp.Validate()[0]\r
+                            if ErrorCode != 0:\r
+                                EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=IncFile)\r
+\r
+                    if type(IncFileTmp) is PathClass:\r
+                        IncFile = IncFileTmp.Path\r
+                    else:\r
+                        IncFile = IncFileTmp\r
+\r
+                self.IncludeToolDefFile(IncFile)\r
+                continue\r
+\r
             NameValuePair = Line.split("=", 1)\r
             if len(NameValuePair) != 2:\r
                 EdkLogger.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index + 1))\r
@@ -143,31 +230,6 @@ class ToolDefClassObject(object):
                         EdkLogger.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index + 1), Name))\r
                     self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value\r
 \r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET]))\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]))\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH]))\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE]))\r
-\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort()\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort()\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()\r
-        self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()\r
-\r
-        KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]\r
-        for Index in range(3,-1,-1):\r
-            for Key in dict(self.ToolsDefTxtDictionary):\r
-                List = Key.split('_')\r
-                if List[Index] == '*':\r
-                    for String in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
-                        List[Index] = String\r
-                        NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
-                        if NewKey not in self.ToolsDefTxtDictionary:\r
-                            self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]\r
-                        continue\r
-                    del self.ToolsDefTxtDictionary[Key]\r
-                elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
-                    del self.ToolsDefTxtDictionary[Key]\r
-\r
     ## ExpandMacros\r
     #\r
     # Replace defined macros with real value\r
@@ -177,12 +239,16 @@ class ToolDefClassObject(object):
     # @retval Value:  The string which has been replaced with real value\r
     #\r
     def ExpandMacros(self, Value):\r
+        # os.environ contains all environment variables uppercase on Windows which cause the key in the self.MacroDictionary is uppercase, but Ref may not\r
         EnvReference = gEnvRefPattern.findall(Value)\r
         for Ref in EnvReference:\r
-            if Ref not in self.MacroDictionary:\r
-                return False, Ref\r
-            Value = Value.replace(Ref, self.MacroDictionary[Ref])\r
-\r
+            if Ref not in self.MacroDictionary and Ref.upper() not in self.MacroDictionary:\r
+                Value = Value.replace(Ref, "")\r
+            else:\r
+                if Ref in self.MacroDictionary:\r
+                    Value = Value.replace(Ref, self.MacroDictionary[Ref])\r
+                else:\r
+                    Value = Value.replace(Ref, self.MacroDictionary[Ref.upper()])\r
         MacroReference = gMacroRefPattern.findall(Value)\r
         for Ref in MacroReference:\r
             if Ref not in self.MacroDictionary:\r
@@ -193,18 +259,23 @@ class ToolDefClassObject(object):
 \r
 ## ToolDefDict\r
 #\r
-# Load tools_def.txt in input workspace dir\r
+# Load tools_def.txt in input Conf dir\r
 #\r
-# @param WorkSpace:  Workspace dir\r
+# @param ConfDir:  Conf dir\r
 #\r
 # @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt\r
 #\r
-def ToolDefDict(WorkSpace):\r
-    Target = TargetTxtDict(WorkSpace)\r
+def ToolDefDict(ConfDir):\r
+    Target = TargetTxtDict(ConfDir)\r
     ToolDef = ToolDefClassObject()\r
     if DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary:\r
-        gDefaultToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
-    ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(WorkSpace, gDefaultToolsDefFile)))\r
+        ToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
+        if ToolsDefFile:\r
+            ToolDef.LoadToolDefFile(os.path.normpath(ToolsDefFile))\r
+        else:\r
+            ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile)))\r
+    else:\r
+        ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile)))\r
     return ToolDef\r
 \r
 ##\r