2010-02-28 23:39:39 +00:00
## @file
# Generate AutoGen.h, AutoGen.c and *.depex files
#
2016-01-19 12:58:52 +00:00
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
2010-05-18 05:04:32 +00:00
# This program and the accompanying materials
2010-02-28 23:39:39 +00:00
# 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.
#
## Import Modules
#
2014-08-15 03:06:48 +00:00
import Common.LongFilePathOs as os
2010-02-28 23:39:39 +00:00
import re
import os.path as path
import copy
2015-06-10 07:50:59 +00:00
import uuid
2010-02-28 23:39:39 +00:00
import GenC
import GenMake
import GenDepex
from StringIO import StringIO
from StrGather import *
from BuildEngine import BuildRule
2014-08-15 03:06:48 +00:00
from Common.LongFilePathSupport import CopyLongFilePath
2010-02-28 23:39:39 +00:00
from Common.BuildToolError import *
from Common.DataType import *
from Common.Misc import *
from Common.String import *
import Common.GlobalData as GlobalData
from GenFds.FdfParser import *
from CommonDataClass.CommonClass import SkuInfoClass
from Workspace.BuildClassObject import *
2013-11-18 07:41:21 +00:00
from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
2010-09-06 01:58:00 +00:00
import Common.VpdInfoFile as VpdInfoFile
2013-11-18 07:41:21 +00:00
from GenPcdDb import CreatePcdDatabaseCode
from Workspace.MetaFileCommentParser import UsageList
2015-10-08 09:27:14 +00:00
from Common.MultipleWorkspace import MultipleWorkspace as mws
2014-08-28 13:53:34 +00:00
import InfSectionParser
2013-11-18 07:41:21 +00:00
## Regular expression for splitting Dependency Expression string into tokens
2010-02-28 23:39:39 +00:00
gDepexTokenPattern = re . compile ( "(\(|\)|\w+| \S+\.inf)" )
2014-08-28 13:53:34 +00:00
#
# Match name = variable
#
gEfiVarStoreNamePattern = re . compile ( "\s*name\s*=\s*(\w+)" )
#
# The format of guid in efivarstore statement likes following and must be correct:
# guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}
#
gEfiVarStoreGuidPattern = re . compile ( "\s*guid\s*=\s*({.*?{.*?}\s*})" )
2010-02-28 23:39:39 +00:00
## Mapping Makefile type
gMakeTypeMap = { "MSFT" : "nmake" , "GCC" : "gmake" }
## Build rule configuration file
2014-08-28 13:53:34 +00:00
gDefaultBuildRuleFile = 'Conf/build_rule.txt'
2010-02-28 23:39:39 +00:00
2012-04-10 07:18:20 +00:00
## Build rule default version
AutoGenReqBuildRuleVerNum = "0.1"
2010-02-28 23:39:39 +00:00
## default file name for AutoGen
gAutoGenCodeFileName = "AutoGen.c"
gAutoGenHeaderFileName = "AutoGen.h"
gAutoGenStringFileName = " %(module_name)s StrDefs.h"
gAutoGenStringFormFileName = " %(module_name)s StrDefs.hpk"
gAutoGenDepexFileName = " %(module_name)s .depex"
2014-08-28 13:53:34 +00:00
gInfSpecVersion = "0x00010017"
2011-05-11 10:26:49 +00:00
#
# Template string to generic AsBuilt INF
#
2013-11-18 07:41:21 +00:00
gAsBuiltInfHeaderString = TemplateString ( """$ {header_comments}
2011-05-11 10:26:49 +00:00
2014-08-28 13:53:34 +00:00
# DO NOT EDIT
# FILE auto-generated
2011-05-11 10:26:49 +00:00
[Defines]
2014-08-28 13:53:34 +00:00
INF_VERSION = $ {module_inf_version}
2011-05-11 10:26:49 +00:00
BASE_NAME = $ {module_name}
FILE_GUID = $ {module_guid}
2014-08-28 13:53:34 +00:00
MODULE_TYPE = $ {module_module_type} $ {BEGIN}
VERSION_STRING = $ {module_version_string} $ {END} $ {BEGIN}
2013-11-18 07:41:21 +00:00
PCD_IS_DRIVER = $ {pcd_is_driver_string} $ {END} $ {BEGIN}
2011-05-11 10:26:49 +00:00
UEFI_SPECIFICATION_VERSION = $ {module_uefi_specification_version} $ {END} $ {BEGIN}
2014-08-28 13:53:34 +00:00
PI_SPECIFICATION_VERSION = $ {module_pi_specification_version} $ {END} $ {BEGIN}
ENTRY_POINT = $ {module_entry_point} $ {END} $ {BEGIN}
UNLOAD_IMAGE = $ {module_unload_image} $ {END} $ {BEGIN}
CONSTRUCTOR = $ {module_constructor} $ {END} $ {BEGIN}
DESTRUCTOR = $ {module_destructor} $ {END} $ {BEGIN}
SHADOW = $ {module_shadow} $ {END} $ {BEGIN}
PCI_VENDOR_ID = $ {module_pci_vendor_id} $ {END} $ {BEGIN}
PCI_DEVICE_ID = $ {module_pci_device_id} $ {END} $ {BEGIN}
PCI_CLASS_CODE = $ {module_pci_class_code} $ {END} $ {BEGIN}
PCI_REVISION = $ {module_pci_revision} $ {END} $ {BEGIN}
BUILD_NUMBER = $ {module_build_number} $ {END} $ {BEGIN}
SPEC = $ {module_spec} $ {END} $ {BEGIN}
UEFI_HII_RESOURCE_SECTION = $ {module_uefi_hii_resource_section} $ {END} $ {BEGIN}
MODULE_UNI_FILE = $ {module_uni_file} $ {END}
2011-05-11 10:26:49 +00:00
2014-08-28 13:53:34 +00:00
[Packages.$ {module_arch} ]$ {BEGIN}
2011-05-11 10:26:49 +00:00
$ {package_item} $ {END}
[Binaries.$ {module_arch} ]$ {BEGIN}
$ {binary_item} $ {END}
2013-11-18 07:41:21 +00:00
[PatchPcd.$ {module_arch} ]$ {BEGIN}
$ {patchablepcd_item}
$ {END}
2014-08-28 13:53:34 +00:00
2013-11-18 07:41:21 +00:00
[Protocols.$ {module_arch} ]$ {BEGIN}
$ {protocol_item}
$ {END}
2014-08-28 13:53:34 +00:00
2013-11-18 07:41:21 +00:00
[Ppis.$ {module_arch} ]$ {BEGIN}
$ {ppi_item}
$ {END}
2014-08-28 13:53:34 +00:00
2013-11-18 07:41:21 +00:00
[Guids.$ {module_arch} ]$ {BEGIN}
$ {guid_item}
$ {END}
2014-08-28 13:53:34 +00:00
2013-11-18 07:41:21 +00:00
[PcdEx.$ {module_arch} ]$ {BEGIN}
$ {pcd_item}
$ {END}
2011-05-11 10:26:49 +00:00
2014-08-28 13:53:34 +00:00
[LibraryClasses.$ {module_arch} ]
## @LIB_INSTANCES$ {BEGIN}
# $ {libraryclasses_item} $ {END}
$ {depexsection_item}
$ {tail_comments}
[BuildOptions.$ {module_arch} ]
2011-05-11 10:26:49 +00:00
## @AsBuilt$ {BEGIN}
## $ {flags_item} $ {END}
""" )
2010-02-28 23:39:39 +00:00
## Base class for AutoGen
#
# This class just implements the cache mechanism of AutoGen objects.
#
class AutoGen ( object ):
# database to maintain the objects of xxxAutoGen
_CACHE_ = {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
## Factory method
#
# @param Class class object of real AutoGen class
# (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
# @param Workspace Workspace directory or WorkspaceAutoGen object
# @param MetaFile The path of meta file
# @param Target Build target
# @param Toolchain Tool chain name
# @param Arch Target arch
# @param *args The specific class related parameters
# @param **kwargs The specific class related dict parameters
#
def __new__ ( Class , Workspace , MetaFile , Target , Toolchain , Arch , * args , ** kwargs ):
# check if the object has been created
Key = ( Target , Toolchain )
if Key not in Class . _CACHE_ or Arch not in Class . _CACHE_ [ Key ] \
or MetaFile not in Class . _CACHE_ [ Key ][ Arch ]:
AutoGenObject = super ( AutoGen , Class ) . __new__ ( Class )
# call real constructor
if not AutoGenObject . _Init ( Workspace , MetaFile , Target , Toolchain , Arch , * args , ** kwargs ):
return None
if Key not in Class . _CACHE_ :
Class . _CACHE_ [ Key ] = {}
if Arch not in Class . _CACHE_ [ Key ]:
Class . _CACHE_ [ Key ][ Arch ] = {}
Class . _CACHE_ [ Key ][ Arch ][ MetaFile ] = AutoGenObject
else :
AutoGenObject = Class . _CACHE_ [ Key ][ Arch ][ MetaFile ]
return AutoGenObject
## hash() operator
#
# The file path of platform file will be used to represent hash value of this object
#
# @retval int Hash value of the file path of platform file
#
def __hash__ ( self ):
return hash ( self . MetaFile )
## str() operator
#
# The file path of platform file will be used to represent this object
#
# @retval string String of platform file path
#
def __str__ ( self ):
return str ( self . MetaFile )
## "==" operator
def __eq__ ( self , Other ):
return Other and self . MetaFile == Other
## Workspace AutoGen class
#
# This class is used mainly to control the whole platform build for different
# architecture. This class will generate top level makefile.
#
class WorkspaceAutoGen ( AutoGen ):
## Real constructor of WorkspaceAutoGen
#
2011-10-11 02:49:48 +00:00
# This method behaves the same as __init__ except that it needs explicit invoke
2010-02-28 23:39:39 +00:00
# (in super class's __new__ method)
#
# @param WorkspaceDir Root directory of workspace
# @param ActivePlatform Meta-file of active platform
# @param Target Build target
# @param Toolchain Tool chain name
# @param ArchList List of architecture of current build
# @param MetaFileDb Database containing meta-files
# @param BuildConfig Configuration of build
# @param ToolDefinition Tool chain definitions
# @param FlashDefinitionFile File of flash definition
# @param Fds FD list to be generated
# @param Fvs FV list to be generated
2011-08-26 07:46:26 +00:00
# @param Caps Capsule list to be generated
2010-02-28 23:39:39 +00:00
# @param SkuId SKU id from command line
#
def _Init ( self , WorkspaceDir , ActivePlatform , Target , Toolchain , ArchList , MetaFileDb ,
2015-12-01 04:22:16 +00:00
BuildConfig , ToolDefinition , FlashDefinitionFile = '' , Fds = None , Fvs = None , Caps = None , SkuId = '' , UniFlag = None ,
2011-12-16 08:52:13 +00:00
Progress = None , BuildModule = None ):
2011-08-26 07:46:26 +00:00
if Fds is None :
Fds = []
if Fvs is None :
Fvs = []
if Caps is None :
Caps = []
2011-10-29 06:59:30 +00:00
self . BuildDatabase = MetaFileDb
self . MetaFile = ActivePlatform
2010-02-28 23:39:39 +00:00
self . WorkspaceDir = WorkspaceDir
2011-10-29 06:59:30 +00:00
self . Platform = self . BuildDatabase [ self . MetaFile , 'COMMON' , Target , Toolchain ]
2011-12-07 06:19:28 +00:00
GlobalData . gActivePlatform = self . Platform
2010-02-28 23:39:39 +00:00
self . BuildTarget = Target
self . ToolChain = Toolchain
self . ArchList = ArchList
self . SkuId = SkuId
2010-03-19 06:55:07 +00:00
self . UniFlag = UniFlag
2010-02-28 23:39:39 +00:00
self . TargetTxt = BuildConfig
self . ToolDef = ToolDefinition
self . FdfFile = FlashDefinitionFile
self . FdTargetList = Fds
self . FvTargetList = Fvs
2011-08-26 07:46:26 +00:00
self . CapTargetList = Caps
2010-02-28 23:39:39 +00:00
self . AutoGenObjectList = []
# there's many relative directory operations, so ...
os . chdir ( self . WorkspaceDir )
2011-10-29 06:59:30 +00:00
#
# Merge Arch
#
if not self . ArchList :
ArchList = set ( self . Platform . SupArchList )
else :
ArchList = set ( self . ArchList ) & set ( self . Platform . SupArchList )
if not ArchList :
EdkLogger . error ( "build" , PARAMETER_INVALID ,
ExtraData = "Invalid ARCH specified. [Valid ARCH: %s ]" % ( " " . join ( self . Platform . SupArchList )))
elif self . ArchList and len ( ArchList ) != len ( self . ArchList ):
SkippedArchList = set ( self . ArchList ) . symmetric_difference ( set ( self . Platform . SupArchList ))
EdkLogger . verbose ( " \n Arch [ %s ] is ignored because the platform supports [ %s ] only!"
% ( " " . join ( SkippedArchList ), " " . join ( self . Platform . SupArchList )))
self . ArchList = tuple ( ArchList )
# Validate build target
if self . BuildTarget not in self . Platform . BuildTargets :
2015-12-01 04:22:16 +00:00
EdkLogger . error ( "build" , PARAMETER_INVALID ,
2011-10-29 06:59:30 +00:00
ExtraData = "Build target [ %s ] is not supported by the platform. [Valid target: %s ]"
% ( self . BuildTarget , " " . join ( self . Platform . BuildTargets )))
2014-08-30 12:59:03 +00:00
2010-02-28 23:39:39 +00:00
# parse FDF file to get PCDs in it, if any
2011-10-29 06:59:30 +00:00
if not self . FdfFile :
self . FdfFile = self . Platform . FlashDefinition
2015-12-01 04:22:16 +00:00
2011-12-16 08:52:13 +00:00
EdkLogger . info ( "" )
if self . ArchList :
EdkLogger . info ( ' %-16s = %s ' % ( "Architecture(s)" , ' ' . join ( self . ArchList )))
EdkLogger . info ( ' %-16s = %s ' % ( "Build target" , self . BuildTarget ))
2015-12-01 04:22:16 +00:00
EdkLogger . info ( ' %-16s = %s ' % ( "Toolchain" , self . ToolChain ))
2011-12-16 08:52:13 +00:00
EdkLogger . info ( ' \n %-24s = %s ' % ( "Active Platform" , self . Platform ))
if BuildModule :
EdkLogger . info ( ' %-24s = %s ' % ( "Active Module" , BuildModule ))
2015-12-01 04:22:16 +00:00
2011-12-16 08:52:13 +00:00
if self . FdfFile :
EdkLogger . info ( ' %-24s = %s ' % ( "Flash Image Definition" , self . FdfFile ))
2011-10-29 06:59:30 +00:00
2011-12-16 08:52:13 +00:00
EdkLogger . verbose ( " \n FLASH_DEFINITION = %s " % self . FdfFile )
2015-12-01 04:22:16 +00:00
2011-12-16 08:52:13 +00:00
if Progress :
Progress . Start ( " \n Processing meta-data" )
2015-12-01 04:22:16 +00:00
2011-10-29 06:59:30 +00:00
if self . FdfFile :
2011-09-19 09:03:59 +00:00
#
# Mark now build in AutoGen Phase
#
2015-12-01 04:22:16 +00:00
GlobalData . gAutoGenPhase = True
2010-02-28 23:39:39 +00:00
Fdf = FdfParser ( self . FdfFile . Path )
Fdf . ParseFile ()
2014-08-26 02:52:24 +00:00
GlobalData . gFdfParser = Fdf
2011-10-29 06:59:30 +00:00
GlobalData . gAutoGenPhase = False
2010-02-28 23:39:39 +00:00
PcdSet = Fdf . Profile . PcdDict
2016-01-26 08:45:34 +00:00
if Fdf . CurrentFdName and Fdf . CurrentFdName in Fdf . Profile . FdDict :
FdDict = Fdf . Profile . FdDict [ Fdf . CurrentFdName ]
for FdRegion in FdDict . RegionList :
if str ( FdRegion . RegionType ) is 'FILE' and self . Platform . VpdToolGuid in str ( FdRegion . RegionDataList ):
if int ( FdRegion . Offset ) % 8 != 0 :
EdkLogger . error ( "build" , FORMAT_INVALID , 'The VPD Base Address %s must be 8-byte aligned.' % ( FdRegion . Offset ))
2010-02-28 23:39:39 +00:00
ModuleList = Fdf . Profile . InfList
self . FdfProfile = Fdf . Profile
2011-10-29 06:59:30 +00:00
for fvname in self . FvTargetList :
if fvname . upper () not in self . FdfProfile . FvDict :
EdkLogger . error ( "build" , OPTION_VALUE_INVALID ,
"No such an FV in FDF file: %s " % fvname )
2010-02-28 23:39:39 +00:00
else :
PcdSet = {}
ModuleList = []
self . FdfProfile = None
2011-10-29 06:59:30 +00:00
if self . FdTargetList :
EdkLogger . info ( "No flash definition file found. FD [ %s ] will be ignored." % " " . join ( self . FdTargetList ))
self . FdTargetList = []
if self . FvTargetList :
EdkLogger . info ( "No flash definition file found. FV [ %s ] will be ignored." % " " . join ( self . FvTargetList ))
self . FvTargetList = []
if self . CapTargetList :
EdkLogger . info ( "No flash definition file found. Capsule [ %s ] will be ignored." % " " . join ( self . CapTargetList ))
self . CapTargetList = []
2015-12-01 04:22:16 +00:00
2010-02-28 23:39:39 +00:00
# apply SKU and inject PCDs from Flash Definition file
for Arch in self . ArchList :
2011-10-29 06:59:30 +00:00
Platform = self . BuildDatabase [ self . MetaFile , Arch , Target , Toolchain ]
2012-04-10 07:18:20 +00:00
2012-05-23 08:27:14 +00:00
DecPcds = {}
2013-08-23 02:18:16 +00:00
DecPcdsKey = set ()
2012-04-10 07:18:20 +00:00
PGen = PlatformAutoGen ( self , self . MetaFile , Target , Toolchain , Arch )
2016-02-25 16:13:31 +08:00
if GlobalData . BuildOptionPcd :
for i , pcd in enumerate ( GlobalData . BuildOptionPcd ):
2016-04-05 12:29:32 +08:00
if type ( pcd ) is tuple :
continue
2016-02-25 16:13:31 +08:00
( pcdname , pcdvalue ) = pcd . split ( '=' )
if not pcdvalue :
EdkLogger . error ( 'build' , AUTOGEN_ERROR , "No Value specified for the PCD %s ." % ( pcdname ))
if '.' in pcdname :
( TokenSpaceGuidCName , TokenCName ) = pcdname . split ( '.' )
HasTokenSpace = True
else :
TokenCName = pcdname
TokenSpaceGuidCName = ''
HasTokenSpace = False
TokenSpaceGuidCNameList = []
FoundFlag = False
PcdDatumType = ''
NewValue = ''
for package in PGen . PackageList :
for key in package . Pcds :
PcdItem = package . Pcds [ key ]
if HasTokenSpace :
if ( PcdItem . TokenCName , PcdItem . TokenSpaceGuidCName ) == ( TokenCName , TokenSpaceGuidCName ):
PcdDatumType = PcdItem . DatumType
NewValue = self . _BuildOptionPcdValueFormat ( TokenSpaceGuidCName , TokenCName , PcdDatumType , pcdvalue )
FoundFlag = True
else :
if PcdItem . TokenCName == TokenCName :
if not PcdItem . TokenSpaceGuidCName in TokenSpaceGuidCNameList :
if len ( TokenSpaceGuidCNameList ) < 1 :
TokenSpaceGuidCNameList . append ( PcdItem . TokenSpaceGuidCName )
PcdDatumType = PcdItem . DatumType
TokenSpaceGuidCName = PcdItem . TokenSpaceGuidCName
NewValue = self . _BuildOptionPcdValueFormat ( TokenSpaceGuidCName , TokenCName , PcdDatumType , pcdvalue )
FoundFlag = True
else :
EdkLogger . error (
'build' ,
AUTOGEN_ERROR ,
"The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s ." % ( TokenCName , PcdItem . TokenSpaceGuidCName , TokenSpaceGuidCNameList [ 0 ])
)
GlobalData . BuildOptionPcd [ i ] = ( TokenSpaceGuidCName , TokenCName , NewValue )
if not FoundFlag :
if HasTokenSpace :
EdkLogger . error ( 'build' , AUTOGEN_ERROR , "The Pcd %s . %s is not found in the DEC file." % ( TokenSpaceGuidCName , TokenCName ))
else :
EdkLogger . error ( 'build' , AUTOGEN_ERROR , "The Pcd %s is not found in the DEC file." % ( TokenCName ))
for BuildData in PGen . BuildDatabase . _CACHE_ . values ():
if BuildData . Arch != Arch :
continue
if BuildData . MetaFile . Ext == '.dec' :
continue
for key in BuildData . Pcds :
PcdItem = BuildData . Pcds [ key ]
if ( TokenSpaceGuidCName , TokenCName ) == ( PcdItem . TokenSpaceGuidCName , PcdItem . TokenCName ):
PcdItem . DefaultValue = NewValue
if ( TokenCName , TokenSpaceGuidCName ) in PcdSet :
PcdSet [( TokenCName , TokenSpaceGuidCName )] = NewValue
2014-08-28 13:53:34 +00:00
#Collect package set information from INF of FDF
2014-08-26 02:52:24 +00:00
PkgSet = set ()
for Inf in ModuleList :
ModuleFile = PathClass ( NormPath ( Inf ), GlobalData . gWorkspace , Arch )
if ModuleFile in Platform . Modules :
continue
ModuleData = self . BuildDatabase [ ModuleFile , Arch , Target , Toolchain ]
PkgSet . update ( ModuleData . Packages )
Pkgs = list ( PkgSet ) + list ( PGen . PackageList )
2012-04-10 07:18:20 +00:00
for Pkg in Pkgs :
2012-05-23 08:27:14 +00:00
for Pcd in Pkg . Pcds :
DecPcds [ Pcd [ 0 ], Pcd [ 1 ]] = Pkg . Pcds [ Pcd ]
2013-08-23 02:18:16 +00:00
DecPcdsKey . add (( Pcd [ 0 ], Pcd [ 1 ], Pcd [ 2 ]))
2012-04-10 07:18:20 +00:00
2010-02-28 23:39:39 +00:00
Platform . SkuName = self . SkuId
for Name , Guid in PcdSet :
2012-04-10 07:18:20 +00:00
if ( Name , Guid ) not in DecPcds :
EdkLogger . error (
'build' ,
PARSER_ERROR ,
"PCD ( %s . %s ) used in FDF is not declared in DEC files." % ( Guid , Name ),
File = self . FdfProfile . PcdFileLineDict [ Name , Guid ][ 0 ],
Line = self . FdfProfile . PcdFileLineDict [ Name , Guid ][ 1 ]
)
2013-08-23 02:18:16 +00:00
else :
# Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.
if ( Name , Guid , TAB_PCDS_FIXED_AT_BUILD ) in DecPcdsKey \
or ( Name , Guid , TAB_PCDS_PATCHABLE_IN_MODULE ) in DecPcdsKey \
or ( Name , Guid , TAB_PCDS_FEATURE_FLAG ) in DecPcdsKey :
Platform . AddPcd ( Name , Guid , PcdSet [ Name , Guid ])
continue
elif ( Name , Guid , TAB_PCDS_DYNAMIC ) in DecPcdsKey or ( Name , Guid , TAB_PCDS_DYNAMIC_EX ) in DecPcdsKey :
EdkLogger . error (
'build' ,
PARSER_ERROR ,
"Using Dynamic or DynamicEx type of PCD [ %s . %s ] in FDF file is not allowed." % ( Guid , Name ),
File = self . FdfProfile . PcdFileLineDict [ Name , Guid ][ 0 ],
Line = self . FdfProfile . PcdFileLineDict [ Name , Guid ][ 1 ]
)
2010-02-28 23:39:39 +00:00
Pa = PlatformAutoGen ( self , self . MetaFile , Target , Toolchain , Arch )
#
# Explicitly collect platform's dynamic PCDs
#
Pa . CollectPlatformDynamicPcds ()
2014-01-10 05:25:50 +00:00
Pa . CollectFixedAtBuildPcds ()
2010-02-28 23:39:39 +00:00
self . AutoGenObjectList . append ( Pa )
2015-12-01 04:22:16 +00:00
2010-11-15 02:51:34 +00:00
#
# Check PCDs token value conflict in each DEC file.
#
self . _CheckAllPcdsTokenValueConflict ()
2015-12-01 04:22:16 +00:00
2011-08-26 07:46:26 +00:00
#
# Check PCD type and definition between DSC and DEC
#
self . _CheckPcdDefineAndType ()
2014-08-28 13:53:34 +00:00
# if self.FdfFile:
# self._CheckDuplicateInFV(Fdf)
2010-02-28 23:39:39 +00:00
self . _BuildDir = None
self . _FvDir = None
self . _MakeFileDir = None
self . _BuildCommand = None
return True
2016-02-25 16:13:31 +08:00
def _BuildOptionPcdValueFormat ( self , TokenSpaceGuidCName , TokenCName , PcdDatumType , Value ):
if PcdDatumType == 'VOID*' :
if Value . startswith ( 'L' ):
if not Value [ 1 ]:
EdkLogger . error ( 'build' , OPTION_VALUE_INVALID , 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"' )
Value = Value [ 0 ] + '"' + Value [ 1 :] + '"'
elif Value . startswith ( 'B' ):
if not Value [ 1 ]:
EdkLogger . error ( 'build' , OPTION_VALUE_INVALID , 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"' )
Value = Value [ 1 :]
else :
if not Value [ 0 ]:
EdkLogger . error ( 'build' , OPTION_VALUE_INVALID , 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"' )
Value = '"' + Value + '"'
IsValid , Cause = CheckPcdDatum ( PcdDatumType , Value )
if not IsValid :
EdkLogger . error ( 'build' , FORMAT_INVALID , Cause , ExtraData = " %s . %s " % ( TokenSpaceGuidCName , TokenCName ))
if PcdDatumType == 'BOOLEAN' :
Value = Value . upper ()
if Value == 'TRUE' or Value == '1' :
Value = '1'
elif Value == 'FALSE' or Value == '0' :
Value = '0'
return Value
2011-10-11 02:49:48 +00:00
## _CheckDuplicateInFV() method
#
# Check whether there is duplicate modules/files exist in FV section.
# The check base on the file GUID;
#
def _CheckDuplicateInFV ( self , Fdf ):
for Fv in Fdf . Profile . FvDict :
_GuidDict = {}
for FfsFile in Fdf . Profile . FvDict [ Fv ] . FfsList :
if FfsFile . InfFileName and FfsFile . NameGuid == None :
#
# Get INF file GUID
#
2015-12-01 04:22:16 +00:00
InfFoundFlag = False
2011-10-11 02:49:48 +00:00
for Pa in self . AutoGenObjectList :
2012-04-10 07:18:20 +00:00
if InfFoundFlag :
break
2011-10-11 02:49:48 +00:00
for Module in Pa . ModuleAutoGenList :
if path . normpath ( Module . MetaFile . File ) == path . normpath ( FfsFile . InfFileName ):
InfFoundFlag = True
if not Module . Guid . upper () in _GuidDict . keys ():
_GuidDict [ Module . Guid . upper ()] = FfsFile
2012-04-10 07:18:20 +00:00
break
2011-10-11 02:49:48 +00:00
else :
2015-12-01 04:22:16 +00:00
EdkLogger . error ( "build" ,
2011-10-11 02:49:48 +00:00
FORMAT_INVALID ,
2015-12-01 04:22:16 +00:00
"Duplicate GUID found for these lines: Line %d : %s and Line %d : %s . GUID: %s " % ( FfsFile . CurrentLineNum ,
2011-10-11 02:49:48 +00:00
FfsFile . CurrentLineContent ,
_GuidDict [ Module . Guid . upper ()] . CurrentLineNum ,
_GuidDict [ Module . Guid . upper ()] . CurrentLineContent ,
Module . Guid . upper ()),
ExtraData = self . FdfFile )
#
# Some INF files not have entity in DSC file.
#
if not InfFoundFlag :
if FfsFile . InfFileName . find ( '$' ) == - 1 :
InfPath = NormPath ( FfsFile . InfFileName )
if not os . path . exists ( InfPath ):
EdkLogger . error ( 'build' , GENFDS_ERROR , "Non-existant Module %s !" % ( FfsFile . InfFileName ))
2015-12-01 04:22:16 +00:00
2011-10-11 02:49:48 +00:00
PathClassObj = PathClass ( FfsFile . InfFileName , self . WorkspaceDir )
#
# Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use
# BuildObject from one of AutoGenObjectList is enough.
#
InfObj = self . AutoGenObjectList [ 0 ] . BuildDatabase . WorkspaceDb . BuildObject [ PathClassObj , 'COMMON' , self . BuildTarget , self . ToolChain ]
if not InfObj . Guid . upper () in _GuidDict . keys ():
_GuidDict [ InfObj . Guid . upper ()] = FfsFile
else :
2015-12-01 04:22:16 +00:00
EdkLogger . error ( "build" ,
2011-10-11 02:49:48 +00:00
FORMAT_INVALID ,
2015-12-01 04:22:16 +00:00
"Duplicate GUID found for these lines: Line %d : %s and Line %d : %s . GUID: %s " % ( FfsFile . CurrentLineNum ,
2011-10-11 02:49:48 +00:00
FfsFile . CurrentLineContent ,
_GuidDict [ InfObj . Guid . upper ()] . CurrentLineNum ,
_GuidDict [ InfObj . Guid . upper ()] . CurrentLineContent ,
InfObj . Guid . upper ()),
ExtraData = self . FdfFile )
InfFoundFlag = False
2015-12-01 04:22:16 +00:00
2011-10-11 02:49:48 +00:00
if FfsFile . NameGuid != None :
_CheckPCDAsGuidPattern = re . compile ( "^PCD\(.+\..+\)$" )
2015-12-01 04:22:16 +00:00
2011-10-11 02:49:48 +00:00
#
# If the NameGuid reference a PCD name.
# The style must match: PCD(xxxx.yyy)
#
if _CheckPCDAsGuidPattern . match ( FfsFile . NameGuid ):
#
# Replace the PCD value.
#
_PcdName = FfsFile . NameGuid . lstrip ( "PCD(" ) . rstrip ( ")" )
PcdFoundFlag = False
for Pa in self . AutoGenObjectList :
if not PcdFoundFlag :
for PcdItem in Pa . AllPcdList :
if ( PcdItem . TokenSpaceGuidCName + "." + PcdItem . TokenCName ) == _PcdName :
#
# First convert from CFormatGuid to GUID string
#
_PcdGuidString = GuidStructureStringToGuidString ( PcdItem . DefaultValue )
2015-12-01 04:22:16 +00:00
2011-10-11 02:49:48 +00:00
if not _PcdGuidString :
#
# Then try Byte array.
#
_PcdGuidString = GuidStructureByteArrayToGuidString ( PcdItem . DefaultValue )
2015-12-01 04:22:16 +00:00
2011-10-11 02:49:48 +00:00
if not _PcdGuidString :
#
# Not Byte array or CFormat GUID, raise error.
#
EdkLogger . error ( "build" ,
FORMAT_INVALID ,
2015-12-01 04:22:16 +00:00
"The format of PCD value is incorrect. PCD: %s , Value: %s \n " % ( _PcdName , PcdItem . DefaultValue ),
2011-10-11 02:49:48 +00:00
ExtraData = self . FdfFile )
2015-12-01 04:22:16 +00:00
if not _PcdGuidString . upper () in _GuidDict . keys ():
2011-10-11 02:49:48 +00:00
_GuidDict [ _PcdGuidString . upper ()] = FfsFile
PcdFoundFlag = True
break
else :
2015-12-01 04:22:16 +00:00
EdkLogger . error ( "build" ,
2011-10-11 02:49:48 +00:00
FORMAT_INVALID ,
2015-12-01 04:22:16 +00:00
"Duplicate GUID found for these lines: Line %d : %s and Line %d : %s . GUID: %s " % ( FfsFile . CurrentLineNum ,
2011-10-11 02:49:48 +00:00
FfsFile . CurrentLineContent ,
_GuidDict [ _PcdGuidString . upper ()] . CurrentLineNum ,
_GuidDict [ _PcdGuidString . upper ()] . CurrentLineContent ,
FfsFile . NameGuid . upper ()),
2015-12-01 04:22:16 +00:00
ExtraData = self . FdfFile )
2011-10-11 02:49:48 +00:00
if not FfsFile . NameGuid . upper () in _GuidDict . keys ():
_GuidDict [ FfsFile . NameGuid . upper ()] = FfsFile
else :
#
# Two raw file GUID conflict.
#
2015-12-01 04:22:16 +00:00
EdkLogger . error ( "build" ,
2011-10-11 02:49:48 +00:00
FORMAT_INVALID ,
2015-12-01 04:22:16 +00:00
"Duplicate GUID found for these lines: Line %d : %s and Line %d : %s . GUID: %s " % ( FfsFile . CurrentLineNum ,
2011-10-11 02:49:48 +00:00
FfsFile . CurrentLineContent ,
_GuidDict [ FfsFile . NameGuid . upper ()] . CurrentLineNum ,
_GuidDict [ FfsFile . NameGuid . upper ()] . CurrentLineContent ,
FfsFile . NameGuid . upper ()),
ExtraData = self . FdfFile )
2015-12-01 04:22:16 +00:00
2011-10-11 02:49:48 +00:00
2011-08-26 07:46:26 +00:00
def _CheckPcdDefineAndType ( self ):
PcdTypeList = [
"FixedAtBuild" , "PatchableInModule" , "FeatureFlag" ,
"Dynamic" , #"DynamicHii", "DynamicVpd",
"DynamicEx" , # "DynamicExHii", "DynamicExVpd"
]
# This dict store PCDs which are not used by any modules with specified arches
UnusedPcd = sdict ()
for Pa in self . AutoGenObjectList :
# Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid
for Pcd in Pa . Platform . Pcds :
PcdType = Pa . Platform . Pcds [ Pcd ] . Type
2015-12-01 04:22:16 +00:00
2011-08-26 07:46:26 +00:00
# If no PCD type, this PCD comes from FDF
if not PcdType :
continue
2015-12-01 04:22:16 +00:00
2011-08-26 07:46:26 +00:00
# Try to remove Hii and Vpd suffix
if PcdType . startswith ( "DynamicEx" ):
PcdType = "DynamicEx"
elif PcdType . startswith ( "Dynamic" ):
PcdType = "Dynamic"
2015-12-01 04:22:16 +00:00
2011-08-26 07:46:26 +00:00
for Package in Pa . PackageList :
# Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType
if ( Pcd [ 0 ], Pcd [ 1 ], PcdType ) in Package . Pcds :
break
for Type in PcdTypeList :
if ( Pcd [ 0 ], Pcd [ 1 ], Type ) in Package . Pcds :
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"Type [ %s ] of PCD [ %s . %s ] in DSC file doesn't match the type [ %s ] defined in DEC file." \
% ( Pa . Platform . Pcds [ Pcd ] . Type , Pcd [ 1 ], Pcd [ 0 ], Type ),
ExtraData = None
)
return
else :
UnusedPcd . setdefault ( Pcd , []) . append ( Pa . Arch )
for Pcd in UnusedPcd :
EdkLogger . warn (
'build' ,
"The PCD was not specified by any INF module in the platform for the given architecture. \n "
" \t PCD: [ %s . %s ] \n\t Platform: [ %s ] \n\t Arch: %s "
% ( Pcd [ 1 ], Pcd [ 0 ], os . path . basename ( str ( self . MetaFile )), str ( UnusedPcd [ Pcd ])),
ExtraData = None
)
2010-02-28 23:39:39 +00:00
def __repr__ ( self ):
return " %s [ %s ]" % ( self . MetaFile , ", " . join ( self . ArchList ))
## Return the directory to store FV files
def _GetFvDir ( self ):
if self . _FvDir == None :
self . _FvDir = path . join ( self . BuildDir , 'FV' )
return self . _FvDir
## Return the directory to store all intermediate and final files built
def _GetBuildDir ( self ):
return self . AutoGenObjectList [ 0 ] . BuildDir
## Return the build output directory platform specifies
def _GetOutputDir ( self ):
return self . Platform . OutputDirectory
## Return platform name
def _GetName ( self ):
return self . Platform . PlatformName
## Return meta-file GUID
def _GetGuid ( self ):
return self . Platform . Guid
## Return platform version
def _GetVersion ( self ):
return self . Platform . Version
## Return paths of tools
def _GetToolDefinition ( self ):
return self . AutoGenObjectList [ 0 ] . ToolDefinition
## Return directory of platform makefile
#
# @retval string Makefile directory
#
def _GetMakeFileDir ( self ):
if self . _MakeFileDir == None :
self . _MakeFileDir = self . BuildDir
return self . _MakeFileDir
## Return build command string
#
# @retval string Build command string
#
def _GetBuildCommand ( self ):
if self . _BuildCommand == None :
# BuildCommand should be all the same. So just get one from platform AutoGen
self . _BuildCommand = self . AutoGenObjectList [ 0 ] . BuildCommand
return self . _BuildCommand
2015-12-01 04:22:16 +00:00
2010-11-15 02:51:34 +00:00
## Check the PCDs token value conflict in each DEC file.
#
# Will cause build break and raise error message while two PCDs conflict.
#
# @return None
#
def _CheckAllPcdsTokenValueConflict ( self ):
2011-09-18 12:17:25 +00:00
for Pa in self . AutoGenObjectList :
for Package in Pa . PackageList :
2010-11-15 02:51:34 +00:00
PcdList = Package . Pcds . values ()
2015-06-23 07:02:03 +00:00
PcdList . sort ( lambda x , y : cmp ( int ( x . TokenValue , 0 ), int ( y . TokenValue , 0 )))
2010-11-15 02:51:34 +00:00
Count = 0
while ( Count < len ( PcdList ) - 1 ) :
Item = PcdList [ Count ]
ItemNext = PcdList [ Count + 1 ]
#
# Make sure in the same token space the TokenValue should be unique
#
2015-06-23 07:02:03 +00:00
if ( int ( Item . TokenValue , 0 ) == int ( ItemNext . TokenValue , 0 )):
2010-11-15 02:51:34 +00:00
SameTokenValuePcdList = []
SameTokenValuePcdList . append ( Item )
SameTokenValuePcdList . append ( ItemNext )
RemainPcdListLength = len ( PcdList ) - Count - 2
for ValueSameCount in range ( RemainPcdListLength ):
2015-06-23 07:02:03 +00:00
if int ( PcdList [ len ( PcdList ) - RemainPcdListLength + ValueSameCount ] . TokenValue , 0 ) == int ( Item . TokenValue , 0 ):
2010-11-15 02:51:34 +00:00
SameTokenValuePcdList . append ( PcdList [ len ( PcdList ) - RemainPcdListLength + ValueSameCount ])
else :
break ;
#
# Sort same token value PCD list with TokenGuid and TokenCName
#
2015-12-01 04:22:16 +00:00
SameTokenValuePcdList . sort ( lambda x , y : cmp ( " %s . %s " % ( x . TokenSpaceGuidCName , x . TokenCName ), " %s . %s " % ( y . TokenSpaceGuidCName , y . TokenCName )))
SameTokenValuePcdListCount = 0
2010-11-15 02:51:34 +00:00
while ( SameTokenValuePcdListCount < len ( SameTokenValuePcdList ) - 1 ):
2015-12-01 04:22:16 +00:00
TemListItem = SameTokenValuePcdList [ SameTokenValuePcdListCount ]
TemListItemNext = SameTokenValuePcdList [ SameTokenValuePcdListCount + 1 ]
2010-11-15 02:51:34 +00:00
if ( TemListItem . TokenSpaceGuidCName == TemListItemNext . TokenSpaceGuidCName ) and ( TemListItem . TokenCName != TemListItemNext . TokenCName ):
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"The TokenValue [ %s ] of PCD [ %s . %s ] is conflict with: [ %s . %s ] in %s " \
% ( TemListItem . TokenValue , TemListItem . TokenSpaceGuidCName , TemListItem . TokenCName , TemListItemNext . TokenSpaceGuidCName , TemListItemNext . TokenCName , Package ),
ExtraData = None
)
SameTokenValuePcdListCount += 1
Count += SameTokenValuePcdListCount
Count += 1
2015-12-01 04:22:16 +00:00
2010-11-15 02:51:34 +00:00
PcdList = Package . Pcds . values ()
2015-12-01 04:22:16 +00:00
PcdList . sort ( lambda x , y : cmp ( " %s . %s " % ( x . TokenSpaceGuidCName , x . TokenCName ), " %s . %s " % ( y . TokenSpaceGuidCName , y . TokenCName )))
2010-11-15 02:51:34 +00:00
Count = 0
while ( Count < len ( PcdList ) - 1 ) :
Item = PcdList [ Count ]
2015-12-01 04:22:16 +00:00
ItemNext = PcdList [ Count + 1 ]
2010-11-15 02:51:34 +00:00
#
# Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.
#
2015-06-23 07:02:03 +00:00
if ( Item . TokenSpaceGuidCName == ItemNext . TokenSpaceGuidCName ) and ( Item . TokenCName == ItemNext . TokenCName ) and ( int ( Item . TokenValue , 0 ) != int ( ItemNext . TokenValue , 0 )):
2010-11-15 02:51:34 +00:00
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"The TokenValue [ %s ] of PCD [ %s . %s ] in %s defined in two places should be same as well." \
% ( Item . TokenValue , Item . TokenSpaceGuidCName , Item . TokenCName , Package ),
ExtraData = None
)
Count += 1
2014-08-28 13:53:34 +00:00
## Generate fds command
2014-08-18 04:59:01 +00:00
def _GenFdsCommand ( self ):
return ( GenMake . TopLevelMakefile ( self ) . _TEMPLATE_ . Replace ( GenMake . TopLevelMakefile ( self ) . _TemplateDict )) . strip ()
2010-02-28 23:39:39 +00:00
2010-09-06 01:58:00 +00:00
## Create makefile for the platform and modules in it
2010-02-28 23:39:39 +00:00
#
# @param CreateDepsMakeFile Flag indicating if the makefile for
# modules will be created as well
#
def CreateMakeFile ( self , CreateDepsMakeFile = False ):
if CreateDepsMakeFile :
for Pa in self . AutoGenObjectList :
Pa . CreateMakeFile ( CreateDepsMakeFile )
## Create autogen code for platform and modules
#
# Since there's no autogen code for platform, this method will do nothing
# if CreateModuleCodeFile is set to False.
#
# @param CreateDepsCodeFile Flag indicating if creating module's
# autogen code file or not
#
def CreateCodeFile ( self , CreateDepsCodeFile = False ):
if not CreateDepsCodeFile :
return
for Pa in self . AutoGenObjectList :
Pa . CreateCodeFile ( CreateDepsCodeFile )
2011-05-26 07:35:18 +00:00
## Create AsBuilt INF file the platform
#
def CreateAsBuiltInf ( self ):
return
2010-02-28 23:39:39 +00:00
Name = property ( _GetName )
Guid = property ( _GetGuid )
Version = property ( _GetVersion )
OutputDir = property ( _GetOutputDir )
ToolDefinition = property ( _GetToolDefinition ) # toolcode : tool path
BuildDir = property ( _GetBuildDir )
FvDir = property ( _GetFvDir )
MakeFileDir = property ( _GetMakeFileDir )
BuildCommand = property ( _GetBuildCommand )
2014-08-18 04:59:01 +00:00
GenFdsCommand = property ( _GenFdsCommand )
2010-02-28 23:39:39 +00:00
## AutoGen class for platform
#
# PlatformAutoGen class will process the original information in platform
# file in order to generate makefile for platform.
#
class PlatformAutoGen ( AutoGen ):
#
# Used to store all PCDs for both PEI and DXE phase, in order to generate
# correct PCD database
#
_DynaPcdList_ = []
_NonDynaPcdList_ = []
2010-11-15 02:51:34 +00:00
#
# The priority list while override build option
#
PrioList = { "0x11111" : 16 , # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
"0x01111" : 15 , # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
"0x10111" : 14 , # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
"0x00111" : 13 , # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
"0x11011" : 12 , # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
"0x01011" : 11 , # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
"0x10011" : 10 , # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
"0x00011" : 9 , # ******_*********_****_COMMANDTYPE_ATTRIBUTE
"0x11101" : 8 , # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
"0x01101" : 7 , # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
"0x10101" : 6 , # TARGET_*********_ARCH_***********_ATTRIBUTE
"0x00101" : 5 , # ******_*********_ARCH_***********_ATTRIBUTE
"0x11001" : 4 , # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
"0x01001" : 3 , # ******_TOOLCHAIN_****_***********_ATTRIBUTE
"0x10001" : 2 , # TARGET_*********_****_***********_ATTRIBUTE
"0x00001" : 1 } # ******_*********_****_***********_ATTRIBUTE (Lowest)
2015-12-01 04:22:16 +00:00
2010-02-28 23:39:39 +00:00
## The real constructor of PlatformAutoGen
#
# This method is not supposed to be called by users of PlatformAutoGen. It's
# only used by factory method __new__() to do real initialization work for an
# object of PlatformAutoGen
#
# @param Workspace WorkspaceAutoGen object
# @param PlatformFile Platform file (DSC file)
# @param Target Build target (DEBUG, RELEASE)
# @param Toolchain Name of tool chain
# @param Arch arch of the platform supports
#
def _Init ( self , Workspace , PlatformFile , Target , Toolchain , Arch ):
EdkLogger . debug ( EdkLogger . DEBUG_9 , "AutoGen platform [ %s ] [ %s ]" % ( PlatformFile , Arch ))
GlobalData . gProcessingFile = " %s [ %s , %s , %s ]" % ( PlatformFile , Arch , Toolchain , Target )
self . MetaFile = PlatformFile
self . Workspace = Workspace
self . WorkspaceDir = Workspace . WorkspaceDir
self . ToolChain = Toolchain
self . BuildTarget = Target
self . Arch = Arch
self . SourceDir = PlatformFile . SubDir
self . SourceOverrideDir = None
self . FdTargetList = self . Workspace . FdTargetList
self . FvTargetList = self . Workspace . FvTargetList
self . AllPcdList = []
2014-08-26 02:52:24 +00:00
# get the original module/package/platform objects
self . BuildDatabase = Workspace . BuildDatabase
2010-02-28 23:39:39 +00:00
# flag indicating if the makefile/C-code file has been created or not
self . IsMakeFileCreated = False
self . IsCodeFileCreated = False
self . _Platform = None
self . _Name = None
self . _Guid = None
self . _Version = None
self . _BuildRule = None
self . _SourceDir = None
self . _BuildDir = None
self . _OutputDir = None
self . _FvDir = None
self . _MakeFileDir = None
self . _FdfFile = None
self . _PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
self . _DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
self . _NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
2014-01-10 05:25:50 +00:00
self . _NonDynamicPcdDict = {}
2010-02-28 23:39:39 +00:00
self . _ToolDefinitions = None
self . _ToolDefFile = None # toolcode : tool path
self . _ToolChainFamily = None
self . _BuildRuleFamily = None
self . _BuildOption = None # toolcode : option
self . _EdkBuildOption = None # edktoolcode : option
self . _EdkIIBuildOption = None # edkiitoolcode : option
self . _PackageList = None
self . _ModuleAutoGenList = None
self . _LibraryAutoGenList = None
self . _BuildCommand = None
2014-08-26 02:52:24 +00:00
self . _AsBuildInfList = []
self . _AsBuildModuleList = []
if GlobalData . gFdfParser != None :
self . _AsBuildInfList = GlobalData . gFdfParser . Profile . InfList
for Inf in self . _AsBuildInfList :
InfClass = PathClass ( NormPath ( Inf ), GlobalData . gWorkspace , self . Arch )
M = self . BuildDatabase [ InfClass , self . Arch , self . BuildTarget , self . ToolChain ]
if not M . IsSupportedArch :
continue
self . _AsBuildModuleList . append ( InfClass )
2014-08-18 04:59:01 +00:00
# get library/modules for build
self . LibraryBuildDirectoryList = []
self . ModuleBuildDirectoryList = []
2010-02-28 23:39:39 +00:00
return True
def __repr__ ( self ):
return " %s [ %s ]" % ( self . MetaFile , self . Arch )
## Create autogen code for platform and modules
#
# Since there's no autogen code for platform, this method will do nothing
# if CreateModuleCodeFile is set to False.
#
# @param CreateModuleCodeFile Flag indicating if creating module's
# autogen code file or not
#
def CreateCodeFile ( self , CreateModuleCodeFile = False ):
# only module has code to be greated, so do nothing if CreateModuleCodeFile is False
if self . IsCodeFileCreated or not CreateModuleCodeFile :
return
for Ma in self . ModuleAutoGenList :
Ma . CreateCodeFile ( True )
# don't do this twice
self . IsCodeFileCreated = True
2014-08-18 04:59:01 +00:00
## Generate Fds Command
def _GenFdsCommand ( self ):
return self . Workspace . GenFdsCommand
2010-02-28 23:39:39 +00:00
## Create makefile for the platform and mdoules in it
#
# @param CreateModuleMakeFile Flag indicating if the makefile for
# modules will be created as well
#
def CreateMakeFile ( self , CreateModuleMakeFile = False ):
if CreateModuleMakeFile :
for ModuleFile in self . Platform . Modules :
Ma = ModuleAutoGen ( self . Workspace , ModuleFile , self . BuildTarget ,
self . ToolChain , self . Arch , self . MetaFile )
Ma . CreateMakeFile ( True )
2014-08-28 13:53:34 +00:00
#Ma.CreateAsBuiltInf()
2010-02-28 23:39:39 +00:00
# no need to create makefile for the platform more than once
if self . IsMakeFileCreated :
return
2014-08-18 04:59:01 +00:00
# create library/module build dirs for platform
2010-02-28 23:39:39 +00:00
Makefile = GenMake . PlatformMakefile ( self )
2014-08-18 04:59:01 +00:00
self . LibraryBuildDirectoryList = Makefile . GetLibraryBuildDirectoryList ()
self . ModuleBuildDirectoryList = Makefile . GetModuleBuildDirectoryList ()
2010-02-28 23:39:39 +00:00
self . IsMakeFileCreated = True
2014-01-10 05:25:50 +00:00
## Deal with Shared FixedAtBuild Pcds
#
def CollectFixedAtBuildPcds ( self ):
for LibAuto in self . LibraryAutoGenList :
FixedAtBuildPcds = {}
ShareFixedAtBuildPcdsSameValue = {}
for Module in LibAuto . _ReferenceModules :
for Pcd in Module . FixedAtBuildPcds + LibAuto . FixedAtBuildPcds :
key = "." . join (( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ))
if key not in FixedAtBuildPcds :
ShareFixedAtBuildPcdsSameValue [ key ] = True
FixedAtBuildPcds [ key ] = Pcd . DefaultValue
else :
if FixedAtBuildPcds [ key ] != Pcd . DefaultValue :
ShareFixedAtBuildPcdsSameValue [ key ] = False
for Pcd in LibAuto . FixedAtBuildPcds :
key = "." . join (( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ))
if ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName ) not in self . NonDynamicPcdDict :
continue
else :
DscPcd = self . NonDynamicPcdDict [( Pcd . TokenCName , Pcd . TokenSpaceGuidCName )]
if DscPcd . Type != "FixedAtBuild" :
continue
if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue [ key ]:
LibAuto . ConstPcd [ key ] = Pcd . DefaultValue
2010-02-28 23:39:39 +00:00
## Collect dynamic PCDs
#
# Gather dynamic PCDs list from each module and their settings from platform
# This interface should be invoked explicitly when platform action is created.
#
def CollectPlatformDynamicPcds ( self ):
2016-02-25 16:13:31 +08:00
# Override the platform Pcd's value by build option
if GlobalData . BuildOptionPcd :
for key in self . Platform . Pcds :
PlatformPcd = self . Platform . Pcds [ key ]
for PcdItem in GlobalData . BuildOptionPcd :
if ( PlatformPcd . TokenSpaceGuidCName , PlatformPcd . TokenCName ) == ( PcdItem [ 0 ], PcdItem [ 1 ]):
PlatformPcd . DefaultValue = PcdItem [ 2 ]
if PlatformPcd . SkuInfoList :
Sku = PlatformPcd . SkuInfoList [ PlatformPcd . SkuInfoList . keys ()[ 0 ]]
Sku . DefaultValue = PcdItem [ 2 ]
break
2010-02-28 23:39:39 +00:00
# for gathering error information
NoDatumTypePcdList = set ()
2014-08-26 02:52:24 +00:00
PcdNotInDb = []
2010-02-28 23:39:39 +00:00
self . _GuidValue = {}
2014-08-26 02:52:24 +00:00
FdfModuleList = []
for InfName in self . _AsBuildInfList :
2015-10-08 09:27:14 +00:00
InfName = mws . join ( self . WorkspaceDir , InfName )
2014-08-26 02:52:24 +00:00
FdfModuleList . append ( os . path . normpath ( InfName ))
2010-02-28 23:39:39 +00:00
for F in self . Platform . Modules . keys ():
M = ModuleAutoGen ( self . Workspace , F , self . BuildTarget , self . ToolChain , self . Arch , self . MetaFile )
#GuidValue.update(M.Guids)
self . Platform . Modules [ F ] . M = M
2015-12-01 04:22:16 +00:00
for PcdFromModule in M . ModulePcdList + M . LibraryPcdList :
2010-02-28 23:39:39 +00:00
# make sure that the "VOID*" kind of datum has MaxDatumSize set
2013-11-18 07:41:21 +00:00
if PcdFromModule . DatumType == "VOID*" and PcdFromModule . MaxDatumSize in [ None , '' ]:
2010-02-28 23:39:39 +00:00
NoDatumTypePcdList . add ( " %s . %s [ %s ]" % ( PcdFromModule . TokenSpaceGuidCName , PcdFromModule . TokenCName , F ))
2014-08-28 13:53:34 +00:00
# Check the PCD from Binary INF or Source INF
2014-08-26 02:52:24 +00:00
if M . IsBinaryModule == True :
PcdFromModule . IsFromBinaryInf = True
2014-08-28 13:53:34 +00:00
# Check the PCD from DSC or not
2014-08-26 02:52:24 +00:00
if ( PcdFromModule . TokenCName , PcdFromModule . TokenSpaceGuidCName ) in self . Platform . Pcds . keys ():
PcdFromModule . IsFromDsc = True
else :
PcdFromModule . IsFromDsc = False
2010-02-28 23:39:39 +00:00
if PcdFromModule . Type in GenC . gDynamicPcd or PcdFromModule . Type in GenC . gDynamicExPcd :
2014-08-26 02:52:24 +00:00
if F . Path not in FdfModuleList :
# If one of the Source built modules listed in the DSC is not listed
# in FDF modules, and the INF lists a PCD can only use the PcdsDynamic
# access method (it is only listed in the DEC file that declares the
# PCD as PcdsDynamic), then build tool will report warning message
# notify the PI that they are attempting to build a module that must
# be included in a flash image in order to be functional. These Dynamic
# PCD will not be added into the Database unless it is used by other
# modules that are included in the FDF file.
if PcdFromModule . Type in GenC . gDynamicPcd and \
PcdFromModule . IsFromBinaryInf == False :
# Print warning message to let the developer make a determine.
if PcdFromModule not in PcdNotInDb :
PcdNotInDb . append ( PcdFromModule )
continue
# If one of the Source built modules listed in the DSC is not listed in
# FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx
# access method (it is only listed in the DEC file that declares the
# PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the
# PCD to the Platform's PCD Database.
if PcdFromModule . Type in GenC . gDynamicExPcd :
if PcdFromModule not in PcdNotInDb :
PcdNotInDb . append ( PcdFromModule )
continue
2010-02-28 23:39:39 +00:00
#
# If a dynamic PCD used by a PEM module/PEI module & DXE module,
# it should be stored in Pcd PEI database, If a dynamic only
# used by DXE module, it should be stored in DXE PCD database.
# The default Phase is DXE
#
if M . ModuleType in [ "PEIM" , "PEI_CORE" ]:
PcdFromModule . Phase = "PEI"
if PcdFromModule not in self . _DynaPcdList_ :
self . _DynaPcdList_ . append ( PcdFromModule )
elif PcdFromModule . Phase == 'PEI' :
# overwrite any the same PCD existing, if Phase is PEI
Index = self . _DynaPcdList_ . index ( PcdFromModule )
self . _DynaPcdList_ [ Index ] = PcdFromModule
elif PcdFromModule not in self . _NonDynaPcdList_ :
self . _NonDynaPcdList_ . append ( PcdFromModule )
2014-08-26 02:52:24 +00:00
elif PcdFromModule in self . _NonDynaPcdList_ and PcdFromModule . IsFromBinaryInf == True :
Index = self . _NonDynaPcdList_ . index ( PcdFromModule )
if self . _NonDynaPcdList_ [ Index ] . IsFromBinaryInf == False :
#The PCD from Binary INF will override the same one from source INF
self . _NonDynaPcdList_ . remove ( self . _NonDynaPcdList_ [ Index ])
PcdFromModule . Pending = False
self . _NonDynaPcdList_ . append ( PcdFromModule )
# Parse the DynamicEx PCD from the AsBuild INF module list of FDF.
DscModuleList = []
for ModuleInf in self . Platform . Modules . keys ():
DscModuleList . append ( os . path . normpath ( ModuleInf . Path ))
# add the PCD from modules that listed in FDF but not in DSC to Database
for InfName in FdfModuleList :
if InfName not in DscModuleList :
InfClass = PathClass ( InfName )
M = self . BuildDatabase [ InfClass , self . Arch , self . BuildTarget , self . ToolChain ]
# If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source)
# for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here.
# For binary module, if in current arch, we need to list the PCDs into database.
if not M . IsSupportedArch :
continue
# Override the module PCD setting by platform setting
ModulePcdList = self . ApplyPcdSetting ( M , M . Pcds )
for PcdFromModule in ModulePcdList :
PcdFromModule . IsFromBinaryInf = True
PcdFromModule . IsFromDsc = False
# Only allow the DynamicEx and Patchable PCD in AsBuild INF
if PcdFromModule . Type not in GenC . gDynamicExPcd and PcdFromModule . Type not in TAB_PCDS_PATCHABLE_IN_MODULE :
EdkLogger . error ( "build" , AUTOGEN_ERROR , "PCD setting error" ,
File = self . MetaFile ,
ExtraData = " \n\t Existed %s PCD %s in: \n\t\t %s \n "
% ( PcdFromModule . Type , PcdFromModule . TokenCName , InfName ))
# make sure that the "VOID*" kind of datum has MaxDatumSize set
if PcdFromModule . DatumType == "VOID*" and PcdFromModule . MaxDatumSize in [ None , '' ]:
NoDatumTypePcdList . add ( " %s . %s [ %s ]" % ( PcdFromModule . TokenSpaceGuidCName , PcdFromModule . TokenCName , InfName ))
if M . ModuleType in [ "PEIM" , "PEI_CORE" ]:
PcdFromModule . Phase = "PEI"
if PcdFromModule not in self . _DynaPcdList_ and PcdFromModule . Type in GenC . gDynamicExPcd :
self . _DynaPcdList_ . append ( PcdFromModule )
elif PcdFromModule not in self . _NonDynaPcdList_ and PcdFromModule . Type in TAB_PCDS_PATCHABLE_IN_MODULE :
self . _NonDynaPcdList_ . append ( PcdFromModule )
if PcdFromModule in self . _DynaPcdList_ and PcdFromModule . Phase == 'PEI' and PcdFromModule . Type in GenC . gDynamicExPcd :
2014-08-28 13:53:34 +00:00
# Overwrite the phase of any the same PCD existing, if Phase is PEI.
# It is to solve the case that a dynamic PCD used by a PEM module/PEI
# module & DXE module at a same time.
# Overwrite the type of the PCDs in source INF by the type of AsBuild
# INF file as DynamicEx.
2014-08-26 02:52:24 +00:00
Index = self . _DynaPcdList_ . index ( PcdFromModule )
self . _DynaPcdList_ [ Index ] . Phase = PcdFromModule . Phase
self . _DynaPcdList_ [ Index ] . Type = PcdFromModule . Type
for PcdFromModule in self . _NonDynaPcdList_ :
# If a PCD is not listed in the DSC file, but binary INF files used by
# this platform all (that use this PCD) list the PCD in a [PatchPcds]
# section, AND all source INF files used by this platform the build
# that use the PCD list the PCD in either a [Pcds] or [PatchPcds]
# section, then the tools must NOT add the PCD to the Platform's PCD
# Database; the build must assign the access method for this PCD as
# PcdsPatchableInModule.
if PcdFromModule not in self . _DynaPcdList_ :
continue
Index = self . _DynaPcdList_ . index ( PcdFromModule )
if PcdFromModule . IsFromDsc == False and \
PcdFromModule . Type in TAB_PCDS_PATCHABLE_IN_MODULE and \
PcdFromModule . IsFromBinaryInf == True and \
self . _DynaPcdList_ [ Index ] . IsFromBinaryInf == False :
Index = self . _DynaPcdList_ . index ( PcdFromModule )
self . _DynaPcdList_ . remove ( self . _DynaPcdList_ [ Index ])
2010-02-28 23:39:39 +00:00
# print out error information and break the build, if error found
if len ( NoDatumTypePcdList ) > 0 :
NoDatumTypePcdListString = " \n\t\t " . join ( NoDatumTypePcdList )
EdkLogger . error ( "build" , AUTOGEN_ERROR , "PCD setting error" ,
File = self . MetaFile ,
ExtraData = " \n\t PCD(s) without MaxDatumSize: \n\t\t %s \n "
% NoDatumTypePcdListString )
self . _NonDynamicPcdList = self . _NonDynaPcdList_
self . _DynamicPcdList = self . _DynaPcdList_
#
# Sort dynamic PCD list to:
# 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
# try to be put header of dynamicd List
# 2) If PCD is HII type, the PCD item should be put after unicode type PCD
#
# The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
#
UnicodePcdArray = []
HiiPcdArray = []
OtherPcdArray = []
2010-11-15 02:51:34 +00:00
VpdPcdDict = {}
2010-09-06 01:58:00 +00:00
VpdFile = VpdInfoFile . VpdInfoFile ()
NeedProcessVpdMapFile = False
if ( self . Workspace . ArchList [ - 1 ] == self . Arch ):
for Pcd in self . _DynamicPcdList :
# just pick the a value to determine whether is unicode string type
2015-12-01 04:22:16 +00:00
Sku = Pcd . SkuInfoList [ Pcd . SkuInfoList . keys ()[ 0 ]]
2010-09-06 01:58:00 +00:00
Sku . VpdOffset = Sku . VpdOffset . strip ()
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
PcdValue = Sku . DefaultValue
if Pcd . DatumType == 'VOID*' and PcdValue . startswith ( "L" ):
# if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
UnicodePcdArray . append ( Pcd )
elif len ( Sku . VariableName ) > 0 :
# if found HII type PCD then insert to right of UnicodeIndex
HiiPcdArray . append ( Pcd )
else :
OtherPcdArray . append ( Pcd )
if Pcd . Type in [ TAB_PCDS_DYNAMIC_VPD , TAB_PCDS_DYNAMIC_EX_VPD ]:
2015-12-01 04:22:16 +00:00
VpdPcdDict [( Pcd . TokenCName , Pcd . TokenSpaceGuidCName )] = Pcd
2010-11-15 02:51:34 +00:00
PlatformPcds = self . Platform . Pcds . keys ()
2015-12-01 04:22:16 +00:00
PlatformPcds . sort ()
2010-11-15 02:51:34 +00:00
#
# Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
#
for PcdKey in PlatformPcds :
2013-11-18 07:41:21 +00:00
Pcd = self . Platform . Pcds [ PcdKey ]
if Pcd . Type in [ TAB_PCDS_DYNAMIC_VPD , TAB_PCDS_DYNAMIC_EX_VPD ] and \
PcdKey in VpdPcdDict :
Pcd = VpdPcdDict [ PcdKey ]
for ( SkuName , Sku ) in Pcd . SkuInfoList . items ():
Sku . VpdOffset = Sku . VpdOffset . strip ()
2016-01-18 01:46:25 +00:00
PcdValue = Sku . DefaultValue
if PcdValue == "" :
PcdValue = Pcd . DefaultValue
if Sku . VpdOffset != '*' :
if PcdValue . startswith ( "{" ):
Alignment = 8
elif PcdValue . startswith ( "L" ):
Alignment = 2
else :
Alignment = 1
2016-01-29 04:44:54 +00:00
try :
VpdOffset = int ( Sku . VpdOffset )
except :
try :
VpdOffset = int ( Sku . VpdOffset , 16 )
except :
EdkLogger . error ( "build" , FORMAT_INVALID , "Invalid offset value %s for PCD %s . %s ." % ( Sku . VpdOffset , Pcd . TokenSpaceGuidCName , Pcd . TokenCName ))
if VpdOffset % Alignment != 0 :
2016-03-09 14:03:39 +08:00
if PcdValue . startswith ( "{" ):
EdkLogger . warn ( "build" , "The offset value of PCD %s . %s is not 8-byte aligned!" % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ), File = self . MetaFile )
else :
EdkLogger . error ( "build" , FORMAT_INVALID , 'The offset value of PCD %s . %s should be %s -byte aligned.' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Alignment ))
2013-11-18 07:41:21 +00:00
VpdFile . Add ( Pcd , Sku . VpdOffset )
# if the offset of a VPD is *, then it need to be fixed up by third party tool.
if not NeedProcessVpdMapFile and Sku . VpdOffset == "*" :
NeedProcessVpdMapFile = True
if self . Platform . VpdToolGuid == None or self . Platform . VpdToolGuid == '' :
EdkLogger . error ( "Build" , FILE_NOT_FOUND , \
"Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file." )
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
#
# Fix the PCDs define in VPD PCD section that never referenced by module.
# An example is PCD for signature usage.
2010-11-15 02:51:34 +00:00
#
for DscPcd in PlatformPcds :
2010-09-06 01:58:00 +00:00
DscPcdEntry = self . Platform . Pcds [ DscPcd ]
if DscPcdEntry . Type in [ TAB_PCDS_DYNAMIC_VPD , TAB_PCDS_DYNAMIC_EX_VPD ]:
if not ( self . Platform . VpdToolGuid == None or self . Platform . VpdToolGuid == '' ):
FoundFlag = False
for VpdPcd in VpdFile . _VpdArray . keys ():
# This PCD has been referenced by module
if ( VpdPcd . TokenSpaceGuidCName == DscPcdEntry . TokenSpaceGuidCName ) and \
( VpdPcd . TokenCName == DscPcdEntry . TokenCName ):
FoundFlag = True
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
# Not found, it should be signature
if not FoundFlag :
# just pick the a value to determine whether is unicode string type
2013-11-18 07:41:21 +00:00
for ( SkuName , Sku ) in DscPcdEntry . SkuInfoList . items ():
Sku . VpdOffset = Sku . VpdOffset . strip ()
# Need to iterate DEC pcd information to get the value & datumtype
for eachDec in self . PackageList :
for DecPcd in eachDec . Pcds :
DecPcdEntry = eachDec . Pcds [ DecPcd ]
if ( DecPcdEntry . TokenSpaceGuidCName == DscPcdEntry . TokenSpaceGuidCName ) and \
( DecPcdEntry . TokenCName == DscPcdEntry . TokenCName ):
# Print warning message to let the developer make a determine.
EdkLogger . warn ( "build" , "Unreferenced vpd pcd used!" ,
File = self . MetaFile , \
ExtraData = "PCD: %s . %s used in the DSC file %s is unreferenced." \
% ( DscPcdEntry . TokenSpaceGuidCName , DscPcdEntry . TokenCName , self . Platform . MetaFile . Path ))
DscPcdEntry . DatumType = DecPcdEntry . DatumType
DscPcdEntry . DefaultValue = DecPcdEntry . DefaultValue
DscPcdEntry . TokenValue = DecPcdEntry . TokenValue
DscPcdEntry . TokenSpaceGuidValue = eachDec . Guids [ DecPcdEntry . TokenSpaceGuidCName ]
# Only fix the value while no value provided in DSC file.
if ( Sku . DefaultValue == "" or Sku . DefaultValue == None ):
DscPcdEntry . SkuInfoList [ DscPcdEntry . SkuInfoList . keys ()[ 0 ]] . DefaultValue = DecPcdEntry . DefaultValue
if DscPcdEntry not in self . _DynamicPcdList :
self . _DynamicPcdList . append ( DscPcdEntry )
# Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]
Sku . VpdOffset = Sku . VpdOffset . strip ()
PcdValue = Sku . DefaultValue
2016-01-18 01:46:25 +00:00
if PcdValue == "" :
PcdValue = DscPcdEntry . DefaultValue
if Sku . VpdOffset != '*' :
if PcdValue . startswith ( "{" ):
Alignment = 8
elif PcdValue . startswith ( "L" ):
Alignment = 2
else :
Alignment = 1
2016-01-29 04:44:54 +00:00
try :
VpdOffset = int ( Sku . VpdOffset )
except :
try :
VpdOffset = int ( Sku . VpdOffset , 16 )
except :
EdkLogger . error ( "build" , FORMAT_INVALID , "Invalid offset value %s for PCD %s . %s ." % ( Sku . VpdOffset , DscPcdEntry . TokenSpaceGuidCName , DscPcdEntry . TokenCName ))
if VpdOffset % Alignment != 0 :
2016-03-09 14:03:39 +08:00
if PcdValue . startswith ( "{" ):
EdkLogger . warn ( "build" , "The offset value of PCD %s . %s is not 8-byte aligned!" % ( DscPcdEntry . TokenSpaceGuidCName , DscPcdEntry . TokenCName ), File = self . MetaFile )
else :
EdkLogger . error ( "build" , FORMAT_INVALID , 'The offset value of PCD %s . %s should be %s -byte aligned.' % ( DscPcdEntry . TokenSpaceGuidCName , DscPcdEntry . TokenCName , Alignment ))
2013-11-18 07:41:21 +00:00
VpdFile . Add ( DscPcdEntry , Sku . VpdOffset )
if not NeedProcessVpdMapFile and Sku . VpdOffset == "*" :
NeedProcessVpdMapFile = True
if DscPcdEntry . DatumType == 'VOID*' and PcdValue . startswith ( "L" ):
UnicodePcdArray . append ( DscPcdEntry )
elif len ( Sku . VariableName ) > 0 :
HiiPcdArray . append ( DscPcdEntry )
else :
OtherPcdArray . append ( DscPcdEntry )
# if the offset of a VPD is *, then it need to be fixed up by third party tool.
2010-09-06 01:58:00 +00:00
if ( self . Platform . FlashDefinition == None or self . Platform . FlashDefinition == '' ) and \
VpdFile . GetCount () != 0 :
EdkLogger . error ( "build" , ATTRIBUTE_NOT_AVAILABLE ,
"Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str ( self . Platform . MetaFile ))
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
if VpdFile . GetCount () != 0 :
FvPath = os . path . join ( self . BuildDir , "FV" )
if not os . path . exists ( FvPath ):
try :
os . makedirs ( FvPath )
except :
EdkLogger . error ( "build" , FILE_WRITE_FAILURE , "Fail to create FV folder under %s " % self . BuildDir )
2015-12-01 04:22:16 +00:00
2010-10-11 06:26:52 +00:00
VpdFilePath = os . path . join ( FvPath , " %s .txt" % self . Platform . VpdToolGuid )
2016-01-29 04:48:55 +00:00
if VpdFile . Write ( VpdFilePath ):
2010-09-06 01:58:00 +00:00
# retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.
BPDGToolName = None
for ToolDef in self . ToolDefinition . values ():
if ToolDef . has_key ( "GUID" ) and ToolDef [ "GUID" ] == self . Platform . VpdToolGuid :
if not ToolDef . has_key ( "PATH" ):
EdkLogger . error ( "build" , ATTRIBUTE_NOT_AVAILABLE , "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self . Platform . VpdToolGuid )
BPDGToolName = ToolDef [ "PATH" ]
break
# Call third party GUID BPDG tool.
if BPDGToolName != None :
2010-10-11 06:26:52 +00:00
VpdInfoFile . CallExtenalBPDGTool ( BPDGToolName , VpdFilePath )
2010-09-06 01:58:00 +00:00
else :
EdkLogger . error ( "Build" , FILE_NOT_FOUND , "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file." )
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
# Process VPD map file generated by third party BPDG tool
if NeedProcessVpdMapFile :
2010-10-11 06:26:52 +00:00
VpdMapFilePath = os . path . join ( self . BuildDir , "FV" , " %s .map" % self . Platform . VpdToolGuid )
2010-09-06 01:58:00 +00:00
if os . path . exists ( VpdMapFilePath ):
VpdFile . Read ( VpdMapFilePath )
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
# Fixup "*" offset
for Pcd in self . _DynamicPcdList :
# just pick the a value to determine whether is unicode string type
2013-11-18 07:41:21 +00:00
i = 0
for ( SkuName , Sku ) in Pcd . SkuInfoList . items ():
if Sku . VpdOffset == "*" :
Sku . VpdOffset = VpdFile . GetOffset ( Pcd )[ i ] . strip ()
i += 1
2010-09-06 01:58:00 +00:00
else :
EdkLogger . error ( "build" , FILE_READ_FAILURE , "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath )
2015-12-01 04:22:16 +00:00
2010-09-06 01:58:00 +00:00
# Delete the DynamicPcdList At the last time enter into this function
2015-12-01 04:22:16 +00:00
del self . _DynamicPcdList [:]
2010-02-28 23:39:39 +00:00
self . _DynamicPcdList . extend ( UnicodePcdArray )
self . _DynamicPcdList . extend ( HiiPcdArray )
self . _DynamicPcdList . extend ( OtherPcdArray )
2014-08-26 02:52:24 +00:00
self . AllPcdList = self . _NonDynamicPcdList + self . _DynamicPcdList
2010-02-28 23:39:39 +00:00
## Return the platform build data object
def _GetPlatform ( self ):
if self . _Platform == None :
2011-10-29 06:59:30 +00:00
self . _Platform = self . BuildDatabase [ self . MetaFile , self . Arch , self . BuildTarget , self . ToolChain ]
2010-02-28 23:39:39 +00:00
return self . _Platform
## Return platform name
def _GetName ( self ):
return self . Platform . PlatformName
## Return the meta file GUID
def _GetGuid ( self ):
return self . Platform . Guid
## Return the platform version
def _GetVersion ( self ):
return self . Platform . Version
## Return the FDF file name
def _GetFdfFile ( self ):
if self . _FdfFile == None :
if self . Workspace . FdfFile != "" :
2015-10-08 09:27:14 +00:00
self . _FdfFile = mws . join ( self . WorkspaceDir , self . Workspace . FdfFile )
2010-02-28 23:39:39 +00:00
else :
self . _FdfFile = ''
return self . _FdfFile
## Return the build output directory platform specifies
def _GetOutputDir ( self ):
return self . Platform . OutputDirectory
## Return the directory to store all intermediate and final files built
def _GetBuildDir ( self ):
if self . _BuildDir == None :
if os . path . isabs ( self . OutputDir ):
self . _BuildDir = path . join (
path . abspath ( self . OutputDir ),
self . BuildTarget + "_" + self . ToolChain ,
)
else :
self . _BuildDir = path . join (
self . WorkspaceDir ,
self . OutputDir ,
self . BuildTarget + "_" + self . ToolChain ,
)
return self . _BuildDir
## Return directory of platform makefile
#
# @retval string Makefile directory
#
def _GetMakeFileDir ( self ):
if self . _MakeFileDir == None :
self . _MakeFileDir = path . join ( self . BuildDir , self . Arch )
return self . _MakeFileDir
## Return build command string
#
# @retval string Build command string
#
def _GetBuildCommand ( self ):
if self . _BuildCommand == None :
self . _BuildCommand = []
if "MAKE" in self . ToolDefinition and "PATH" in self . ToolDefinition [ "MAKE" ]:
self . _BuildCommand += SplitOption ( self . ToolDefinition [ "MAKE" ][ "PATH" ])
if "FLAGS" in self . ToolDefinition [ "MAKE" ]:
NewOption = self . ToolDefinition [ "MAKE" ][ "FLAGS" ] . strip ()
if NewOption != '' :
2010-11-15 02:51:34 +00:00
self . _BuildCommand += SplitOption ( NewOption )
2010-02-28 23:39:39 +00:00
return self . _BuildCommand
## Get tool chain definition
#
# Get each tool defition for given tool chain from tools_def.txt and platform
#
def _GetToolDefinition ( self ):
if self . _ToolDefinitions == None :
ToolDefinition = self . Workspace . ToolDef . ToolsDefTxtDictionary
if TAB_TOD_DEFINES_COMMAND_TYPE not in self . Workspace . ToolDef . ToolsDefTxtDatabase :
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE , "No tools found in configuration" ,
ExtraData = "[ %s ]" % self . MetaFile )
self . _ToolDefinitions = {}
DllPathList = set ()
for Def in ToolDefinition :
Target , Tag , Arch , Tool , Attr = Def . split ( "_" )
if Target != self . BuildTarget or Tag != self . ToolChain or Arch != self . Arch :
continue
Value = ToolDefinition [ Def ]
# don't record the DLL
if Attr == "DLL" :
DllPathList . add ( Value )
continue
if Tool not in self . _ToolDefinitions :
self . _ToolDefinitions [ Tool ] = {}
self . _ToolDefinitions [ Tool ][ Attr ] = Value
ToolsDef = ''
MakePath = ''
if GlobalData . gOptions . SilentMode and "MAKE" in self . _ToolDefinitions :
if "FLAGS" not in self . _ToolDefinitions [ "MAKE" ]:
self . _ToolDefinitions [ "MAKE" ][ "FLAGS" ] = ""
self . _ToolDefinitions [ "MAKE" ][ "FLAGS" ] += " -s"
MakeFlags = ''
for Tool in self . _ToolDefinitions :
for Attr in self . _ToolDefinitions [ Tool ]:
Value = self . _ToolDefinitions [ Tool ][ Attr ]
if Tool in self . BuildOption and Attr in self . BuildOption [ Tool ]:
# check if override is indicated
if self . BuildOption [ Tool ][ Attr ] . startswith ( '=' ):
Value = self . BuildOption [ Tool ][ Attr ][ 1 :]
else :
Value += " " + self . BuildOption [ Tool ][ Attr ]
if Attr == "PATH" :
# Don't put MAKE definition in the file
if Tool == "MAKE" :
MakePath = Value
else :
ToolsDef += " %s = %s \n " % ( Tool , Value )
elif Attr != "DLL" :
# Don't put MAKE definition in the file
if Tool == "MAKE" :
if Attr == "FLAGS" :
MakeFlags = Value
else :
ToolsDef += " %s _ %s = %s \n " % ( Tool , Attr , Value )
ToolsDef += " \n "
SaveFileOnChange ( self . ToolDefinitionFile , ToolsDef )
for DllPath in DllPathList :
os . environ [ "PATH" ] = DllPath + os . pathsep + os . environ [ "PATH" ]
os . environ [ "MAKE_FLAGS" ] = MakeFlags
return self . _ToolDefinitions
## Return the paths of tools
def _GetToolDefFile ( self ):
if self . _ToolDefFile == None :
self . _ToolDefFile = os . path . join ( self . MakeFileDir , "TOOLS_DEF." + self . Arch )
return self . _ToolDefFile
## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
def _GetToolChainFamily ( self ):
if self . _ToolChainFamily == None :
ToolDefinition = self . Workspace . ToolDef . ToolsDefTxtDatabase
if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
or self . ToolChain not in ToolDefinition [ TAB_TOD_DEFINES_FAMILY ] \
or not ToolDefinition [ TAB_TOD_DEFINES_FAMILY ][ self . ToolChain ]:
EdkLogger . verbose ( "No tool chain family found in configuration for %s . Default to MSFT." \
% self . ToolChain )
self . _ToolChainFamily = "MSFT"
else :
self . _ToolChainFamily = ToolDefinition [ TAB_TOD_DEFINES_FAMILY ][ self . ToolChain ]
return self . _ToolChainFamily
def _GetBuildRuleFamily ( self ):
if self . _BuildRuleFamily == None :
ToolDefinition = self . Workspace . ToolDef . ToolsDefTxtDatabase
if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
or self . ToolChain not in ToolDefinition [ TAB_TOD_DEFINES_BUILDRULEFAMILY ] \
or not ToolDefinition [ TAB_TOD_DEFINES_BUILDRULEFAMILY ][ self . ToolChain ]:
EdkLogger . verbose ( "No tool chain family found in configuration for %s . Default to MSFT." \
% self . ToolChain )
self . _BuildRuleFamily = "MSFT"
else :
self . _BuildRuleFamily = ToolDefinition [ TAB_TOD_DEFINES_BUILDRULEFAMILY ][ self . ToolChain ]
return self . _BuildRuleFamily
## Return the build options specific for all modules in this platform
def _GetBuildOptions ( self ):
if self . _BuildOption == None :
self . _BuildOption = self . _ExpandBuildOption ( self . Platform . BuildOptions )
return self . _BuildOption
## Return the build options specific for EDK modules in this platform
def _GetEdkBuildOptions ( self ):
if self . _EdkBuildOption == None :
self . _EdkBuildOption = self . _ExpandBuildOption ( self . Platform . BuildOptions , EDK_NAME )
return self . _EdkBuildOption
## Return the build options specific for EDKII modules in this platform
def _GetEdkIIBuildOptions ( self ):
if self . _EdkIIBuildOption == None :
self . _EdkIIBuildOption = self . _ExpandBuildOption ( self . Platform . BuildOptions , EDKII_NAME )
return self . _EdkIIBuildOption
2014-08-28 13:53:34 +00:00
## Parse build_rule.txt in Conf Directory.
2010-02-28 23:39:39 +00:00
#
# @retval BuildRule object
#
def _GetBuildRule ( self ):
if self . _BuildRule == None :
BuildRuleFile = None
if TAB_TAT_DEFINES_BUILD_RULE_CONF in self . Workspace . TargetTxt . TargetTxtDictionary :
BuildRuleFile = self . Workspace . TargetTxt . TargetTxtDictionary [ TAB_TAT_DEFINES_BUILD_RULE_CONF ]
if BuildRuleFile in [ None , '' ]:
2014-08-28 13:53:34 +00:00
BuildRuleFile = gDefaultBuildRuleFile
2010-02-28 23:39:39 +00:00
self . _BuildRule = BuildRule ( BuildRuleFile )
2012-04-10 07:18:20 +00:00
if self . _BuildRule . _FileVersion == "" :
self . _BuildRule . _FileVersion = AutoGenReqBuildRuleVerNum
else :
if self . _BuildRule . _FileVersion < AutoGenReqBuildRuleVerNum :
# If Build Rule's version is less than the version number required by the tools, halting the build.
2015-12-01 04:22:16 +00:00
EdkLogger . error ( "build" , AUTOGEN_ERROR ,
2012-04-10 07:18:20 +00:00
ExtraData = "The version number [ %s ] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [ %s ])" \
% ( self . _BuildRule . _FileVersion , AutoGenReqBuildRuleVerNum ))
2015-12-01 04:22:16 +00:00
2010-02-28 23:39:39 +00:00
return self . _BuildRule
## Summarize the packages used by modules in this platform
def _GetPackageList ( self ):
if self . _PackageList == None :
self . _PackageList = set ()
for La in self . LibraryAutoGenList :
self . _PackageList . update ( La . DependentPackageList )
for Ma in self . ModuleAutoGenList :
self . _PackageList . update ( Ma . DependentPackageList )
2014-08-26 02:52:24 +00:00
#Collect package set information from INF of FDF
PkgSet = set ()
for ModuleFile in self . _AsBuildModuleList :
if ModuleFile in self . Platform . Modules :
continue
ModuleData = self . BuildDatabase [ ModuleFile , self . Arch , self . BuildTarget , self . ToolChain ]
PkgSet . update ( ModuleData . Packages )
self . _PackageList = list ( self . _PackageList ) + list ( PkgSet )
2010-02-28 23:39:39 +00:00
return self . _PackageList
2014-01-10 05:25:50 +00:00
def _GetNonDynamicPcdDict ( self ):
if self . _NonDynamicPcdDict :
return self . _NonDynamicPcdDict
for Pcd in self . NonDynamicPcdList :
self . _NonDynamicPcdDict [( Pcd . TokenCName , Pcd . TokenSpaceGuidCName )] = Pcd
return self . _NonDynamicPcdDict
2010-02-28 23:39:39 +00:00
## Get list of non-dynamic PCDs
def _GetNonDynamicPcdList ( self ):
2010-09-06 01:58:00 +00:00
if self . _NonDynamicPcdList == None :
self . CollectPlatformDynamicPcds ()
2010-02-28 23:39:39 +00:00
return self . _NonDynamicPcdList
## Get list of dynamic PCDs
def _GetDynamicPcdList ( self ):
2010-09-06 01:58:00 +00:00
if self . _DynamicPcdList == None :
self . CollectPlatformDynamicPcds ()
2010-02-28 23:39:39 +00:00
return self . _DynamicPcdList
## Generate Token Number for all PCD
def _GetPcdTokenNumbers ( self ):
if self . _PcdTokenNumber == None :
self . _PcdTokenNumber = sdict ()
TokenNumber = 1
2011-12-07 06:19:28 +00:00
#
# Make the Dynamic and DynamicEx PCD use within different TokenNumber area.
# Such as:
#
# Dynamic PCD:
# TokenNumber 0 ~ 10
# DynamicEx PCD:
# TokeNumber 11 ~ 20
#
2010-02-28 23:39:39 +00:00
for Pcd in self . DynamicPcdList :
if Pcd . Phase == "PEI" :
2011-12-07 06:19:28 +00:00
if Pcd . Type in [ "Dynamic" , "DynamicDefault" , "DynamicVpd" , "DynamicHii" ]:
EdkLogger . debug ( EdkLogger . DEBUG_5 , " %s %s ( %s ) -> %d " % ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , Pcd . Phase , TokenNumber ))
self . _PcdTokenNumber [ Pcd . TokenCName , Pcd . TokenSpaceGuidCName ] = TokenNumber
TokenNumber += 1
2015-12-01 04:22:16 +00:00
2011-12-07 06:19:28 +00:00
for Pcd in self . DynamicPcdList :
if Pcd . Phase == "PEI" :
if Pcd . Type in [ "DynamicEx" , "DynamicExDefault" , "DynamicExVpd" , "DynamicExHii" ]:
EdkLogger . debug ( EdkLogger . DEBUG_5 , " %s %s ( %s ) -> %d " % ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , Pcd . Phase , TokenNumber ))
self . _PcdTokenNumber [ Pcd . TokenCName , Pcd . TokenSpaceGuidCName ] = TokenNumber
TokenNumber += 1
2015-12-01 04:22:16 +00:00
2010-02-28 23:39:39 +00:00
for Pcd in self . DynamicPcdList :
if Pcd . Phase == "DXE" :
2011-12-07 06:19:28 +00:00
if Pcd . Type in [ "Dynamic" , "DynamicDefault" , "DynamicVpd" , "DynamicHii" ]:
EdkLogger . debug ( EdkLogger . DEBUG_5 , " %s %s ( %s ) -> %d " % ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , Pcd . Phase , TokenNumber ))
self . _PcdTokenNumber [ Pcd . TokenCName , Pcd . TokenSpaceGuidCName ] = TokenNumber
TokenNumber += 1
2015-12-01 04:22:16 +00:00
2011-12-07 06:19:28 +00:00
for Pcd in self . DynamicPcdList :
if Pcd . Phase == "DXE" :
if Pcd . Type in [ "DynamicEx" , "DynamicExDefault" , "DynamicExVpd" , "DynamicExHii" ]:
EdkLogger . debug ( EdkLogger . DEBUG_5 , " %s %s ( %s ) -> %d " % ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , Pcd . Phase , TokenNumber ))
self . _PcdTokenNumber [ Pcd . TokenCName , Pcd . TokenSpaceGuidCName ] = TokenNumber
TokenNumber += 1
2015-12-01 04:22:16 +00:00
2010-02-28 23:39:39 +00:00
for Pcd in self . NonDynamicPcdList :
self . _PcdTokenNumber [ Pcd . TokenCName , Pcd . TokenSpaceGuidCName ] = TokenNumber
TokenNumber += 1
return self . _PcdTokenNumber
## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
def _GetAutoGenObjectList ( self ):
self . _ModuleAutoGenList = []
self . _LibraryAutoGenList = []
for ModuleFile in self . Platform . Modules :
Ma = ModuleAutoGen (
self . Workspace ,
ModuleFile ,
self . BuildTarget ,
self . ToolChain ,
self . Arch ,
self . MetaFile
)
if Ma not in self . _ModuleAutoGenList :
self . _ModuleAutoGenList . append ( Ma )
for La in Ma . LibraryAutoGenList :
if La not in self . _LibraryAutoGenList :
self . _LibraryAutoGenList . append ( La )
2014-01-10 05:25:50 +00:00
if Ma not in La . _ReferenceModules :
La . _ReferenceModules . append ( Ma )
2010-02-28 23:39:39 +00:00
## Summarize ModuleAutoGen objects of all modules to be built for this platform
def _GetModuleAutoGenList ( self ):
if self . _ModuleAutoGenList == None :
self . _GetAutoGenObjectList ()
return self . _ModuleAutoGenList
## Summarize ModuleAutoGen objects of all libraries to be built for this platform
def _GetLibraryAutoGenList ( self ):
if self . _LibraryAutoGenList == None :
self . _GetAutoGenObjectList ()
return self . _LibraryAutoGenList
## Test if a module is supported by the platform
#
# An error will be raised directly if the module or its arch is not supported
# by the platform or current configuration
#
def ValidModule ( self , Module ):
2014-08-26 02:52:24 +00:00
return Module in self . Platform . Modules or Module in self . Platform . LibraryInstances \
or Module in self . _AsBuildModuleList
2010-02-28 23:39:39 +00:00
## Resolve the library classes in a module to library instances
#
# This method will not only resolve library classes but also sort the library
# instances according to the dependency-ship.
#
# @param Module The module from which the library classes will be resolved
#
# @retval library_list List of library instances sorted
#
def ApplyLibraryInstance ( self , Module ):
ModuleType = Module . ModuleType
# for overridding library instances with module specific setting
PlatformModule = self . Platform . Modules [ str ( Module )]
# add forced library instances (specified under LibraryClasses sections)
2011-05-11 10:26:49 +00:00
#
# If a module has a MODULE_TYPE of USER_DEFINED,
# do not link in NULL library class instances from the global [LibraryClasses.*] sections.
#
if Module . ModuleType != SUP_MODULE_USER_DEFINED :
for LibraryClass in self . Platform . LibraryClasses . GetKeys ():
if LibraryClass . startswith ( "NULL" ) and self . Platform . LibraryClasses [ LibraryClass , Module . ModuleType ]:
Module . LibraryClasses [ LibraryClass ] = self . Platform . LibraryClasses [ LibraryClass , Module . ModuleType ]
2010-02-28 23:39:39 +00:00
# add forced library instances (specified in module overrides)
for LibraryClass in PlatformModule . LibraryClasses :
if LibraryClass . startswith ( "NULL" ):
Module . LibraryClasses [ LibraryClass ] = PlatformModule . LibraryClasses [ LibraryClass ]
2011-09-18 12:17:25 +00:00
# EdkII module
2010-02-28 23:39:39 +00:00
LibraryConsumerList = [ Module ]
Constructor = []
ConsumedByList = sdict ()
LibraryInstance = sdict ()
EdkLogger . verbose ( "" )
EdkLogger . verbose ( "Library instances of module [ %s ] [ %s ]:" % ( str ( Module ), self . Arch ))
while len ( LibraryConsumerList ) > 0 :
M = LibraryConsumerList . pop ()
for LibraryClassName in M . LibraryClasses :
if LibraryClassName not in LibraryInstance :
# override library instance for this module
if LibraryClassName in PlatformModule . LibraryClasses :
LibraryPath = PlatformModule . LibraryClasses [ LibraryClassName ]
else :
LibraryPath = self . Platform . LibraryClasses [ LibraryClassName , ModuleType ]
if LibraryPath == None or LibraryPath == "" :
LibraryPath = M . LibraryClasses [ LibraryClassName ]
if LibraryPath == None or LibraryPath == "" :
EdkLogger . error ( "build" , RESOURCE_NOT_AVAILABLE ,
"Instance of library class [ %s ] is not found" % LibraryClassName ,
File = self . MetaFile ,
ExtraData = "in [ %s ] [ %s ] \n\t consumed by module [ %s ]" % ( str ( M ), self . Arch , str ( Module )))
2011-10-29 06:59:30 +00:00
LibraryModule = self . BuildDatabase [ LibraryPath , self . Arch , self . BuildTarget , self . ToolChain ]
2010-02-28 23:39:39 +00:00
# for those forced library instance (NULL library), add a fake library class
if LibraryClassName . startswith ( "NULL" ):
LibraryModule . LibraryClass . append ( LibraryClassObject ( LibraryClassName , [ ModuleType ]))
elif LibraryModule . LibraryClass == None \
or len ( LibraryModule . LibraryClass ) == 0 \
or ( ModuleType != 'USER_DEFINED'
and ModuleType not in LibraryModule . LibraryClass [ 0 ] . SupModList ):
# only USER_DEFINED can link against any library instance despite of its SupModList
EdkLogger . error ( "build" , OPTION_MISSING ,
"Module type [ %s ] is not supported by library instance [ %s ]" \
% ( ModuleType , LibraryPath ), File = self . MetaFile ,
ExtraData = "consumed by [ %s ]" % str ( Module ))
LibraryInstance [ LibraryClassName ] = LibraryModule
LibraryConsumerList . append ( LibraryModule )
EdkLogger . verbose ( " \t " + str ( LibraryClassName ) + " : " + str ( LibraryModule ))
else :
LibraryModule = LibraryInstance [ LibraryClassName ]
if LibraryModule == None :
continue
if LibraryModule . ConstructorList != [] and LibraryModule not in Constructor :
Constructor . append ( LibraryModule )
if LibraryModule not in ConsumedByList :
ConsumedByList [ LibraryModule ] = []
# don't add current module itself to consumer list
if M != Module :
if M in ConsumedByList [ LibraryModule ]:
continue
ConsumedByList [ LibraryModule ] . append ( M )
#
# Initialize the sorted output list to the empty set
#
SortedLibraryList = []
#
# Q <- Set of all nodes with no incoming edges
#
LibraryList = [] #LibraryInstance.values()
Q = []
for LibraryClassName in LibraryInstance :
M = LibraryInstance [ LibraryClassName ]
LibraryList . append ( M )
if ConsumedByList [ M ] == []:
Q . append ( M )
#
# start the DAG algorithm
#
while True :
EdgeRemoved = True
while Q == [] and EdgeRemoved :
EdgeRemoved = False
# for each node Item with a Constructor
for Item in LibraryList :
if Item not in Constructor :
continue
# for each Node without a constructor with an edge e from Item to Node
for Node in ConsumedByList [ Item ]:
if Node in Constructor :
continue
# remove edge e from the graph if Node has no constructor
ConsumedByList [ Item ] . remove ( Node )
EdgeRemoved = True
if ConsumedByList [ Item ] == []:
# insert Item into Q
Q . insert ( 0 , Item )
break
if Q != []:
break
# DAG is done if there's no more incoming edge for all nodes
if Q == []:
break
# remove node from Q
Node = Q . pop ()
# output Node
SortedLibraryList . append ( Node )
# for each node Item with an edge e from Node to Item do
for Item in LibraryList :
if Node not in ConsumedByList [ Item ]:
continue
# remove edge e from the graph
ConsumedByList [ Item ] . remove ( Node )
if ConsumedByList [ Item ] != []:
continue
# insert Item into Q, if Item has no other incoming edges
Q . insert ( 0 , Item )
#
# if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
#
for Item in LibraryList :
if ConsumedByList [ Item ] != [] and Item in Constructor and len ( Constructor ) > 1 :
ErrorMessage = " \t consumed by " + " \n\t consumed by " . join ([ str ( L ) for L in ConsumedByList [ Item ]])
EdkLogger . error ( "build" , BUILD_ERROR , 'Library [ %s ] with constructors has a cycle' % str ( Item ),
ExtraData = ErrorMessage , File = self . MetaFile )
if Item not in SortedLibraryList :
SortedLibraryList . append ( Item )
#
# Build the list of constructor and destructir names
# The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
#
SortedLibraryList . reverse ()
return SortedLibraryList
## Override PCD setting (type, value, ...)
#
# @param ToPcd The PCD to be overrided
# @param FromPcd The PCD overrideing from
#
def _OverridePcd ( self , ToPcd , FromPcd , Module = "" ):
#
# in case there's PCDs coming from FDF file, which have no type given.
# at this point, ToPcd.Type has the type found from dependent
# package
#
if FromPcd != None :
if ToPcd . Pending and FromPcd . Type not in [ None , '' ]:
ToPcd . Type = FromPcd . Type
2010-09-06 01:58:00 +00:00
elif ( ToPcd . Type not in [ None , '' ]) and ( FromPcd . Type not in [ None , '' ]) \
and ( ToPcd . Type != FromPcd . Type ) and ( ToPcd . Type in FromPcd . Type ):
if ToPcd . Type . strip () == "DynamicEx" :
2015-12-01 04:22:16 +00:00
ToPcd . Type = FromPcd . Type
2010-02-28 23:39:39 +00:00
elif ToPcd . Type not in [ None , '' ] and FromPcd . Type not in [ None , '' ] \
and ToPcd . Type != FromPcd . Type :
EdkLogger . error ( "build" , OPTION_CONFLICT , "Mismatched PCD type" ,
ExtraData = " %s . %s is defined as [ %s ] in module %s , but as [ %s ] in platform." \
% ( ToPcd . TokenSpaceGuidCName , ToPcd . TokenCName ,
ToPcd . Type , Module , FromPcd . Type ),
File = self . MetaFile )
if FromPcd . MaxDatumSize not in [ None , '' ]:
ToPcd . MaxDatumSize = FromPcd . MaxDatumSize
if FromPcd . DefaultValue not in [ None , '' ]:
ToPcd . DefaultValue = FromPcd . DefaultValue
if FromPcd . TokenValue not in [ None , '' ]:
ToPcd . TokenValue = FromPcd . TokenValue
if FromPcd . MaxDatumSize not in [ None , '' ]:
ToPcd . MaxDatumSize = FromPcd . MaxDatumSize
if FromPcd . DatumType not in [ None , '' ]:
ToPcd . DatumType = FromPcd . DatumType
if FromPcd . SkuInfoList not in [ None , '' , []]:
ToPcd . SkuInfoList = FromPcd . SkuInfoList
# check the validation of datum
IsValid , Cause = CheckPcdDatum ( ToPcd . DatumType , ToPcd . DefaultValue )
if not IsValid :
EdkLogger . error ( 'build' , FORMAT_INVALID , Cause , File = self . MetaFile ,
ExtraData = " %s . %s " % ( ToPcd . TokenSpaceGuidCName , ToPcd . TokenCName ))
2015-04-10 06:59:47 +00:00
ToPcd . validateranges = FromPcd . validateranges
ToPcd . validlists = FromPcd . validlists
ToPcd . expressions = FromPcd . expressions
2010-02-28 23:39:39 +00:00
if ToPcd . DatumType == "VOID*" and ToPcd . MaxDatumSize in [ '' , None ]:
EdkLogger . debug ( EdkLogger . DEBUG_9 , "No MaxDatumSize specified for PCD %s . %s " \
% ( ToPcd . TokenSpaceGuidCName , ToPcd . TokenCName ))
Value = ToPcd . DefaultValue
if Value in [ None , '' ]:
2013-11-18 07:41:21 +00:00
ToPcd . MaxDatumSize = '1'
2010-02-28 23:39:39 +00:00
elif Value [ 0 ] == 'L' :
2013-11-18 07:41:21 +00:00
ToPcd . MaxDatumSize = str (( len ( Value ) - 2 ) * 2 )
2010-02-28 23:39:39 +00:00
elif Value [ 0 ] == '{' :
ToPcd . MaxDatumSize = str ( len ( Value . split ( ',' )))
else :
2013-11-18 07:41:21 +00:00
ToPcd . MaxDatumSize = str ( len ( Value ) - 1 )
2010-02-28 23:39:39 +00:00
# apply default SKU for dynamic PCDS if specified one is not available
if ( ToPcd . Type in PCD_DYNAMIC_TYPE_LIST or ToPcd . Type in PCD_DYNAMIC_EX_TYPE_LIST ) \
and ToPcd . SkuInfoList in [ None , {}, '' ]:
if self . Platform . SkuName in self . Platform . SkuIds :
SkuName = self . Platform . SkuName
else :
SkuName = 'DEFAULT'
ToPcd . SkuInfoList = {
SkuName : SkuInfoClass ( SkuName , self . Platform . SkuIds [ SkuName ], '' , '' , '' , '' , '' , ToPcd . DefaultValue )
}
## Apply PCD setting defined platform to a module
#
# @param Module The module from which the PCD setting will be overrided
#
# @retval PCD_list The list PCDs with settings from platform
#
def ApplyPcdSetting ( self , Module , Pcds ):
# for each PCD in module
2015-12-01 04:22:16 +00:00
for Name , Guid in Pcds :
PcdInModule = Pcds [ Name , Guid ]
2010-02-28 23:39:39 +00:00
# find out the PCD setting in platform
2015-12-01 04:22:16 +00:00
if ( Name , Guid ) in self . Platform . Pcds :
PcdInPlatform = self . Platform . Pcds [ Name , Guid ]
2010-02-28 23:39:39 +00:00
else :
PcdInPlatform = None
# then override the settings if any
self . _OverridePcd ( PcdInModule , PcdInPlatform , Module )
# resolve the VariableGuid value
for SkuId in PcdInModule . SkuInfoList :
Sku = PcdInModule . SkuInfoList [ SkuId ]
if Sku . VariableGuid == '' : continue
Sku . VariableGuidValue = GuidValue ( Sku . VariableGuid , self . PackageList )
if Sku . VariableGuidValue == None :
PackageList = " \n\t " . join ([ str ( P ) for P in self . PackageList ])
EdkLogger . error (
'build' ,
RESOURCE_NOT_AVAILABLE ,
"Value of GUID [ %s ] is not found in" % Sku . VariableGuid ,
ExtraData = PackageList + " \n\t (used with %s . %s from module %s )" \
% ( Guid , Name , str ( Module )),
File = self . MetaFile
)
# override PCD settings with module specific setting
if Module in self . Platform . Modules :
PlatformModule = self . Platform . Modules [ str ( Module )]
for Key in PlatformModule . Pcds :
if Key in Pcds :
self . _OverridePcd ( Pcds [ Key ], PlatformModule . Pcds [ Key ], Module )
return Pcds . values ()
## Resolve library names to library modules
#
2011-09-18 12:17:25 +00:00
# (for Edk.x modules)
2010-02-28 23:39:39 +00:00
#
# @param Module The module from which the library names will be resolved
#
# @retval library_list The list of library modules
#
def ResolveLibraryReference ( self , Module ):
EdkLogger . verbose ( "" )
EdkLogger . verbose ( "Library instances of module [ %s ] [ %s ]:" % ( str ( Module ), self . Arch ))
LibraryConsumerList = [ Module ]
2011-09-18 12:17:25 +00:00
# "CompilerStub" is a must for Edk modules
2010-02-28 23:39:39 +00:00
if Module . Libraries :
Module . Libraries . append ( "CompilerStub" )
LibraryList = []
while len ( LibraryConsumerList ) > 0 :
M = LibraryConsumerList . pop ()
for LibraryName in M . Libraries :
Library = self . Platform . LibraryClasses [ LibraryName , ':dummy:' ]
if Library == None :
for Key in self . Platform . LibraryClasses . data . keys ():
if LibraryName . upper () == Key . upper ():
Library = self . Platform . LibraryClasses [ Key , ':dummy:' ]
break
if Library == None :
EdkLogger . warn ( "build" , "Library [ %s ] is not found" % LibraryName , File = str ( M ),
ExtraData = " \t %s [ %s ]" % ( str ( Module ), self . Arch ))
continue
if Library not in LibraryList :
LibraryList . append ( Library )
LibraryConsumerList . append ( Library )
EdkLogger . verbose ( " \t " + LibraryName + " : " + str ( Library ) + ' ' + str ( type ( Library )))
return LibraryList
2010-11-15 02:51:34 +00:00
## Calculate the priority value of the build option
#
# @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
#
# @retval Value Priority value based on the priority list.
#
def CalculatePriorityValue ( self , Key ):
2015-12-01 04:22:16 +00:00
Target , ToolChain , Arch , CommandType , Attr = Key . split ( '_' )
PriorityValue = 0x11111
2010-11-15 02:51:34 +00:00
if Target == "*" :
PriorityValue &= 0x01111
if ToolChain == "*" :
PriorityValue &= 0x10111
if Arch == "*" :
PriorityValue &= 0x11011
if CommandType == "*" :
PriorityValue &= 0x11101
if Attr == "*" :
PriorityValue &= 0x11110
2015-12-01 04:22:16 +00:00
return self . PrioList [ "0x %0.5x " % PriorityValue ]
2010-11-15 02:51:34 +00:00
2010-02-28 23:39:39 +00:00
## Expand * in build option key
#
# @param Options Options to be expanded
#
# @retval options Options expanded
2010-11-15 02:51:34 +00:00
#
2010-02-28 23:39:39 +00:00
def _ExpandBuildOption ( self , Options , ModuleStyle = None ):
BuildOptions = {}
FamilyMatch = False
FamilyIsNull = True
2015-12-01 04:22:16 +00:00
2010-11-15 02:51:34 +00:00
OverrideList = {}
#
# Construct a list contain the build options which need override.
#
for Key in Options :
#
# Key[0] -- tool family
# Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
#
2015-06-19 01:43:45 +00:00
if ( Key [ 0 ] == self . BuildRuleFamily and
( ModuleStyle == None or len ( Key ) < 3 or ( len ( Key ) > 2 and Key [ 2 ] == ModuleStyle ))):
2010-11-15 02:51:34 +00:00
Target , ToolChain , Arch , CommandType , Attr = Key [ 1 ] . split ( '_' )
if Target == self . BuildTarget or Target == "*" :
if ToolChain == self . ToolChain or ToolChain == "*" :
if Arch == self . Arch or Arch == "*" :
if Options [ Key ] . startswith ( "=" ):
2015-12-01 04:22:16 +00:00
if OverrideList . get ( Key [ 1 ]) != None :
2010-11-15 02:51:34 +00:00
OverrideList . pop ( Key [ 1 ])
OverrideList [ Key [ 1 ]] = Options [ Key ]
#
# Use the highest priority value.
#
if ( len ( OverrideList ) >= 2 ):
2015-12-01 04:22:16 +00:00
KeyList = OverrideList . keys ()
2010-11-15 02:51:34 +00:00
for Index in range ( len ( KeyList )):
2015-12-01 04:22:16 +00:00
NowKey = KeyList [ Index ]
2010-11-15 02:51:34 +00:00
Target1 , ToolChain1 , Arch1 , CommandType1 , Attr1 = NowKey . split ( "_" )
for Index1 in range ( len ( KeyList ) - Index - 1 ):
NextKey = KeyList [ Index1 + Index + 1 ]
#
# Compare two Key, if one is included by another, choose the higher priority one
#
Target2 , ToolChain2 , Arch2 , CommandType2 , Attr2 = NextKey . split ( "_" )
if Target1 == Target2 or Target1 == "*" or Target2 == "*" :
if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*" :
if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*" :
if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*" :
if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*" :
if self . CalculatePriorityValue ( NowKey ) > self . CalculatePriorityValue ( NextKey ):
2015-12-01 04:22:16 +00:00
if Options . get (( self . BuildRuleFamily , NextKey )) != None :
2010-11-15 02:51:34 +00:00
Options . pop (( self . BuildRuleFamily , NextKey ))
else :
2015-12-01 04:22:16 +00:00
if Options . get (( self . BuildRuleFamily , NowKey )) != None :
2010-11-15 02:51:34 +00:00
Options . pop (( self . BuildRuleFamily , NowKey ))
2010-02-28 23:39:39 +00:00
for Key in Options :
if ModuleStyle != None and len ( Key ) > 2 :
# Check Module style is EDK or EDKII.
# Only append build option for the matched style module.
if ModuleStyle == EDK_NAME and Key [ 2 ] != EDK_NAME :
continue
elif ModuleStyle == EDKII_NAME and Key [ 2 ] != EDKII_NAME :
continue
Family = Key [ 0 ]
Target , Tag , Arch , Tool , Attr = Key [ 1 ] . split ( "_" )
# if tool chain family doesn't match, skip it
if Tool in self . ToolDefinition and Family != "" :
FamilyIsNull = False
if self . ToolDefinition [ Tool ] . get ( TAB_TOD_DEFINES_BUILDRULEFAMILY , "" ) != "" :
if Family != self . ToolDefinition [ Tool ][ TAB_TOD_DEFINES_BUILDRULEFAMILY ]:
continue
elif Family != self . ToolDefinition [ Tool ][ TAB_TOD_DEFINES_FAMILY ]:
continue
FamilyMatch = True
# expand any wildcard
if Target == "*" or Target == self . BuildTarget :
if Tag == "*" or Tag == self . ToolChain :
if Arch == "*" or Arch == self . Arch :
if Tool not in BuildOptions :
BuildOptions [ Tool ] = {}
2015-07-02 03:42:34 +00:00
if Attr != "FLAGS" or Attr not in BuildOptions [ Tool ] or Options [ Key ] . startswith ( '=' ):
2010-02-28 23:39:39 +00:00
BuildOptions [ Tool ][ Attr ] = Options [ Key ]
else :
# append options for the same tool
BuildOptions [ Tool ][ Attr ] += " " + Options [ Key ]
# Build Option Family has been checked, which need't to be checked again for family.
if FamilyMatch or FamilyIsNull :
return BuildOptions
2015-06-19 01:43:45 +00:00
2010-02-28 23:39:39 +00:00
for Key in Options :
if ModuleStyle != None and len ( Key ) > 2 :
# Check Module style is EDK or EDKII.
# Only append build option for the matched style module.
if ModuleStyle == EDK_NAME and Key [ 2 ] != EDK_NAME :
continue
elif ModuleStyle == EDKII_NAME and Key [ 2 ] != EDKII_NAME :
continue
Family = Key [ 0 ]
Target , Tag , Arch , Tool , Attr = Key [ 1 ] . split ( "_" )
# if tool chain family doesn't match, skip it
2015-12-01 04:22:16 +00:00
if Tool not in self . ToolDefinition or Family == "" :
2010-02-28 23:39:39 +00:00
continue
# option has been added before
if Family != self . ToolDefinition [ Tool ][ TAB_TOD_DEFINES_FAMILY ]:
continue
# expand any wildcard
if Target == "*" or Target == self . BuildTarget :
if Tag == "*" or Tag == self . ToolChain :
if Arch == "*" or Arch == self . Arch :
if Tool not in BuildOptions :
BuildOptions [ Tool ] = {}
2015-07-02 03:42:34 +00:00
if Attr != "FLAGS" or Attr not in BuildOptions [ Tool ] or Options [ Key ] . startswith ( '=' ):
2010-02-28 23:39:39 +00:00
BuildOptions [ Tool ][ Attr ] = Options [ Key ]
else :
# append options for the same tool
BuildOptions [ Tool ][ Attr ] += " " + Options [ Key ]
return BuildOptions
## Append build options in platform to a module
#
# @param Module The module to which the build options will be appened
#
# @retval options The options appended with build options in platform
#
def ApplyBuildOption ( self , Module ):
# Get the different options for the different style module
if Module . AutoGenVersion < 0x00010005 :
PlatformOptions = self . EdkBuildOption
2015-06-11 05:16:40 +00:00
ModuleTypeOptions = self . Platform . GetBuildOptionsByModuleType ( EDK_NAME , Module . ModuleType )
2010-02-28 23:39:39 +00:00
else :
PlatformOptions = self . EdkIIBuildOption
2015-06-11 05:16:40 +00:00
ModuleTypeOptions = self . Platform . GetBuildOptionsByModuleType ( EDKII_NAME , Module . ModuleType )
ModuleTypeOptions = self . _ExpandBuildOption ( ModuleTypeOptions )
2010-02-28 23:39:39 +00:00
ModuleOptions = self . _ExpandBuildOption ( Module . BuildOptions )
if Module in self . Platform . Modules :
PlatformModule = self . Platform . Modules [ str ( Module )]
PlatformModuleOptions = self . _ExpandBuildOption ( PlatformModule . BuildOptions )
else :
PlatformModuleOptions = {}
2015-05-26 10:32:07 +00:00
BuildRuleOrder = None
2015-06-11 05:16:40 +00:00
for Options in [ self . ToolDefinition , ModuleOptions , PlatformOptions , ModuleTypeOptions , PlatformModuleOptions ]:
2015-05-26 10:32:07 +00:00
for Tool in Options :
for Attr in Options [ Tool ]:
if Attr == TAB_TOD_DEFINES_BUILDRULEORDER :
BuildRuleOrder = Options [ Tool ][ Attr ]
2015-06-11 05:16:40 +00:00
AllTools = set ( ModuleOptions . keys () + PlatformOptions . keys () +
PlatformModuleOptions . keys () + ModuleTypeOptions . keys () +
self . ToolDefinition . keys ())
2010-02-28 23:39:39 +00:00
BuildOptions = {}
for Tool in AllTools :
if Tool not in BuildOptions :
BuildOptions [ Tool ] = {}
2015-06-11 05:16:40 +00:00
for Options in [ self . ToolDefinition , ModuleOptions , PlatformOptions , ModuleTypeOptions , PlatformModuleOptions ]:
2010-02-28 23:39:39 +00:00
if Tool not in Options :
continue
for Attr in Options [ Tool ]:
Value = Options [ Tool ][ Attr ]
2015-05-26 10:32:07 +00:00
#
# Do not generate it in Makefile
#
if Attr == TAB_TOD_DEFINES_BUILDRULEORDER :
continue
2010-02-28 23:39:39 +00:00
if Attr not in BuildOptions [ Tool ]:
BuildOptions [ Tool ][ Attr ] = ""
# check if override is indicated
if Value . startswith ( '=' ):
2015-10-08 09:27:14 +00:00
ToolPath = Value [ 1 :]
ToolPath = mws . handleWsMacro ( ToolPath )
BuildOptions [ Tool ][ Attr ] = ToolPath
2015-07-02 03:42:34 +00:00
else :
2015-10-08 09:27:14 +00:00
Value = mws . handleWsMacro ( Value )
2010-02-28 23:39:39 +00:00
BuildOptions [ Tool ][ Attr ] += " " + Value
2010-03-19 06:55:07 +00:00
if Module . AutoGenVersion < 0x00010005 and self . Workspace . UniFlag != None :
#
# Override UNI flag only for EDK module.
#
if 'BUILD' not in BuildOptions :
BuildOptions [ 'BUILD' ] = {}
BuildOptions [ 'BUILD' ][ 'FLAGS' ] = self . Workspace . UniFlag
2015-05-26 10:32:07 +00:00
return BuildOptions , BuildRuleOrder
2010-02-28 23:39:39 +00:00
Platform = property ( _GetPlatform )
Name = property ( _GetName )
Guid = property ( _GetGuid )
Version = property ( _GetVersion )
OutputDir = property ( _GetOutputDir )
BuildDir = property ( _GetBuildDir )
MakeFileDir = property ( _GetMakeFileDir )
FdfFile = property ( _GetFdfFile )
PcdTokenNumber = property ( _GetPcdTokenNumbers ) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
DynamicPcdList = property ( _GetDynamicPcdList ) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
NonDynamicPcdList = property ( _GetNonDynamicPcdList ) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
2014-01-10 05:25:50 +00:00
NonDynamicPcdDict = property ( _GetNonDynamicPcdDict )
2010-02-28 23:39:39 +00:00
PackageList = property ( _GetPackageList )
ToolDefinition = property ( _GetToolDefinition ) # toolcode : tool path
ToolDefinitionFile = property ( _GetToolDefFile ) # toolcode : lib path
ToolChainFamily = property ( _GetToolChainFamily )
BuildRuleFamily = property ( _GetBuildRuleFamily )
BuildOption = property ( _GetBuildOptions ) # toolcode : option
EdkBuildOption = property ( _GetEdkBuildOptions ) # edktoolcode : option
EdkIIBuildOption = property ( _GetEdkIIBuildOptions ) # edkiitoolcode : option
BuildCommand = property ( _GetBuildCommand )
BuildRule = property ( _GetBuildRule )
ModuleAutoGenList = property ( _GetModuleAutoGenList )
LibraryAutoGenList = property ( _GetLibraryAutoGenList )
2014-08-21 07:51:21 +00:00
GenFdsCommand = property ( _GenFdsCommand )
2010-02-28 23:39:39 +00:00
## ModuleAutoGen class
#
# This class encapsules the AutoGen behaviors for the build tools. In addition to
# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
# to the [depex] section in module's inf file.
#
class ModuleAutoGen ( AutoGen ):
## The real constructor of ModuleAutoGen
#
# This method is not supposed to be called by users of ModuleAutoGen. It's
# only used by factory method __new__() to do real initialization work for an
# object of ModuleAutoGen
#
# @param Workspace EdkIIWorkspaceBuild object
# @param ModuleFile The path of module file
# @param Target Build target (DEBUG, RELEASE)
# @param Toolchain Name of tool chain
# @param Arch The arch the module supports
# @param PlatformFile Platform meta-file
#
def _Init ( self , Workspace , ModuleFile , Target , Toolchain , Arch , PlatformFile ):
EdkLogger . debug ( EdkLogger . DEBUG_9 , "AutoGen module [ %s ] [ %s ]" % ( ModuleFile , Arch ))
GlobalData . gProcessingFile = " %s [ %s , %s , %s ]" % ( ModuleFile , Arch , Toolchain , Target )
self . Workspace = Workspace
self . WorkspaceDir = Workspace . WorkspaceDir
self . MetaFile = ModuleFile
self . PlatformInfo = PlatformAutoGen ( Workspace , PlatformFile , Target , Toolchain , Arch )
# check if this module is employed by active platform
if not self . PlatformInfo . ValidModule ( self . MetaFile ):
EdkLogger . verbose ( "Module [ %s ] for [ %s ] is not employed by active platform \n " \
% ( self . MetaFile , Arch ))
return False
self . SourceDir = self . MetaFile . SubDir
2015-10-08 09:27:14 +00:00
self . SourceDir = mws . relpath ( self . SourceDir , self . WorkspaceDir )
2014-08-28 13:53:34 +00:00
2010-02-28 23:39:39 +00:00
self . SourceOverrideDir = None
# use overrided path defined in DSC file
if self . MetaFile . Key in GlobalData . gOverrideDir :
self . SourceOverrideDir = GlobalData . gOverrideDir [ self . MetaFile . Key ]
self . ToolChain = Toolchain
self . BuildTarget = Target
self . Arch = Arch
self . ToolChainFamily = self . PlatformInfo . ToolChainFamily
self . BuildRuleFamily = self . PlatformInfo . BuildRuleFamily
self . IsMakeFileCreated = False
self . IsCodeFileCreated = False
2011-05-11 10:26:49 +00:00
self . IsAsBuiltInfCreated = False
self . DepexGenerated = False
2010-02-28 23:39:39 +00:00
self . BuildDatabase = self . Workspace . BuildDatabase
2015-05-26 10:32:07 +00:00
self . BuildRuleOrder = None
2010-02-28 23:39:39 +00:00
self . _Module = None
self . _Name = None
self . _Guid = None
self . _Version = None
self . _ModuleType = None
self . _ComponentType = None
self . _PcdIsDriver = None
self . _AutoGenVersion = None
self . _LibraryFlag = None
self . _CustomMakefile = None
self . _Macro = None
self . _BuildDir = None
self . _OutputDir = None
self . _DebugDir = None
self . _MakeFileDir = None
self . _IncludePathList = None
2016-03-16 11:06:44 +08:00
self . _IncludePathLength = 0
2010-02-28 23:39:39 +00:00
self . _AutoGenFileList = None
self . _UnicodeFileList = None
self . _SourceFileList = None
self . _ObjectFileList = None
self . _BinaryFileList = None
self . _DependentPackageList = None
self . _DependentLibraryList = None
self . _LibraryAutoGenList = None
self . _DerivedPackageList = None
self . _ModulePcdList = None
self . _LibraryPcdList = None
2013-11-18 07:41:21 +00:00
self . _PcdComments = sdict ()
2010-02-28 23:39:39 +00:00
self . _GuidList = None
2013-11-18 07:41:21 +00:00
self . _GuidsUsedByPcd = None
self . _GuidComments = sdict ()
2010-02-28 23:39:39 +00:00
self . _ProtocolList = None
2013-11-18 07:41:21 +00:00
self . _ProtocolComments = sdict ()
2010-02-28 23:39:39 +00:00
self . _PpiList = None
2013-11-18 07:41:21 +00:00
self . _PpiComments = sdict ()
2010-02-28 23:39:39 +00:00
self . _DepexList = None
self . _DepexExpressionList = None
self . _BuildOption = None
2011-10-11 02:49:48 +00:00
self . _BuildOptionIncPathList = None
2010-02-28 23:39:39 +00:00
self . _BuildTargets = None
self . _IntroBuildTargetList = None
self . _FinalBuildTargetList = None
self . _FileTypes = None
self . _BuildRules = None
2014-01-10 05:25:50 +00:00
## The Modules referenced to this Library
# Only Library has this attribute
self . _ReferenceModules = []
## Store the FixedAtBuild Pcds
#
self . _FixedAtBuildPcds = []
self . ConstPcd = {}
2010-02-28 23:39:39 +00:00
return True
def __repr__ ( self ):
return " %s [ %s ]" % ( self . MetaFile , self . Arch )
2014-01-10 05:25:50 +00:00
# Get FixedAtBuild Pcds of this Module
def _GetFixedAtBuildPcds ( self ):
if self . _FixedAtBuildPcds :
return self . _FixedAtBuildPcds
for Pcd in self . ModulePcdList :
if self . IsLibrary :
if not ( Pcd . Pending == False and Pcd . Type == "FixedAtBuild" ):
continue
elif Pcd . Type != "FixedAtBuild" :
continue
if Pcd not in self . _FixedAtBuildPcds :
self . _FixedAtBuildPcds . append ( Pcd )
return self . _FixedAtBuildPcds
2015-06-10 07:50:59 +00:00
def _GetUniqueBaseName ( self ):
BaseName = self . Name
for Module in self . PlatformInfo . ModuleAutoGenList :
if Module . MetaFile == self . MetaFile :
continue
if Module . Name == self . Name :
if uuid . UUID ( Module . Guid ) == uuid . UUID ( self . Guid ):
EdkLogger . error ( "build" , FILE_DUPLICATED , 'Modules have same BaseName and FILE_GUID: \n '
' %s \n %s ' % ( Module . MetaFile , self . MetaFile ))
BaseName = ' %s _ %s ' % ( self . Name , self . Guid )
return BaseName
2010-02-28 23:39:39 +00:00
# Macros could be used in build_rule.txt (also Makefile)
def _GetMacros ( self ):
if self . _Macro == None :
self . _Macro = sdict ()
self . _Macro [ "WORKSPACE" ] = self . WorkspaceDir
self . _Macro [ "MODULE_NAME" ] = self . Name
2015-06-10 07:50:59 +00:00
self . _Macro [ "MODULE_NAME_GUID" ] = self . _GetUniqueBaseName ()
2010-02-28 23:39:39 +00:00
self . _Macro [ "MODULE_GUID" ] = self . Guid
self . _Macro [ "MODULE_VERSION" ] = self . Version
self . _Macro [ "MODULE_TYPE" ] = self . ModuleType
self . _Macro [ "MODULE_FILE" ] = str ( self . MetaFile )
self . _Macro [ "MODULE_FILE_BASE_NAME" ] = self . MetaFile . BaseName
self . _Macro [ "MODULE_RELATIVE_DIR" ] = self . SourceDir
self . _Macro [ "MODULE_DIR" ] = self . SourceDir
self . _Macro [ "BASE_NAME" ] = self . Name
self . _Macro [ "ARCH" ] = self . Arch
self . _Macro [ "TOOLCHAIN" ] = self . ToolChain
self . _Macro [ "TOOLCHAIN_TAG" ] = self . ToolChain
2011-10-29 06:59:30 +00:00
self . _Macro [ "TOOL_CHAIN_TAG" ] = self . ToolChain
2010-02-28 23:39:39 +00:00
self . _Macro [ "TARGET" ] = self . BuildTarget
self . _Macro [ "BUILD_DIR" ] = self . PlatformInfo . BuildDir
self . _Macro [ "BIN_DIR" ] = os . path . join ( self . PlatformInfo . BuildDir , self . Arch )
self . _Macro [ "LIB_DIR" ] = os . path . join ( self . PlatformInfo . BuildDir , self . Arch )
self . _Macro [ "MODULE_BUILD_DIR" ] = self . BuildDir
self . _Macro [ "OUTPUT_DIR" ] = self . OutputDir
self . _Macro [ "DEBUG_DIR" ] = self . DebugDir
2016-03-11 18:58:44 +08:00
self . _Macro [ "DEST_DIR_OUTPUT" ] = self . OutputDir
self . _Macro [ "DEST_DIR_DEBUG" ] = self . DebugDir
2016-03-23 14:54:36 +08:00
self . _Macro [ "PLATFORM_NAME" ] = self . PlatformInfo . Name
self . _Macro [ "PLATFORM_GUID" ] = self . PlatformInfo . Guid
self . _Macro [ "PLATFORM_VERSION" ] = self . PlatformInfo . Version
self . _Macro [ "PLATFORM_RELATIVE_DIR" ] = self . PlatformInfo . SourceDir
self . _Macro [ "PLATFORM_DIR" ] = mws . join ( self . WorkspaceDir , self . PlatformInfo . SourceDir )
self . _Macro [ "PLATFORM_OUTPUT_DIR" ] = self . PlatformInfo . OutputDir
2010-02-28 23:39:39 +00:00
return self . _Macro
## Return the module build data object
def _GetModule ( self ):
if self . _Module == None :
2011-10-29 06:59:30 +00:00
self . _Module = self . Workspace . BuildDatabase [ self . MetaFile , self . Arch , self . BuildTarget , self . ToolChain ]
2010-02-28 23:39:39 +00:00
return self . _Module
## Return the module name
def _GetBaseName ( self ):
return self . Module . BaseName
2011-09-18 12:17:25 +00:00
## Return the module DxsFile if exist
def _GetDxsFile ( self ):
return self . Module . DxsFile
2010-02-28 23:39:39 +00:00
## Return the module SourceOverridePath
def _GetSourceOverridePath ( self ):
return self . Module . SourceOverridePath
## Return the module meta-file GUID
def _GetGuid ( self ):
2014-08-28 13:53:34 +00:00
#
# To build same module more than once, the module path with FILE_GUID overridden has
# the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path
# in DSC. The overridden GUID can be retrieved from file name
#
if os . path . basename ( self . MetaFile . File ) != os . path . basename ( self . MetaFile . Path ):
#
# Length of GUID is 36
#
return os . path . basename ( self . MetaFile . Path )[: 36 ]
2010-02-28 23:39:39 +00:00
return self . Module . Guid
## Return the module version
def _GetVersion ( self ):
return self . Module . Version
## Return the module type
def _GetModuleType ( self ):
return self . Module . ModuleType
2011-09-18 12:17:25 +00:00
## Return the component type (for Edk.x style of module)
2010-02-28 23:39:39 +00:00
def _GetComponentType ( self ):
return self . Module . ComponentType
## Return the build type
def _GetBuildType ( self ):
return self . Module . BuildType
## Return the PCD_IS_DRIVER setting
def _GetPcdIsDriver ( self ):
return self . Module . PcdIsDriver
## Return the autogen version, i.e. module meta-file version
def _GetAutoGenVersion ( self ):
return self . Module . AutoGenVersion
## Check if the module is library or not
def _IsLibrary ( self ):
if self . _LibraryFlag == None :
if self . Module . LibraryClass != None and self . Module . LibraryClass != []:
self . _LibraryFlag = True
else :
self . _LibraryFlag = False
return self . _LibraryFlag
2013-11-18 07:41:21 +00:00
## Check if the module is binary module or not
def _IsBinaryModule ( self ):
return self . Module . IsBinaryModule
2010-02-28 23:39:39 +00:00
## Return the directory to store intermediate files of the module
def _GetBuildDir ( self ):
if self . _BuildDir == None :
self . _BuildDir = path . join (
self . PlatformInfo . BuildDir ,
self . Arch ,
self . SourceDir ,
self . MetaFile . BaseName
)
CreateDirectory ( self . _BuildDir )
return self . _BuildDir
## Return the directory to store the intermediate object files of the mdoule
def _GetOutputDir ( self ):
if self . _OutputDir == None :
self . _OutputDir = path . join ( self . BuildDir , "OUTPUT" )
CreateDirectory ( self . _OutputDir )
return self . _OutputDir
## Return the directory to store auto-gened source files of the mdoule
def _GetDebugDir ( self ):
if self . _DebugDir == None :
self . _DebugDir = path . join ( self . BuildDir , "DEBUG" )
CreateDirectory ( self . _DebugDir )
return self . _DebugDir
## Return the path of custom file
def _GetCustomMakefile ( self ):
if self . _CustomMakefile == None :
self . _CustomMakefile = {}
for Type in self . Module . CustomMakefile :
if Type in gMakeTypeMap :
MakeType = gMakeTypeMap [ Type ]
else :
MakeType = 'nmake'
if self . SourceOverrideDir != None :
File = os . path . join ( self . SourceOverrideDir , self . Module . CustomMakefile [ Type ])
if not os . path . exists ( File ):
File = os . path . join ( self . SourceDir , self . Module . CustomMakefile [ Type ])
else :
File = os . path . join ( self . SourceDir , self . Module . CustomMakefile [ Type ])
self . _CustomMakefile [ MakeType ] = File
return self . _CustomMakefile
## Return the directory of the makefile
#
# @retval string The directory string of module's makefile
#
def _GetMakeFileDir ( self ):
return self . BuildDir
## Return build command string
#
# @retval string Build command string
#
def _GetBuildCommand ( self ):
return self . PlatformInfo . BuildCommand
## Get object list of all packages the module and its dependent libraries belong to
#
# @retval list The list of package object
#
def _GetDerivedPackageList ( self ):
PackageList = []
for M in [ self . Module ] + self . DependentLibraryList :
for Package in M . Packages :
if Package in PackageList :
continue
PackageList . append ( Package )
return PackageList
2014-08-28 13:53:34 +00:00
## Get the depex string
#
# @return : a string contain all depex expresion.
def _GetDepexExpresionString ( self ):
DepexStr = ''
DepexList = []
## DPX_SOURCE IN Define section.
if self . Module . DxsFile :
return DepexStr
for M in [ self . Module ] + self . DependentLibraryList :
Filename = M . MetaFile . Path
InfObj = InfSectionParser . InfSectionParser ( Filename )
DepexExpresionList = InfObj . GetDepexExpresionList ()
for DepexExpresion in DepexExpresionList :
for key in DepexExpresion . keys ():
Arch , ModuleType = key
# the type of build module is USER_DEFINED.
# All different DEPEX section tags would be copied into the As Built INF file
# and there would be separate DEPEX section tags
if self . ModuleType . upper () == SUP_MODULE_USER_DEFINED :
if ( Arch . upper () == self . Arch . upper ()) and ( ModuleType . upper () != TAB_ARCH_COMMON ):
DepexList . append ({( Arch , ModuleType ): DepexExpresion [ key ][:]})
else :
if Arch . upper () == TAB_ARCH_COMMON or \
( Arch . upper () == self . Arch . upper () and \
ModuleType . upper () in [ TAB_ARCH_COMMON , self . ModuleType . upper ()]):
DepexList . append ({( Arch , ModuleType ): DepexExpresion [ key ][:]})
#the type of build module is USER_DEFINED.
if self . ModuleType . upper () == SUP_MODULE_USER_DEFINED :
for Depex in DepexList :
for key in Depex . keys ():
DepexStr += '[Depex. %s . %s ] \n ' % key
DepexStr += ' \n ' . join ([ '# ' + val for val in Depex [ key ]])
DepexStr += ' \n\n '
if not DepexStr :
return '[Depex. %s ] \n ' % self . Arch
return DepexStr
#the type of build module not is USER_DEFINED.
Count = 0
for Depex in DepexList :
Count += 1
if DepexStr != '' :
DepexStr += ' AND '
DepexStr += '('
for D in Depex . values ():
DepexStr += ' ' . join ([ val for val in D ])
Index = DepexStr . find ( 'END' )
if Index > - 1 and Index == len ( DepexStr ) - 3 :
DepexStr = DepexStr [: - 3 ]
DepexStr = DepexStr . strip ()
DepexStr += ')'
if Count == 1 :
DepexStr = DepexStr . lstrip ( '(' ) . rstrip ( ')' ) . strip ()
if not DepexStr :
return '[Depex. %s ] \n ' % self . Arch
return '[Depex. %s ] \n # ' % self . Arch + DepexStr
2010-02-28 23:39:39 +00:00
## Merge dependency expression
#
# @retval list The token list of the dependency expression after parsed
#
def _GetDepexTokenList ( self ):
if self . _DepexList == None :
self . _DepexList = {}
2011-09-18 12:17:25 +00:00
if self . DxsFile or self . IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self . FileTypes :
2010-02-28 23:39:39 +00:00
return self . _DepexList
self . _DepexList [ self . ModuleType ] = []
for ModuleType in self . _DepexList :
DepexList = self . _DepexList [ ModuleType ]
#
# Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
#
for M in [ self . Module ] + self . DependentLibraryList :
Inherited = False
for D in M . Depex [ self . Arch , ModuleType ]:
if DepexList != []:
DepexList . append ( 'AND' )
DepexList . append ( '(' )
DepexList . extend ( D )
if DepexList [ - 1 ] == 'END' : # no need of a END at this time
DepexList . pop ()
DepexList . append ( ')' )
Inherited = True
if Inherited :
EdkLogger . verbose ( "DEPEX[ %s ] (+ %s ) = %s " % ( self . Name , M . BaseName , DepexList ))
if 'BEFORE' in DepexList or 'AFTER' in DepexList :
break
if len ( DepexList ) > 0 :
EdkLogger . verbose ( '' )
return self . _DepexList
## Merge dependency expression
#
# @retval list The token list of the dependency expression after parsed
#
def _GetDepexExpressionTokenList ( self ):
if self . _DepexExpressionList == None :
self . _DepexExpressionList = {}
2011-09-18 12:17:25 +00:00
if self . DxsFile or self . IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self . FileTypes :
2010-02-28 23:39:39 +00:00
return self . _DepexExpressionList
self . _DepexExpressionList [ self . ModuleType ] = ''
for ModuleType in self . _DepexExpressionList :
DepexExpressionList = self . _DepexExpressionList [ ModuleType ]
#
# Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
#
for M in [ self . Module ] + self . DependentLibraryList :
Inherited = False
for D in M . DepexExpression [ self . Arch , ModuleType ]:
if DepexExpressionList != '' :
DepexExpressionList += ' AND '
DepexExpressionList += '('
DepexExpressionList += D
DepexExpressionList = DepexExpressionList . rstrip ( 'END' ) . strip ()
DepexExpressionList += ')'
Inherited = True
if Inherited :
EdkLogger . verbose ( "DEPEX[ %s ] (+ %s ) = %s " % ( self . Name , M . BaseName , DepexExpressionList ))
if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList :
break
if len ( DepexExpressionList ) > 0 :
EdkLogger . verbose ( '' )
self . _DepexExpressionList [ ModuleType ] = DepexExpressionList
return self . _DepexExpressionList
## Return the list of specification version required for the module
#
# @retval list The list of specification defined in module file
#
def _GetSpecification ( self ):
return self . Module . Specification
## Tool option for the module build
#
# @param PlatformInfo The object of PlatformBuildInfo
# @retval dict The dict containing valid options
#
def _GetModuleBuildOption ( self ):
if self . _BuildOption == None :
2015-05-26 10:32:07 +00:00
self . _BuildOption , self . BuildRuleOrder = self . PlatformInfo . ApplyBuildOption ( self . Module )
if self . BuildRuleOrder :
self . BuildRuleOrder = [ '. %s ' % Ext for Ext in self . BuildRuleOrder . split ()]
2010-02-28 23:39:39 +00:00
return self . _BuildOption
2011-10-11 02:49:48 +00:00
## Get include path list from tool option for the module build
#
# @retval list The include path list
#
def _GetBuildOptionIncPathList ( self ):
if self . _BuildOptionIncPathList == None :
#
2011-11-09 04:32:08 +00:00
# Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT
2011-10-11 02:49:48 +00:00
# is the former use /I , the Latter used -I to specify include directories
#
if self . PlatformInfo . ToolChainFamily in ( 'MSFT' ):
2015-12-01 04:22:16 +00:00
gBuildOptIncludePattern = re . compile ( r "(?:.*?)/I[ \t]*([^ ]*)" , re . MULTILINE | re . DOTALL )
2011-11-09 04:32:08 +00:00
elif self . PlatformInfo . ToolChainFamily in ( 'INTEL' , 'GCC' , 'RVCT' ):
2015-12-01 04:22:16 +00:00
gBuildOptIncludePattern = re . compile ( r "(?:.*?)-I[ \t]*([^ ]*)" , re . MULTILINE | re . DOTALL )
2011-11-09 04:32:08 +00:00
else :
#
# New ToolChainFamily, don't known whether there is option to specify include directories
#
self . _BuildOptionIncPathList = []
return self . _BuildOptionIncPathList
2011-10-11 02:49:48 +00:00
BuildOptionIncPathList = []
for Tool in ( 'CC' , 'PP' , 'VFRPP' , 'ASLPP' , 'ASLCC' , 'APP' , 'ASM' ):
Attr = 'FLAGS'
try :
FlagOption = self . BuildOption [ Tool ][ Attr ]
except KeyError :
FlagOption = ''
2011-11-09 04:32:08 +00:00
if self . PlatformInfo . ToolChainFamily != 'RVCT' :
IncPathList = [ NormPath ( Path , self . Macros ) for Path in gBuildOptIncludePattern . findall ( FlagOption )]
else :
#
# RVCT may specify a list of directory seperated by commas
#
IncPathList = []
for Path in gBuildOptIncludePattern . findall ( FlagOption ):
PathList = GetSplitList ( Path , TAB_COMMA_SPLIT )
IncPathList += [ NormPath ( PathEntry , self . Macros ) for PathEntry in PathList ]
2011-10-11 02:49:48 +00:00
#
# EDK II modules must not reference header files outside of the packages they depend on or
# within the module's directory tree. Report error if violation.
#
if self . AutoGenVersion >= 0x00010005 and len ( IncPathList ) > 0 :
for Path in IncPathList :
if ( Path not in self . IncludePathList ) and ( CommonPath ([ Path , self . MetaFile . Dir ]) != self . MetaFile . Dir ):
2015-12-01 04:22:16 +00:00
ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS ' %s '" % ( Path , Tool , FlagOption )
EdkLogger . error ( "build" ,
2011-10-11 02:49:48 +00:00
PARAMETER_INVALID ,
2015-12-01 04:22:16 +00:00
ExtraData = ErrMsg ,
File = str ( self . MetaFile ))
2011-10-11 02:49:48 +00:00
BuildOptionIncPathList += IncPathList
self . _BuildOptionIncPathList = BuildOptionIncPathList
return self . _BuildOptionIncPathList
2010-02-28 23:39:39 +00:00
## Return a list of files which can be built from source
#
# What kind of files can be built is determined by build rules in
2014-08-28 13:53:34 +00:00
# $(CONF_DIRECTORY)/build_rule.txt and toolchain family.
2010-02-28 23:39:39 +00:00
#
def _GetSourceFileList ( self ):
if self . _SourceFileList == None :
self . _SourceFileList = []
for F in self . Module . Sources :
# match tool chain
2010-10-11 06:26:52 +00:00
if F . TagName not in ( "" , "*" , self . ToolChain ):
2010-02-28 23:39:39 +00:00
EdkLogger . debug ( EdkLogger . DEBUG_9 , "The toolchain [ %s ] for processing file [ %s ] is found, "
"but [ %s ] is needed" % ( F . TagName , str ( F ), self . ToolChain ))
continue
# match tool chain family
2010-10-11 06:26:52 +00:00
if F . ToolChainFamily not in ( "" , "*" , self . ToolChainFamily ):
2010-02-28 23:39:39 +00:00
EdkLogger . debug (
EdkLogger . DEBUG_0 ,
"The file [ %s ] must be built by tools of [ %s ], " \
"but current toolchain family is [ %s ]" \
% ( str ( F ), F . ToolChainFamily , self . ToolChainFamily ))
continue
# add the file path into search path list for file including
if F . Dir not in self . IncludePathList and self . AutoGenVersion >= 0x00010005 :
self . IncludePathList . insert ( 0 , F . Dir )
self . _SourceFileList . append ( F )
2016-01-19 12:58:52 +00:00
self . _MatchBuildRuleOrder ( self . _SourceFileList )
for F in self . _SourceFileList :
2010-02-28 23:39:39 +00:00
self . _ApplyBuildRule ( F , TAB_UNKNOWN_FILE )
return self . _SourceFileList
2016-01-19 12:58:52 +00:00
def _MatchBuildRuleOrder ( self , FileList ):
Order_Dict = {}
self . _GetModuleBuildOption ()
for SingleFile in FileList :
if self . BuildRuleOrder and SingleFile . Ext in self . BuildRuleOrder and SingleFile . Ext in self . BuildRules :
key = SingleFile . Path . split ( SingleFile . Ext )[ 0 ]
if key in Order_Dict :
Order_Dict [ key ] . append ( SingleFile . Ext )
else :
Order_Dict [ key ] = [ SingleFile . Ext ]
RemoveList = []
for F in Order_Dict :
if len ( Order_Dict [ F ]) > 1 :
Order_Dict [ F ] . sort ( key = lambda i : self . BuildRuleOrder . index ( i ))
for Ext in Order_Dict [ F ][ 1 :]:
RemoveList . append ( F + Ext )
for item in RemoveList :
FileList . remove ( item )
return FileList
2010-02-28 23:39:39 +00:00
## Return the list of unicode files
def _GetUnicodeFileList ( self ):
if self . _UnicodeFileList == None :
if TAB_UNICODE_FILE in self . FileTypes :
self . _UnicodeFileList = self . FileTypes [ TAB_UNICODE_FILE ]
else :
self . _UnicodeFileList = []
return self . _UnicodeFileList
## Return a list of files which can be built from binary
#
# "Build" binary files are just to copy them to build directory.
#
# @retval list The list of files which can be built later
#
def _GetBinaryFiles ( self ):
if self . _BinaryFileList == None :
self . _BinaryFileList = []
for F in self . Module . Binaries :
if F . Target not in [ 'COMMON' , '*' ] and F . Target != self . BuildTarget :
continue
self . _BinaryFileList . append ( F )
self . _ApplyBuildRule ( F , F . Type )
return self . _BinaryFileList
def _GetBuildRules ( self ):
if self . _BuildRules == None :
BuildRules = {}
BuildRuleDatabase = self . PlatformInfo . BuildRule
for Type in BuildRuleDatabase . FileTypeList :
#first try getting build rule by BuildRuleFamily
RuleObject = BuildRuleDatabase [ Type , self . BuildType , self . Arch , self . BuildRuleFamily ]
if not RuleObject :
# build type is always module type, but ...
if self . ModuleType != self . BuildType :
RuleObject = BuildRuleDatabase [ Type , self . ModuleType , self . Arch , self . BuildRuleFamily ]
#second try getting build rule by ToolChainFamily
if not RuleObject :
RuleObject = BuildRuleDatabase [ Type , self . BuildType , self . Arch , self . ToolChainFamily ]
if not RuleObject :
# build type is always module type, but ...
if self . ModuleType != self . BuildType :
RuleObject = BuildRuleDatabase [ Type , self . ModuleType , self . Arch , self . ToolChainFamily ]
if not RuleObject :
continue
RuleObject = RuleObject . Instantiate ( self . Macros )
BuildRules [ Type ] = RuleObject
for Ext in RuleObject . SourceFileExtList :
BuildRules [ Ext ] = RuleObject
self . _BuildRules = BuildRules
return self . _BuildRules
def _ApplyBuildRule ( self , File , FileType ):
if self . _BuildTargets == None :
self . _IntroBuildTargetList = set ()
self . _FinalBuildTargetList = set ()
self . _BuildTargets = {}
self . _FileTypes = {}
2014-08-21 01:39:18 +00:00
SubDirectory = os . path . join ( self . OutputDir , File . SubDir )
if not os . path . exists ( SubDirectory ):
CreateDirectory ( SubDirectory )
2010-02-28 23:39:39 +00:00
LastTarget = None
RuleChain = []
SourceList = [ File ]
Index = 0
2015-05-26 10:32:07 +00:00
#
# Make sure to get build rule order value
#
self . _GetModuleBuildOption ()
2010-02-28 23:39:39 +00:00
while Index < len ( SourceList ):
Source = SourceList [ Index ]
Index = Index + 1
if Source != File :
CreateDirectory ( Source . Dir )
if File . IsBinary and File == Source and self . _BinaryFileList != None and File in self . _BinaryFileList :
2011-05-11 10:26:49 +00:00
# Skip all files that are not binary libraries
if not self . IsLibrary :
2015-12-01 04:22:16 +00:00
continue
2010-02-28 23:39:39 +00:00
RuleObject = self . BuildRules [ TAB_DEFAULT_BINARY_FILE ]
elif FileType in self . BuildRules :
RuleObject = self . BuildRules [ FileType ]
elif Source . Ext in self . BuildRules :
RuleObject = self . BuildRules [ Source . Ext ]
else :
# stop at no more rules
if LastTarget :
self . _FinalBuildTargetList . add ( LastTarget )
break
FileType = RuleObject . SourceFileType
if FileType not in self . _FileTypes :
self . _FileTypes [ FileType ] = set ()
self . _FileTypes [ FileType ] . add ( Source )
# stop at STATIC_LIBRARY for library
if self . IsLibrary and FileType == TAB_STATIC_LIBRARY :
if LastTarget :
self . _FinalBuildTargetList . add ( LastTarget )
break
2015-05-26 10:32:07 +00:00
Target = RuleObject . Apply ( Source , self . BuildRuleOrder )
2010-02-28 23:39:39 +00:00
if not Target :
if LastTarget :
self . _FinalBuildTargetList . add ( LastTarget )
break
elif not Target . Outputs :
# Only do build for target with outputs
self . _FinalBuildTargetList . add ( Target )
if FileType not in self . _BuildTargets :
self . _BuildTargets [ FileType ] = set ()
self . _BuildTargets [ FileType ] . add ( Target )
if not Source . IsBinary and Source == File :
self . _IntroBuildTargetList . add ( Target )
# to avoid cyclic rule
if FileType in RuleChain :
break
RuleChain . append ( FileType )
SourceList . extend ( Target . Outputs )
LastTarget = Target
FileType = TAB_UNKNOWN_FILE
def _GetTargets ( self ):
if self . _BuildTargets == None :
self . _IntroBuildTargetList = set ()
self . _FinalBuildTargetList = set ()
self . _BuildTargets = {}
self . _FileTypes = {}
2011-09-18 12:17:25 +00:00
#TRICK: call _GetSourceFileList to apply build rule for source files
2010-02-28 23:39:39 +00:00
if self . SourceFileList :
pass
#TRICK: call _GetBinaryFileList to apply build rule for binary files
if self . BinaryFileList :
pass
return self . _BuildTargets
def _GetIntroTargetList ( self ):
self . _GetTargets ()
return self . _IntroBuildTargetList
def _GetFinalTargetList ( self ):
self . _GetTargets ()
return self . _FinalBuildTargetList
def _GetFileTypes ( self ):
self . _GetTargets ()
return self . _FileTypes
## Get the list of package object the module depends on
#
# @retval list The package object list
#
def _GetDependentPackageList ( self ):
return self . Module . Packages
## Return the list of auto-generated code file
#
# @retval list The list of auto-generated file
#
def _GetAutoGenFileList ( self ):
UniStringAutoGenC = True
2011-08-26 07:46:26 +00:00
UniStringBinBuffer = StringIO ()
2010-02-28 23:39:39 +00:00
if self . BuildType == 'UEFI_HII' :
UniStringAutoGenC = False
if self . _AutoGenFileList == None :
self . _AutoGenFileList = {}
AutoGenC = TemplateString ()
AutoGenH = TemplateString ()
StringH = TemplateString ()
GenC . CreateCode ( self , AutoGenC , AutoGenH , StringH , UniStringAutoGenC , UniStringBinBuffer )
2014-08-21 07:12:33 +00:00
#
# AutoGen.c is generated if there are library classes in inf, or there are object files
#
if str ( AutoGenC ) != "" and ( len ( self . Module . LibraryClasses ) > 0
or TAB_OBJECT_FILE in self . FileTypes ):
2010-02-28 23:39:39 +00:00
AutoFile = PathClass ( gAutoGenCodeFileName , self . DebugDir )
self . _AutoGenFileList [ AutoFile ] = str ( AutoGenC )
self . _ApplyBuildRule ( AutoFile , TAB_UNKNOWN_FILE )
if str ( AutoGenH ) != "" :
AutoFile = PathClass ( gAutoGenHeaderFileName , self . DebugDir )
self . _AutoGenFileList [ AutoFile ] = str ( AutoGenH )
self . _ApplyBuildRule ( AutoFile , TAB_UNKNOWN_FILE )
if str ( StringH ) != "" :
AutoFile = PathClass ( gAutoGenStringFileName % { "module_name" : self . Name }, self . DebugDir )
self . _AutoGenFileList [ AutoFile ] = str ( StringH )
self . _ApplyBuildRule ( AutoFile , TAB_UNKNOWN_FILE )
if UniStringBinBuffer != None and UniStringBinBuffer . getvalue () != "" :
AutoFile = PathClass ( gAutoGenStringFormFileName % { "module_name" : self . Name }, self . OutputDir )
self . _AutoGenFileList [ AutoFile ] = UniStringBinBuffer . getvalue ()
AutoFile . IsBinary = True
self . _ApplyBuildRule ( AutoFile , TAB_UNKNOWN_FILE )
if UniStringBinBuffer != None :
UniStringBinBuffer . close ()
return self . _AutoGenFileList
## Return the list of library modules explicitly or implicityly used by this module
def _GetLibraryList ( self ):
if self . _DependentLibraryList == None :
# only merge library classes and PCD for non-library module
if self . IsLibrary :
self . _DependentLibraryList = []
else :
if self . AutoGenVersion < 0x00010005 :
self . _DependentLibraryList = self . PlatformInfo . ResolveLibraryReference ( self . Module )
else :
self . _DependentLibraryList = self . PlatformInfo . ApplyLibraryInstance ( self . Module )
return self . _DependentLibraryList
2013-11-18 07:41:21 +00:00
@staticmethod
def UpdateComments ( Recver , Src ):
for Key in Src :
if Key not in Recver :
Recver [ Key ] = []
Recver [ Key ] . extend ( Src [ Key ])
2010-02-28 23:39:39 +00:00
## Get the list of PCDs from current module
#
# @retval list The list of PCD
#
def _GetModulePcdList ( self ):
if self . _ModulePcdList == None :
# apply PCD settings from platform
self . _ModulePcdList = self . PlatformInfo . ApplyPcdSetting ( self . Module , self . Module . Pcds )
2013-11-18 07:41:21 +00:00
self . UpdateComments ( self . _PcdComments , self . Module . PcdComments )
2010-02-28 23:39:39 +00:00
return self . _ModulePcdList
## Get the list of PCDs from dependent libraries
#
# @retval list The list of PCD
#
def _GetLibraryPcdList ( self ):
if self . _LibraryPcdList == None :
2011-10-11 02:49:48 +00:00
Pcds = sdict ()
2010-02-28 23:39:39 +00:00
if not self . IsLibrary :
# get PCDs from dependent libraries
for Library in self . DependentLibraryList :
2013-11-18 07:41:21 +00:00
self . UpdateComments ( self . _PcdComments , Library . PcdComments )
2010-02-28 23:39:39 +00:00
for Key in Library . Pcds :
# skip duplicated PCDs
if Key in self . Module . Pcds or Key in Pcds :
continue
Pcds [ Key ] = copy . copy ( Library . Pcds [ Key ])
# apply PCD settings from platform
self . _LibraryPcdList = self . PlatformInfo . ApplyPcdSetting ( self . Module , Pcds )
else :
self . _LibraryPcdList = []
return self . _LibraryPcdList
## Get the GUID value mapping
#
# @retval dict The mapping between GUID cname and its value
#
def _GetGuidList ( self ):
if self . _GuidList == None :
2014-11-11 07:33:50 +00:00
self . _GuidList = sdict ()
self . _GuidList . update ( self . Module . Guids )
2010-02-28 23:39:39 +00:00
for Library in self . DependentLibraryList :
self . _GuidList . update ( Library . Guids )
2013-11-18 07:41:21 +00:00
self . UpdateComments ( self . _GuidComments , Library . GuidComments )
self . UpdateComments ( self . _GuidComments , self . Module . GuidComments )
2010-02-28 23:39:39 +00:00
return self . _GuidList
2013-11-18 07:41:21 +00:00
def GetGuidsUsedByPcd ( self ):
if self . _GuidsUsedByPcd == None :
self . _GuidsUsedByPcd = sdict ()
self . _GuidsUsedByPcd . update ( self . Module . GetGuidsUsedByPcd ())
for Library in self . DependentLibraryList :
self . _GuidsUsedByPcd . update ( Library . GetGuidsUsedByPcd ())
return self . _GuidsUsedByPcd
2010-02-28 23:39:39 +00:00
## Get the protocol value mapping
#
# @retval dict The mapping between protocol cname and its value
#
def _GetProtocolList ( self ):
if self . _ProtocolList == None :
2014-11-11 07:33:50 +00:00
self . _ProtocolList = sdict ()
self . _ProtocolList . update ( self . Module . Protocols )
2010-02-28 23:39:39 +00:00
for Library in self . DependentLibraryList :
self . _ProtocolList . update ( Library . Protocols )
2013-11-18 07:41:21 +00:00
self . UpdateComments ( self . _ProtocolComments , Library . ProtocolComments )
self . UpdateComments ( self . _ProtocolComments , self . Module . ProtocolComments )
2010-02-28 23:39:39 +00:00
return self . _ProtocolList
## Get the PPI value mapping
#
# @retval dict The mapping between PPI cname and its value
#
def _GetPpiList ( self ):
if self . _PpiList == None :
2014-11-11 07:33:50 +00:00
self . _PpiList = sdict ()
self . _PpiList . update ( self . Module . Ppis )
2010-02-28 23:39:39 +00:00
for Library in self . DependentLibraryList :
self . _PpiList . update ( Library . Ppis )
2013-11-18 07:41:21 +00:00
self . UpdateComments ( self . _PpiComments , Library . PpiComments )
self . UpdateComments ( self . _PpiComments , self . Module . PpiComments )
2010-02-28 23:39:39 +00:00
return self . _PpiList
## Get the list of include search path
#
# @retval list The list path
#
def _GetIncludePathList ( self ):
if self . _IncludePathList == None :
self . _IncludePathList = []
if self . AutoGenVersion < 0x00010005 :
for Inc in self . Module . Includes :
if Inc not in self . _IncludePathList :
self . _IncludePathList . append ( Inc )
2011-09-18 12:17:25 +00:00
# for Edk modules
2010-02-28 23:39:39 +00:00
Inc = path . join ( Inc , self . Arch . capitalize ())
if os . path . exists ( Inc ) and Inc not in self . _IncludePathList :
self . _IncludePathList . append ( Inc )
2011-09-18 12:17:25 +00:00
# Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
2010-02-28 23:39:39 +00:00
self . _IncludePathList . append ( self . DebugDir )
else :
self . _IncludePathList . append ( self . MetaFile . Dir )
self . _IncludePathList . append ( self . DebugDir )
for Package in self . Module . Packages :
2015-10-08 09:27:14 +00:00
PackageDir = mws . join ( self . WorkspaceDir , Package . MetaFile . Dir )
2010-02-28 23:39:39 +00:00
if PackageDir not in self . _IncludePathList :
self . _IncludePathList . append ( PackageDir )
for Inc in Package . Includes :
if Inc not in self . _IncludePathList :
self . _IncludePathList . append ( str ( Inc ))
return self . _IncludePathList
2016-03-16 11:06:44 +08:00
def _GetIncludePathLength ( self ):
self . _IncludePathLength = 0
if self . _IncludePathList :
for inc in self . _IncludePathList :
self . _IncludePathLength += len ( ' ' + inc )
return self . _IncludePathLength
2014-08-28 13:53:34 +00:00
## Get HII EX PCDs which maybe used by VFR
#
# efivarstore used by VFR may relate with HII EX PCDs
# Get the variable name and GUID from efivarstore and HII EX PCD
# List the HII EX PCDs in As Built INF if both name and GUID match.
#
# @retval list HII EX PCDs
#
def _GetPcdsMaybeUsedByVfr ( self ):
if not self . SourceFileList :
return []
NameGuids = []
for SrcFile in self . SourceFileList :
if SrcFile . Ext . lower () != '.vfr' :
continue
Vfri = os . path . join ( self . OutputDir , SrcFile . BaseName + '.i' )
if not os . path . exists ( Vfri ):
continue
VfriFile = open ( Vfri , 'r' )
Content = VfriFile . read ()
VfriFile . close ()
Pos = Content . find ( 'efivarstore' )
while Pos != - 1 :
#
# Make sure 'efivarstore' is the start of efivarstore statement
# In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'
#
Index = Pos - 1
while Index >= 0 and Content [ Index ] in ' \t\r\n ' :
Index -= 1
if Index >= 0 and Content [ Index ] != ';' :
Pos = Content . find ( 'efivarstore' , Pos + len ( 'efivarstore' ))
continue
#
# 'efivarstore' must be followed by name and guid
#
Name = gEfiVarStoreNamePattern . search ( Content , Pos )
if not Name :
break
Guid = gEfiVarStoreGuidPattern . search ( Content , Pos )
if not Guid :
break
NameArray = ConvertStringToByteArray ( 'L"' + Name . group ( 1 ) + '"' )
NameGuids . append (( NameArray , GuidStructureStringToGuidString ( Guid . group ( 1 ))))
Pos = Content . find ( 'efivarstore' , Name . end ())
if not NameGuids :
return []
HiiExPcds = []
for Pcd in self . PlatformInfo . Platform . Pcds . values ():
if Pcd . Type != TAB_PCDS_DYNAMIC_EX_HII :
continue
for SkuName in Pcd . SkuInfoList :
SkuInfo = Pcd . SkuInfoList [ SkuName ]
Name = ConvertStringToByteArray ( SkuInfo . VariableName )
Value = GuidValue ( SkuInfo . VariableGuid , self . PlatformInfo . PackageList )
if not Value :
continue
Guid = GuidStructureStringToGuidString ( Value )
if ( Name , Guid ) in NameGuids and Pcd not in HiiExPcds :
HiiExPcds . append ( Pcd )
break
return HiiExPcds
2015-06-11 05:20:00 +00:00
def _GenOffsetBin ( self ):
VfrUniBaseName = {}
for SourceFile in self . Module . Sources :
if SourceFile . Type . upper () == ".VFR" :
#
# search the .map file to find the offset of vfr binary in the PE32+/TE file.
#
VfrUniBaseName [ SourceFile . BaseName ] = ( SourceFile . BaseName + "Bin" )
if SourceFile . Type . upper () == ".UNI" :
#
# search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
#
VfrUniBaseName [ "UniOffsetName" ] = ( self . Name + "Strings" )
if len ( VfrUniBaseName ) == 0 :
return None
MapFileName = os . path . join ( self . OutputDir , self . Name + ".map" )
EfiFileName = os . path . join ( self . OutputDir , self . Name + ".efi" )
VfrUniOffsetList = GetVariableOffset ( MapFileName , EfiFileName , VfrUniBaseName . values ())
if not VfrUniOffsetList :
return None
OutputName = ' %s Offset.bin' % self . Name
UniVfrOffsetFileName = os . path . join ( self . OutputDir , OutputName )
try :
fInputfile = open ( UniVfrOffsetFileName , "wb+" , 0 )
except :
EdkLogger . error ( "build" , FILE_OPEN_FAILURE , "File open failed for %s " % UniVfrOffsetFileName , None )
# Use a instance of StringIO to cache data
fStringIO = StringIO ( '' )
for Item in VfrUniOffsetList :
if ( Item [ 0 ] . find ( "Strings" ) != - 1 ):
#
# UNI offset in image.
# GUID + Offset
# { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
#
UniGuid = [ 0xe0 , 0xc5 , 0x13 , 0x89 , 0xf6 , 0x33 , 0x86 , 0x4d , 0x9b , 0xf1 , 0x43 , 0xef , 0x89 , 0xfc , 0x6 , 0x66 ]
UniGuid = [ chr ( ItemGuid ) for ItemGuid in UniGuid ]
fStringIO . write ( '' . join ( UniGuid ))
UniValue = pack ( 'Q' , int ( Item [ 1 ], 16 ))
fStringIO . write ( UniValue )
else :
#
# VFR binary offset in image.
# GUID + Offset
# { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
#
VfrGuid = [ 0xb4 , 0x7c , 0xbc , 0xd0 , 0x47 , 0x6a , 0x5f , 0x49 , 0xaa , 0x11 , 0x71 , 0x7 , 0x46 , 0xda , 0x6 , 0xa2 ]
VfrGuid = [ chr ( ItemGuid ) for ItemGuid in VfrGuid ]
fStringIO . write ( '' . join ( VfrGuid ))
type ( Item [ 1 ])
VfrValue = pack ( 'Q' , int ( Item [ 1 ], 16 ))
fStringIO . write ( VfrValue )
#
# write data into file.
#
try :
fInputfile . write ( fStringIO . getvalue ())
except :
EdkLogger . error ( "build" , FILE_WRITE_FAILURE , "Write data to file %s failed, please check whether the "
"file been locked or using by other applications." % UniVfrOffsetFileName , None )
fStringIO . close ()
fInputfile . close ()
return OutputName
2011-05-11 10:26:49 +00:00
## Create AsBuilt INF file the module
#
def CreateAsBuiltInf ( self ):
if self . IsAsBuiltInfCreated :
return
# Skip the following code for EDK I inf
if self . AutoGenVersion < 0x00010005 :
return
# Skip the following code for libraries
if self . IsLibrary :
return
# Skip the following code for modules with no source files
if self . SourceFileList == None or self . SourceFileList == []:
return
# Skip the following code for modules without any binary files
if self . BinaryFileList <> None and self . BinaryFileList <> []:
return
### TODO: How to handles mixed source and binary modules
2013-11-18 07:41:21 +00:00
# Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries
2011-05-11 10:26:49 +00:00
# Also find all packages that the DynamicEx PCDs depend on
Pcds = []
2013-11-18 07:41:21 +00:00
PatchablePcds = {}
2015-12-01 04:22:16 +00:00
Packages = []
2013-11-18 07:41:21 +00:00
PcdCheckList = []
PcdTokenSpaceList = []
2011-05-11 10:26:49 +00:00
for Pcd in self . ModulePcdList + self . LibraryPcdList :
2013-11-18 07:41:21 +00:00
if Pcd . Type == TAB_PCDS_PATCHABLE_IN_MODULE :
PatchablePcds [ Pcd . TokenCName ] = Pcd
PcdCheckList . append (( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , 'PatchableInModule' ))
elif Pcd . Type in GenC . gDynamicExPcd :
if Pcd not in Pcds :
Pcds += [ Pcd ]
PcdCheckList . append (( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , 'DynamicEx' ))
PcdCheckList . append (( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , 'Dynamic' ))
PcdTokenSpaceList . append ( Pcd . TokenSpaceGuidCName )
GuidList = sdict ()
GuidList . update ( self . GuidList )
for TokenSpace in self . GetGuidsUsedByPcd ():
# If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list
# The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs
if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList :
GuidList . pop ( TokenSpace )
CheckList = ( GuidList , self . PpiList , self . ProtocolList , PcdCheckList )
for Package in self . DerivedPackageList :
if Package in Packages :
continue
BeChecked = ( Package . Guids , Package . Ppis , Package . Protocols , Package . Pcds )
Found = False
for Index in range ( len ( BeChecked )):
for Item in CheckList [ Index ]:
if Item in BeChecked [ Index ]:
Packages += [ Package ]
Found = True
break
if Found : break
2011-05-11 10:26:49 +00:00
2014-08-28 13:53:34 +00:00
VfrPcds = self . _GetPcdsMaybeUsedByVfr ()
for Pkg in self . PlatformInfo . PackageList :
if Pkg in Packages :
continue
for VfrPcd in VfrPcds :
if (( VfrPcd . TokenCName , VfrPcd . TokenSpaceGuidCName , 'DynamicEx' ) in Pkg . Pcds or
( VfrPcd . TokenCName , VfrPcd . TokenSpaceGuidCName , 'Dynamic' ) in Pkg . Pcds ):
Packages += [ Pkg ]
break
2011-05-11 10:26:49 +00:00
ModuleType = self . ModuleType
if ModuleType == 'UEFI_DRIVER' and self . DepexGenerated :
2013-11-18 07:41:21 +00:00
ModuleType = 'DXE_DRIVER'
DriverType = ''
if self . PcdIsDriver != '' :
DriverType = self . PcdIsDriver
2011-05-11 10:26:49 +00:00
2014-08-28 13:53:34 +00:00
Guid = self . Guid
MDefs = self . Module . Defines
2011-05-11 10:26:49 +00:00
AsBuiltInfDict = {
'module_name' : self . Name ,
2014-08-28 13:53:34 +00:00
'module_guid' : Guid ,
2011-05-11 10:26:49 +00:00
'module_module_type' : ModuleType ,
2014-08-28 13:53:34 +00:00
'module_version_string' : [ MDefs [ 'VERSION_STRING' ]] if 'VERSION_STRING' in MDefs else [],
2013-11-18 07:41:21 +00:00
'pcd_is_driver_string' : [],
2011-05-11 10:26:49 +00:00
'module_uefi_specification_version' : [],
'module_pi_specification_version' : [],
2014-08-28 13:53:34 +00:00
'module_entry_point' : self . Module . ModuleEntryPointList ,
'module_unload_image' : self . Module . ModuleUnloadImageList ,
'module_constructor' : self . Module . ConstructorList ,
'module_destructor' : self . Module . DestructorList ,
'module_shadow' : [ MDefs [ 'SHADOW' ]] if 'SHADOW' in MDefs else [],
'module_pci_vendor_id' : [ MDefs [ 'PCI_VENDOR_ID' ]] if 'PCI_VENDOR_ID' in MDefs else [],
'module_pci_device_id' : [ MDefs [ 'PCI_DEVICE_ID' ]] if 'PCI_DEVICE_ID' in MDefs else [],
'module_pci_class_code' : [ MDefs [ 'PCI_CLASS_CODE' ]] if 'PCI_CLASS_CODE' in MDefs else [],
'module_pci_revision' : [ MDefs [ 'PCI_REVISION' ]] if 'PCI_REVISION' in MDefs else [],
'module_build_number' : [ MDefs [ 'BUILD_NUMBER' ]] if 'BUILD_NUMBER' in MDefs else [],
'module_spec' : [ MDefs [ 'SPEC' ]] if 'SPEC' in MDefs else [],
'module_uefi_hii_resource_section' : [ MDefs [ 'UEFI_HII_RESOURCE_SECTION' ]] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],
'module_uni_file' : [ MDefs [ 'MODULE_UNI_FILE' ]] if 'MODULE_UNI_FILE' in MDefs else [],
2011-05-11 10:26:49 +00:00
'module_arch' : self . Arch ,
2015-12-01 04:22:16 +00:00
'package_item' : [ ' %s ' % ( Package . MetaFile . File . replace ( ' \\ ' , '/' )) for Package in Packages ],
2011-05-11 10:26:49 +00:00
'binary_item' : [],
2013-11-18 07:41:21 +00:00
'patchablepcd_item' : [],
2011-05-11 10:26:49 +00:00
'pcd_item' : [],
2013-11-18 07:41:21 +00:00
'protocol_item' : [],
'ppi_item' : [],
'guid_item' : [],
'flags_item' : [],
'libraryclasses_item' : []
2011-05-11 10:26:49 +00:00
}
2014-08-28 13:53:34 +00:00
if self . AutoGenVersion > int ( gInfSpecVersion , 0 ):
AsBuiltInfDict [ 'module_inf_version' ] = '0x %08x ' % self . AutoGenVersion
else :
AsBuiltInfDict [ 'module_inf_version' ] = gInfSpecVersion
2013-11-18 07:41:21 +00:00
if DriverType :
AsBuiltInfDict [ 'pcd_is_driver_string' ] += [ DriverType ]
2011-05-11 10:26:49 +00:00
if 'UEFI_SPECIFICATION_VERSION' in self . Specification :
AsBuiltInfDict [ 'module_uefi_specification_version' ] += [ self . Specification [ 'UEFI_SPECIFICATION_VERSION' ]]
if 'PI_SPECIFICATION_VERSION' in self . Specification :
AsBuiltInfDict [ 'module_pi_specification_version' ] += [ self . Specification [ 'PI_SPECIFICATION_VERSION' ]]
2015-12-01 04:22:16 +00:00
OutputDir = self . OutputDir . replace ( ' \\ ' , '/' ) . strip ( '/' )
2011-05-11 10:26:49 +00:00
if self . ModuleType in [ 'BASE' , 'USER_DEFINED' ]:
for Item in self . CodaTargetList :
2015-12-01 04:22:16 +00:00
File = Item . Target . Path . replace ( ' \\ ' , '/' ) . strip ( '/' ) . replace ( OutputDir , '' ) . strip ( '/' )
if Item . Target . Ext . lower () == '.aml' :
2011-05-11 10:26:49 +00:00
AsBuiltInfDict [ 'binary_item' ] += [ 'ASL|' + File ]
2015-12-01 04:22:16 +00:00
elif Item . Target . Ext . lower () == '.acpi' :
2011-05-11 10:26:49 +00:00
AsBuiltInfDict [ 'binary_item' ] += [ 'ACPI|' + File ]
else :
AsBuiltInfDict [ 'binary_item' ] += [ 'BIN|' + File ]
else :
for Item in self . CodaTargetList :
2015-12-01 04:22:16 +00:00
File = Item . Target . Path . replace ( ' \\ ' , '/' ) . strip ( '/' ) . replace ( OutputDir , '' ) . strip ( '/' )
if Item . Target . Ext . lower () == '.efi' :
2011-05-11 10:26:49 +00:00
AsBuiltInfDict [ 'binary_item' ] += [ 'PE32|' + self . Name + '.efi' ]
else :
AsBuiltInfDict [ 'binary_item' ] += [ 'BIN|' + File ]
if self . DepexGenerated :
if self . ModuleType in [ 'PEIM' ]:
AsBuiltInfDict [ 'binary_item' ] += [ 'PEI_DEPEX|' + self . Name + '.depex' ]
2015-12-01 04:22:16 +00:00
if self . ModuleType in [ 'DXE_DRIVER' , 'DXE_RUNTIME_DRIVER' , 'DXE_SAL_DRIVER' , 'UEFI_DRIVER' ]:
2011-05-11 10:26:49 +00:00
AsBuiltInfDict [ 'binary_item' ] += [ 'DXE_DEPEX|' + self . Name + '.depex' ]
if self . ModuleType in [ 'DXE_SMM_DRIVER' ]:
AsBuiltInfDict [ 'binary_item' ] += [ 'SMM_DEPEX|' + self . Name + '.depex' ]
2015-06-11 05:20:00 +00:00
Bin = self . _GenOffsetBin ()
if Bin :
AsBuiltInfDict [ 'binary_item' ] += [ 'BIN| %s ' % Bin ]
2013-11-18 07:41:21 +00:00
for Root , Dirs , Files in os . walk ( OutputDir ):
for File in Files :
if File . lower () . endswith ( '.pdb' ):
AsBuiltInfDict [ 'binary_item' ] += [ 'DISPOSABLE|' + File ]
HeaderComments = self . Module . HeaderComments
StartPos = 0
for Index in range ( len ( HeaderComments )):
if HeaderComments [ Index ] . find ( '@BinaryHeader' ) != - 1 :
HeaderComments [ Index ] = HeaderComments [ Index ] . replace ( '@BinaryHeader' , '@file' )
StartPos = Index
break
AsBuiltInfDict [ 'header_comments' ] = ' \n ' . join ( HeaderComments [ StartPos :]) . replace ( ':#' , '://' )
2014-08-28 13:53:34 +00:00
AsBuiltInfDict [ 'tail_comments' ] = ' \n ' . join ( self . Module . TailComments )
2013-11-18 07:41:21 +00:00
GenList = [
( self . ProtocolList , self . _ProtocolComments , 'protocol_item' ),
( self . PpiList , self . _PpiComments , 'ppi_item' ),
( GuidList , self . _GuidComments , 'guid_item' )
]
for Item in GenList :
for CName in Item [ 0 ]:
Comments = ''
if CName in Item [ 1 ]:
Comments = ' \n ' . join ( Item [ 1 ][ CName ])
Entry = CName
if Comments :
Entry = Comments + ' \n ' + CName
AsBuiltInfDict [ Item [ 2 ]] . append ( Entry )
PatchList = parsePcdInfoFromMapFile (
os . path . join ( self . OutputDir , self . Name + '.map' ),
os . path . join ( self . OutputDir , self . Name + '.efi' )
)
if PatchList :
for PatchPcd in PatchList :
if PatchPcd [ 0 ] not in PatchablePcds :
continue
Pcd = PatchablePcds [ PatchPcd [ 0 ]]
PcdValue = ''
if Pcd . DatumType != 'VOID*' :
HexFormat = '0x %02x '
if Pcd . DatumType == 'UINT16' :
HexFormat = '0x %04x '
elif Pcd . DatumType == 'UINT32' :
HexFormat = '0x %08x '
elif Pcd . DatumType == 'UINT64' :
HexFormat = '0x %016x '
PcdValue = HexFormat % int ( Pcd . DefaultValue , 0 )
else :
if Pcd . MaxDatumSize == None or Pcd . MaxDatumSize == '' :
EdkLogger . error ( "build" , AUTOGEN_ERROR ,
"Unknown [MaxDatumSize] of PCD [ %s . %s ]" % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
)
ArraySize = int ( Pcd . MaxDatumSize , 0 )
PcdValue = Pcd . DefaultValue
if PcdValue [ 0 ] != '{' :
Unicode = False
if PcdValue [ 0 ] == 'L' :
Unicode = True
PcdValue = PcdValue . lstrip ( 'L' )
PcdValue = eval ( PcdValue )
NewValue = '{'
for Index in range ( 0 , len ( PcdValue )):
if Unicode :
CharVal = ord ( PcdValue [ Index ])
NewValue = NewValue + '0x %02x ' % ( CharVal & 0x00FF ) + ', ' \
+ '0x %02x ' % ( CharVal >> 8 ) + ', '
else :
NewValue = NewValue + '0x %02x ' % ( ord ( PcdValue [ Index ]) % 0x100 ) + ', '
Padding = '0x00, '
if Unicode :
Padding = Padding * 2
ArraySize = ArraySize / 2
if ArraySize < ( len ( PcdValue ) + 1 ):
EdkLogger . error ( "build" , AUTOGEN_ERROR ,
"The maximum size of VOID* type PCD ' %s . %s ' is less than its actual size occupied." % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
)
if ArraySize > len ( PcdValue ) + 1 :
NewValue = NewValue + Padding * ( ArraySize - len ( PcdValue ) - 1 )
PcdValue = NewValue + Padding . strip () . rstrip ( ',' ) + '}'
elif len ( PcdValue . split ( ',' )) <= ArraySize :
PcdValue = PcdValue . rstrip ( '}' ) + ', 0x00' * ( ArraySize - len ( PcdValue . split ( ',' )))
PcdValue += '}'
else :
EdkLogger . error ( "build" , AUTOGEN_ERROR ,
"The maximum size of VOID* type PCD ' %s . %s ' is less than its actual size occupied." % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
)
PcdItem = ' %s . %s | %s |0x %X ' % \
( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , PcdValue , PatchPcd [ 1 ])
PcdComments = ''
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) in self . _PcdComments :
PcdComments = ' \n ' . join ( self . _PcdComments [ Pcd . TokenSpaceGuidCName , Pcd . TokenCName ])
if PcdComments :
PcdItem = PcdComments + ' \n ' + PcdItem
AsBuiltInfDict [ 'patchablepcd_item' ] . append ( PcdItem )
2014-08-28 13:53:34 +00:00
HiiPcds = []
for Pcd in Pcds + VfrPcds :
2013-11-18 07:41:21 +00:00
PcdComments = ''
PcdCommentList = []
HiiInfo = ''
2014-08-28 13:53:34 +00:00
SkuId = ''
2013-11-18 07:41:21 +00:00
if Pcd . Type == TAB_PCDS_DYNAMIC_EX_HII :
for SkuName in Pcd . SkuInfoList :
SkuInfo = Pcd . SkuInfoList [ SkuName ]
2014-08-28 13:53:34 +00:00
SkuId = SkuInfo . SkuId
2013-11-18 07:41:21 +00:00
HiiInfo = '## %s | %s | %s ' % ( SkuInfo . VariableName , SkuInfo . VariableGuid , SkuInfo . VariableOffset )
break
2014-08-28 13:53:34 +00:00
if SkuId :
#
# Don't generate duplicated HII PCD
#
if ( SkuId , Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) in HiiPcds :
continue
else :
HiiPcds . append (( SkuId , Pcd . TokenSpaceGuidCName , Pcd . TokenCName ))
2013-11-18 07:41:21 +00:00
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) in self . _PcdComments :
PcdCommentList = self . _PcdComments [ Pcd . TokenSpaceGuidCName , Pcd . TokenCName ][:]
if HiiInfo :
UsageIndex = - 1
2014-08-28 13:53:34 +00:00
UsageStr = ''
2013-11-18 07:41:21 +00:00
for Index , Comment in enumerate ( PcdCommentList ):
for Usage in UsageList :
if Comment . find ( Usage ) != - 1 :
2014-08-28 13:53:34 +00:00
UsageStr = Usage
2013-11-18 07:41:21 +00:00
UsageIndex = Index
break
if UsageIndex != - 1 :
2014-08-28 13:53:34 +00:00
PcdCommentList [ UsageIndex ] = '## %s %s %s ' % ( UsageStr , HiiInfo , PcdCommentList [ UsageIndex ] . replace ( UsageStr , '' ))
2013-11-18 07:41:21 +00:00
else :
2014-08-28 13:53:34 +00:00
PcdCommentList . append ( '## UNDEFINED ' + HiiInfo )
2013-11-18 07:41:21 +00:00
PcdComments = ' \n ' . join ( PcdCommentList )
PcdEntry = Pcd . TokenSpaceGuidCName + '.' + Pcd . TokenCName
if PcdComments :
PcdEntry = PcdComments + ' \n ' + PcdEntry
AsBuiltInfDict [ 'pcd_item' ] += [ PcdEntry ]
2011-05-11 10:26:49 +00:00
for Item in self . BuildOption :
if 'FLAGS' in self . BuildOption [ Item ]:
AsBuiltInfDict [ 'flags_item' ] += [ ' %s : %s _ %s _ %s _ %s _FLAGS = %s ' % ( self . ToolChainFamily , self . BuildTarget , self . ToolChain , self . Arch , Item , self . BuildOption [ Item ][ 'FLAGS' ] . strip ())]
2014-08-28 13:53:34 +00:00
# Generated LibraryClasses section in comments.
for Library in self . LibraryAutoGenList :
AsBuiltInfDict [ 'libraryclasses_item' ] += [ Library . MetaFile . File . replace ( ' \\ ' , '/' )]
# Generated depex expression section in comments.
AsBuiltInfDict [ 'depexsection_item' ] = ''
DepexExpresion = self . _GetDepexExpresionString ()
if DepexExpresion :
AsBuiltInfDict [ 'depexsection_item' ] = DepexExpresion
2011-05-11 10:26:49 +00:00
AsBuiltInf = TemplateString ()
AsBuiltInf . Append ( gAsBuiltInfHeaderString . Replace ( AsBuiltInfDict ))
SaveFileOnChange ( os . path . join ( self . OutputDir , self . Name + '.inf' ), str ( AsBuiltInf ), False )
self . IsAsBuiltInfCreated = True
2010-02-28 23:39:39 +00:00
## Create makefile for the module and its dependent libraries
#
# @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
# dependent libraries will be created
#
def CreateMakeFile ( self , CreateLibraryMakeFile = True ):
2014-08-26 07:14:38 +00:00
# Ignore generating makefile when it is a binary module
2014-08-26 02:52:24 +00:00
if self . IsBinaryModule :
return
2014-08-26 07:14:38 +00:00
2010-02-28 23:39:39 +00:00
if self . IsMakeFileCreated :
return
if not self . IsLibrary and CreateLibraryMakeFile :
for LibraryAutoGen in self . LibraryAutoGenList :
LibraryAutoGen . CreateMakeFile ()
if len ( self . CustomMakefile ) == 0 :
Makefile = GenMake . ModuleMakefile ( self )
else :
Makefile = GenMake . CustomMakefile ( self )
if Makefile . Generate ():
EdkLogger . debug ( EdkLogger . DEBUG_9 , "Generated makefile for module %s [ %s ]" %
( self . Name , self . Arch ))
else :
EdkLogger . debug ( EdkLogger . DEBUG_9 , "Skipped the generation of makefile for module %s [ %s ]" %
( self . Name , self . Arch ))
self . IsMakeFileCreated = True
2014-08-26 02:52:24 +00:00
def CopyBinaryFiles ( self ):
for File in self . Module . Binaries :
SrcPath = File . Path
DstPath = os . path . join ( self . OutputDir , os . path . basename ( SrcPath ))
CopyLongFilePath ( SrcPath , DstPath )
2010-02-28 23:39:39 +00:00
## Create autogen code for the module and its dependent libraries
#
# @param CreateLibraryCodeFile Flag indicating if or not the code of
# dependent libraries will be created
#
def CreateCodeFile ( self , CreateLibraryCodeFile = True ):
if self . IsCodeFileCreated :
return
2013-11-18 07:41:21 +00:00
# Need to generate PcdDatabase even PcdDriver is binarymodule
if self . IsBinaryModule and self . PcdIsDriver != '' :
CreatePcdDatabaseCode ( self , TemplateString (), TemplateString ())
return
2014-08-26 02:52:24 +00:00
if self . IsBinaryModule :
2014-09-04 08:32:44 +00:00
if self . IsLibrary :
self . CopyBinaryFiles ()
2014-08-26 02:52:24 +00:00
return
2013-11-18 07:41:21 +00:00
2010-02-28 23:39:39 +00:00
if not self . IsLibrary and CreateLibraryCodeFile :
for LibraryAutoGen in self . LibraryAutoGenList :
LibraryAutoGen . CreateCodeFile ()
AutoGenList = []
IgoredAutoGenList = []
for File in self . AutoGenFileList :
if GenC . Generate ( File . Path , self . AutoGenFileList [ File ], File . IsBinary ):
2011-09-18 12:17:25 +00:00
#Ignore Edk AutoGen.c
2010-02-28 23:39:39 +00:00
if self . AutoGenVersion < 0x00010005 and File . Name == 'AutoGen.c' :
continue
AutoGenList . append ( str ( File ))
else :
IgoredAutoGenList . append ( str ( File ))
# Skip the following code for EDK I inf
if self . AutoGenVersion < 0x00010005 :
return
for ModuleType in self . DepexList :
2010-05-18 05:04:32 +00:00
# Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
if len ( self . DepexList [ ModuleType ]) == 0 or ModuleType == "USER_DEFINED" :
2010-02-28 23:39:39 +00:00
continue
2010-05-18 05:04:32 +00:00
2010-02-28 23:39:39 +00:00
Dpx = GenDepex . DependencyExpression ( self . DepexList [ ModuleType ], ModuleType , True )
DpxFile = gAutoGenDepexFileName % { "module_name" : self . Name }
2011-05-11 10:26:49 +00:00
if len ( Dpx . PostfixNotation ) <> 0 :
2011-10-29 06:59:30 +00:00
self . DepexGenerated = True
2011-05-11 10:26:49 +00:00
2010-02-28 23:39:39 +00:00
if Dpx . Generate ( path . join ( self . OutputDir , DpxFile )):
AutoGenList . append ( str ( DpxFile ))
else :
IgoredAutoGenList . append ( str ( DpxFile ))
if IgoredAutoGenList == []:
EdkLogger . debug ( EdkLogger . DEBUG_9 , "Generated [ %s ] files for module %s [ %s ]" %
( " " . join ( AutoGenList ), self . Name , self . Arch ))
elif AutoGenList == []:
EdkLogger . debug ( EdkLogger . DEBUG_9 , "Skipped the generation of [ %s ] files for module %s [ %s ]" %
( " " . join ( IgoredAutoGenList ), self . Name , self . Arch ))
else :
EdkLogger . debug ( EdkLogger . DEBUG_9 , "Generated [ %s ] (skipped %s ) files for module %s [ %s ]" %
( " " . join ( AutoGenList ), " " . join ( IgoredAutoGenList ), self . Name , self . Arch ))
self . IsCodeFileCreated = True
return AutoGenList
## Summarize the ModuleAutoGen objects of all libraries used by this module
def _GetLibraryAutoGenList ( self ):
if self . _LibraryAutoGenList == None :
self . _LibraryAutoGenList = []
for Library in self . DependentLibraryList :
La = ModuleAutoGen (
self . Workspace ,
Library . MetaFile ,
self . BuildTarget ,
self . ToolChain ,
self . Arch ,
self . PlatformInfo . MetaFile
)
if La not in self . _LibraryAutoGenList :
self . _LibraryAutoGenList . append ( La )
for Lib in La . CodaTargetList :
self . _ApplyBuildRule ( Lib . Target , TAB_UNKNOWN_FILE )
return self . _LibraryAutoGenList
Module = property ( _GetModule )
Name = property ( _GetBaseName )
Guid = property ( _GetGuid )
Version = property ( _GetVersion )
ModuleType = property ( _GetModuleType )
ComponentType = property ( _GetComponentType )
BuildType = property ( _GetBuildType )
PcdIsDriver = property ( _GetPcdIsDriver )
AutoGenVersion = property ( _GetAutoGenVersion )
Macros = property ( _GetMacros )
Specification = property ( _GetSpecification )
IsLibrary = property ( _IsLibrary )
2013-11-18 07:41:21 +00:00
IsBinaryModule = property ( _IsBinaryModule )
2010-02-28 23:39:39 +00:00
BuildDir = property ( _GetBuildDir )
OutputDir = property ( _GetOutputDir )
DebugDir = property ( _GetDebugDir )
MakeFileDir = property ( _GetMakeFileDir )
CustomMakefile = property ( _GetCustomMakefile )
IncludePathList = property ( _GetIncludePathList )
2016-03-16 11:06:44 +08:00
IncludePathLength = property ( _GetIncludePathLength )
2010-02-28 23:39:39 +00:00
AutoGenFileList = property ( _GetAutoGenFileList )
UnicodeFileList = property ( _GetUnicodeFileList )
SourceFileList = property ( _GetSourceFileList )
BinaryFileList = property ( _GetBinaryFiles ) # FileType : [File List]
Targets = property ( _GetTargets )
IntroTargetList = property ( _GetIntroTargetList )
CodaTargetList = property ( _GetFinalTargetList )
FileTypes = property ( _GetFileTypes )
BuildRules = property ( _GetBuildRules )
DependentPackageList = property ( _GetDependentPackageList )
DependentLibraryList = property ( _GetLibraryList )
LibraryAutoGenList = property ( _GetLibraryAutoGenList )
DerivedPackageList = property ( _GetDerivedPackageList )
ModulePcdList = property ( _GetModulePcdList )
LibraryPcdList = property ( _GetLibraryPcdList )
GuidList = property ( _GetGuidList )
ProtocolList = property ( _GetProtocolList )
PpiList = property ( _GetPpiList )
DepexList = property ( _GetDepexTokenList )
2011-09-18 12:17:25 +00:00
DxsFile = property ( _GetDxsFile )
2010-02-28 23:39:39 +00:00
DepexExpressionList = property ( _GetDepexExpressionTokenList )
BuildOption = property ( _GetModuleBuildOption )
2011-10-11 02:49:48 +00:00
BuildOptionIncPathList = property ( _GetBuildOptionIncPathList )
2010-02-28 23:39:39 +00:00
BuildCommand = property ( _GetBuildCommand )
2014-01-10 05:25:50 +00:00
FixedAtBuildPcds = property ( _GetFixedAtBuildPcds )
2010-02-28 23:39:39 +00:00
# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__' :
pass