2 # This file is used to define each component of Target.txt file
4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
11 from __future__
import print_function
12 from __future__
import absolute_import
14 import Common
.GlobalData
as GlobalData
15 import Common
.LongFilePathOs
as os
16 from . import EdkLogger
17 from . import DataType
18 from .BuildToolError
import *
20 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
21 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
23 gDefaultTargetTxtFile
= "target.txt"
25 ## TargetTxtClassObject
27 # This class defined content used in file target.txt
29 # @param object: Inherited from object class
30 # @param Filename: Input value for full path of target.txt
32 # @var TargetTxtDictionary: To store keys and values defined in target.txt
34 class TargetTxtClassObject(object):
35 def __init__(self
, Filename
= None):
36 self
.TargetTxtDictionary
= {
37 DataType
.TAB_TAT_DEFINES_ACTIVE_PLATFORM
: '',
38 DataType
.TAB_TAT_DEFINES_ACTIVE_MODULE
: '',
39 DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
: '',
40 DataType
.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER
: '',
41 DataType
.TAB_TAT_DEFINES_TARGET
: [],
42 DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_TAG
: [],
43 DataType
.TAB_TAT_DEFINES_TARGET_ARCH
: [],
44 DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
: '',
46 self
.ConfDirectoryPath
= ""
47 if Filename
is not None:
48 self
.LoadTargetTxtFile(Filename
)
52 # Load target.txt file and parse it, return a set structure to store keys and values
54 # @param Filename: Input value for full path of target.txt
56 # @retval set() A set structure to store keys and values
57 # @retval 1 Error happenes in parsing
59 def LoadTargetTxtFile(self
, Filename
):
60 if os
.path
.exists(Filename
) and os
.path
.isfile(Filename
):
61 return self
.ConvertTextFileToDict(Filename
, '#', '=')
63 EdkLogger
.error("Target.txt Parser", FILE_NOT_FOUND
, ExtraData
=Filename
)
66 ## ConvertTextFileToDict
68 # Convert a text file to a dictionary of (name:value) pairs.
69 # The data is saved to self.TargetTxtDictionary
71 # @param FileName: Text filename
72 # @param CommentCharacter: Comment char, be used to ignore comment content
73 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
75 # @retval 0 Convert successfully
76 # @retval 1 Open file failed
78 def ConvertTextFileToDict(self
, FileName
, CommentCharacter
, KeySplitCharacter
):
81 F
= open(FileName
, 'r')
82 self
.ConfDirectoryPath
= os
.path
.dirname(FileName
)
84 EdkLogger
.error("build", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
90 if Line
.startswith(CommentCharacter
) or Line
== '':
93 LineList
= Line
.split(KeySplitCharacter
, 1)
94 Key
= LineList
[0].strip()
95 if len(LineList
) == 2:
96 Value
= LineList
[1].strip()
100 if Key
in [DataType
.TAB_TAT_DEFINES_ACTIVE_PLATFORM
, DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
, \
101 DataType
.TAB_TAT_DEFINES_ACTIVE_MODULE
, DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
]:
102 self
.TargetTxtDictionary
[Key
] = Value
.replace('\\', '/')
103 if Key
== DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
and self
.TargetTxtDictionary
[Key
]:
104 if self
.TargetTxtDictionary
[Key
].startswith("Conf/"):
105 Tools_Def
= os
.path
.join(self
.ConfDirectoryPath
, self
.TargetTxtDictionary
[Key
].strip())
106 if not os
.path
.exists(Tools_Def
) or not os
.path
.isfile(Tools_Def
):
107 # If Conf/Conf does not exist, try just the Conf/ directory
108 Tools_Def
= os
.path
.join(self
.ConfDirectoryPath
, self
.TargetTxtDictionary
[Key
].replace("Conf/", "", 1).strip())
110 # The File pointed to by TOOL_CHAIN_CONF is not in a Conf/ directory
111 Tools_Def
= os
.path
.join(self
.ConfDirectoryPath
, self
.TargetTxtDictionary
[Key
].strip())
112 self
.TargetTxtDictionary
[Key
] = Tools_Def
113 if Key
== DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
and self
.TargetTxtDictionary
[Key
]:
114 if self
.TargetTxtDictionary
[Key
].startswith("Conf/"):
115 Build_Rule
= os
.path
.join(self
.ConfDirectoryPath
, self
.TargetTxtDictionary
[Key
].strip())
116 if not os
.path
.exists(Build_Rule
) or not os
.path
.isfile(Build_Rule
):
117 # If Conf/Conf does not exist, try just the Conf/ directory
118 Build_Rule
= os
.path
.join(self
.ConfDirectoryPath
, self
.TargetTxtDictionary
[Key
].replace("Conf/", "", 1).strip())
120 # The File pointed to by BUILD_RULE_CONF is not in a Conf/ directory
121 Build_Rule
= os
.path
.join(self
.ConfDirectoryPath
, self
.TargetTxtDictionary
[Key
].strip())
122 self
.TargetTxtDictionary
[Key
] = Build_Rule
123 elif Key
in [DataType
.TAB_TAT_DEFINES_TARGET
, DataType
.TAB_TAT_DEFINES_TARGET_ARCH
, \
124 DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_TAG
]:
125 self
.TargetTxtDictionary
[Key
] = Value
.split()
126 elif Key
== DataType
.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER
:
130 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid number of [%s]: %s." % (Key
, Value
),
132 self
.TargetTxtDictionary
[Key
] = Value
133 #elif Key not in GlobalData.gGlobalDefines:
134 # GlobalData.gGlobalDefines[Key] = Value
141 # Load target.txt in input Conf dir
143 # @param ConfDir: Conf dir
145 # @retval Target An instance of TargetTxtClassObject() with loaded target.txt
148 class TargetTxtDict():
150 def __new__(cls
, *args
, **kw
):
151 if not hasattr(cls
, '_instance'):
152 orig
= super(TargetTxtDict
, cls
)
153 cls
._instance
= orig
.__new
__(cls
, *args
, **kw
)
157 if not hasattr(self
, 'Target'):
158 self
.TxtTarget
= None
162 if not self
.TxtTarget
:
164 return self
.TxtTarget
166 def _GetTarget(self
):
167 Target
= TargetTxtClassObject()
168 ConfDirectory
= GlobalData
.gCmdConfDir
170 # Get alternate Conf location, if it is absolute, then just use the absolute directory name
171 ConfDirectoryPath
= os
.path
.normpath(ConfDirectory
)
173 if not os
.path
.isabs(ConfDirectoryPath
):
174 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
175 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
176 ConfDirectoryPath
= mws
.join(os
.environ
["WORKSPACE"], ConfDirectoryPath
)
178 if "CONF_PATH" in os
.environ
:
179 ConfDirectoryPath
= os
.path
.normcase(os
.path
.normpath(os
.environ
["CONF_PATH"]))
181 # Get standard WORKSPACE/Conf use the absolute path to the WORKSPACE/Conf
182 ConfDirectoryPath
= mws
.join(os
.environ
["WORKSPACE"], 'Conf')
183 GlobalData
.gConfDirectory
= ConfDirectoryPath
184 targettxt
= os
.path
.normpath(os
.path
.join(ConfDirectoryPath
, gDefaultTargetTxtFile
))
185 if os
.path
.exists(targettxt
):
186 Target
.LoadTargetTxtFile(targettxt
)
187 self
.TxtTarget
= Target
191 # This acts like the main() function for the script, unless it is 'import'ed into another
194 if __name__
== '__main__':
196 Target
= TargetTxtDict(os
.getenv("WORKSPACE"))
197 print(Target
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER
])
198 print(Target
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TARGET
])
199 print(Target
.TargetTxtDictionary
)