summaryrefslogtreecommitdiff
path: root/BaseTools/Source
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2011-10-29 06:59:30 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2011-10-29 06:59:30 +0000
commit0d2711a69397d2971079121df4326d84736c181e (patch)
tree0d3c93b9db1df5a30a0d15ec9d70c75768c1f67c /BaseTools/Source
parent421fb3b504cfe18033c49a40fcd46bab45a0fb50 (diff)
downloadedk2-platforms-0d2711a69397d2971079121df4326d84736c181e.tar.xz
Sync BaseTools Trunk (version r2387) to EDKII main trunk.
Signed-off-by: lgao4 Reviewed-by: gikidy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12602 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source')
-rw-r--r--BaseTools/Source/C/Common/BasePeCoff.c2
-rw-r--r--BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c4
-rw-r--r--BaseTools/Source/C/GenFv/GenFvInternalLib.c6
-rw-r--r--BaseTools/Source/C/GenFw/Elf32Convert.c10
-rw-r--r--BaseTools/Source/C/GenFw/Elf64Convert.c14
-rw-r--r--BaseTools/Source/C/GenSec/GenSec.c4
-rw-r--r--BaseTools/Source/C/GenVtf/GenVtf.c18
-rw-r--r--BaseTools/Source/C/GnuGenBootSector/GnuGenBootSector.c4
-rw-r--r--BaseTools/Source/C/Include/Common/BuildVersion.h2
-rw-r--r--BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c21
-rw-r--r--BaseTools/Source/C/Makefiles/ms.app22
-rw-r--r--BaseTools/Source/C/Split/Split.c5
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp7
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrFormPkg.h8
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrSyntax.g33
-rw-r--r--BaseTools/Source/C/VolInfo/VolInfo.c1
-rw-r--r--BaseTools/Source/Python/AutoGen/AutoGen.py77
-rw-r--r--BaseTools/Source/Python/AutoGen/BuildEngine.py2
-rw-r--r--BaseTools/Source/Python/AutoGen/GenC.py8
-rw-r--r--BaseTools/Source/Python/AutoGen/GenMake.py14
-rw-r--r--BaseTools/Source/Python/Common/BuildVersion.py2
-rw-r--r--BaseTools/Source/Python/Common/DataType.py1
-rw-r--r--BaseTools/Source/Python/Common/Expression.py555
-rw-r--r--BaseTools/Source/Python/Common/GlobalData.py11
-rw-r--r--BaseTools/Source/Python/Common/Misc.py8
-rw-r--r--BaseTools/Source/Python/Common/String.py56
-rw-r--r--BaseTools/Source/Python/CommonDataClass/DataClass.py4
-rw-r--r--BaseTools/Source/Python/CommonDataClass/Exceptions.py29
-rw-r--r--BaseTools/Source/Python/GenFds/AprioriSection.py4
-rw-r--r--BaseTools/Source/Python/GenFds/DepexSection.py5
-rw-r--r--BaseTools/Source/Python/GenFds/Fd.py8
-rw-r--r--BaseTools/Source/Python/GenFds/FdfParser.py268
-rw-r--r--BaseTools/Source/Python/GenFds/FfsFileStatement.py4
-rw-r--r--BaseTools/Source/Python/GenFds/FfsInfStatement.py14
-rw-r--r--BaseTools/Source/Python/GenFds/Fv.py8
-rw-r--r--BaseTools/Source/Python/GenFds/GenFds.py37
-rw-r--r--BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py73
-rw-r--r--BaseTools/Source/Python/GenFds/Section.py2
-rw-r--r--BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py1
-rw-r--r--BaseTools/Source/Python/UPT/Library/ParserValidate.py12
-rw-r--r--BaseTools/Source/Python/Workspace/MetaDataTable.py31
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileParser.py1126
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileTable.py106
-rw-r--r--BaseTools/Source/Python/Workspace/WorkspaceDatabase.py509
-rw-r--r--BaseTools/Source/Python/build/BuildReport.py46
-rw-r--r--BaseTools/Source/Python/build/build.py344
46 files changed, 2227 insertions, 1299 deletions
diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c
index 54bd099e1d..816f309f66 100644
--- a/BaseTools/Source/C/Common/BasePeCoff.c
+++ b/BaseTools/Source/C/Common/BasePeCoff.c
@@ -979,6 +979,7 @@ Returns:
ImageContext,
Section->VirtualAddress + Section->Misc.VirtualSize - 1
);
+
//
// If the base start or end address resolved to 0, then fail.
//
@@ -987,6 +988,7 @@ Returns:
return RETURN_LOAD_ERROR;
}
+
if (ImageContext->IsTeImage) {
Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);
End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);
diff --git a/BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c b/BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c
index 01685964f1..f83c532b25 100644
--- a/BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c
+++ b/BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -181,7 +181,6 @@ Returns:
CHAR8* OutputFileName = NULL;
CHAR8* InputFileNames[MAX_PE_IMAGES + 1];
UINT8 InputFileCount = 0;
- BOOLEAN QuietFlag = FALSE;
UINT64 DebugLevel = 0;
UINT64 VerboseLevel = 0;
EFI_STATUS Status = EFI_SUCCESS;
@@ -220,7 +219,6 @@ Returns:
}
if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
- QuietFlag = TRUE;
argc --;
argv ++;
continue;
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 9fdcb47d6b..45a2c8022d 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -2801,7 +2801,6 @@ Returns:
PE_COFF_LOADER_IMAGE_CONTEXT OrigImageContext;
EFI_PHYSICAL_ADDRESS XipBase;
EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;
- EFI_PHYSICAL_ADDRESS *BaseToUpdate;
UINTN Index;
EFI_FILE_SECTION_POINTER CurrentPe32Section;
EFI_FFS_FILE_STATE SavedState;
@@ -2818,7 +2817,6 @@ Returns:
Index = 0;
MemoryImagePointer = NULL;
- BaseToUpdate = NULL;
TEImageHeader = NULL;
ImgHdr = NULL;
SectionHeader = NULL;
@@ -2992,7 +2990,6 @@ Returns:
}
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
- BaseToUpdate = &XipBase;
break;
case EFI_FV_FILETYPE_DRIVER:
@@ -3008,7 +3005,6 @@ Returns:
return EFI_ABORTED;
}
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
- BaseToUpdate = &XipBase;
break;
default:
diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/GenFw/Elf32Convert.c
index 42ae35bfef..ddb45acc86 100644
--- a/BaseTools/Source/C/GenFw/Elf32Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf32Convert.c
@@ -738,10 +738,6 @@ WriteRelocations32 (
UINT8 *Targ;
Elf32_Phdr *DynamicSegment;
Elf32_Phdr *TargetSegment;
- Elf_Sym *Sym;
- Elf_Shdr *SymtabShdr;
- UINT8 *Symtab;
-
for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) {
Elf_Shdr *RelShdr = GetShdrByIndex(Index);
@@ -750,16 +746,10 @@ WriteRelocations32 (
if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {
UINT32 RelIdx;
- SymtabShdr = GetShdrByIndex (RelShdr->sh_link);
- Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;
FoundRelocations = TRUE;
for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);
- Elf_Shdr *SymShdr;
- Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);
- SymShdr = GetShdrByIndex (Sym->st_shndx);
-
if (mEhdr->e_machine == EM_386) {
switch (ELF_R_TYPE(Rel->r_info)) {
case R_386_NONE:
diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c
index fbe6ff8232..e7c5d4997a 100644
--- a/BaseTools/Source/C/GenFw/Elf64Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -637,28 +637,16 @@ WriteRelocations64 (
UINT32 Index;
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
EFI_IMAGE_DATA_DIRECTORY *Dir;
- BOOLEAN FoundRelocations;
- Elf_Sym *Sym;
- Elf_Shdr *SymtabShdr;
- UINT8 *Symtab;
-
- for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) {
+ for (Index = 0; Index < mEhdr->e_shnum; Index++) {
Elf_Shdr *RelShdr = GetShdrByIndex(Index);
if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) {
Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info);
if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {
UINT64 RelIdx;
- SymtabShdr = GetShdrByIndex (RelShdr->sh_link);
- Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;
- FoundRelocations = TRUE;
for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);
- Elf_Shdr *SymShdr;
-
- Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);
- SymShdr = GetShdrByIndex (Sym->st_shndx);
if (mEhdr->e_machine == EM_X86_64) {
switch (ELF_R_TYPE(Rel->r_info)) {
diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c
index ffa0ee62fb..79e8e1bebb 100644
--- a/BaseTools/Source/C/GenSec/GenSec.c
+++ b/BaseTools/Source/C/GenSec/GenSec.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -915,7 +915,6 @@ Returns:
{
UINT32 Index;
UINT32 InputFileNum;
- FILE *InFile;
FILE *OutFile;
CHAR8 **InputFileName;
CHAR8 *OutputFileName;
@@ -944,7 +943,6 @@ Returns:
SectionName = NULL;
CompressionName = NULL;
StringBuffer = "";
- InFile = NULL;
OutFile = NULL;
VersionNumber = 0;
InputFileNum = 0;
diff --git a/BaseTools/Source/C/GenVtf/GenVtf.c b/BaseTools/Source/C/GenVtf/GenVtf.c
index e56544e544..eaf2f56fed 100644
--- a/BaseTools/Source/C/GenVtf/GenVtf.c
+++ b/BaseTools/Source/C/GenVtf/GenVtf.c
@@ -1,6 +1,6 @@
/**
-Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 1999 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -1141,7 +1141,6 @@ Returns:
EFI_STATUS Status;
UINT64 CompStartAddress;
UINT64 FileSize;
- UINT64 NumByteRead;
UINT64 NumAdjustByte;
UINT8 *Buffer;
FILE *Fp;
@@ -1189,7 +1188,7 @@ Returns:
//
// Read first 64 bytes of PAL header and use it to find version info
//
- NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
+ fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
//
// PAL header contains the version info. Currently, we will use the header
@@ -1200,7 +1199,7 @@ Returns:
}
}
- NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
+ fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
fclose (Fp);
//
@@ -1329,7 +1328,6 @@ Returns:
UINT64 AbsAddress;
UINTN RelativeAddress;
UINT64 FileSize;
- UINT64 NumByteRead;
UINT8 *Buffer;
FILE *Fp;
FIT_TABLE *PalFitPtr;
@@ -1367,7 +1365,7 @@ Returns:
//
// Read, Get version Info and discard the PAL header.
//
- NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
+ fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
//
// Extract the version info from header of PAL_A. Once done, discrad this buffer
@@ -1379,7 +1377,7 @@ Returns:
//
// Read PAL_A file in a buffer
//
- NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
+ fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
fclose (Fp);
PalStartAddress = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize);
@@ -1759,7 +1757,6 @@ Returns:
UINT8 *Buffer;
UINT8 *LocalVtfBuffer;
UINTN FileSize;
- UINTN NumByteRead;
FILE *Fp;
if (!strcmp (FileName, "")) {
@@ -1784,7 +1781,7 @@ Returns:
return EFI_OUT_OF_RESOURCES;
}
- NumByteRead = fread (Buffer, sizeof (UINT8), FileSize, Fp);
+ fread (Buffer, sizeof (UINT8), FileSize, Fp);
LocalVtfBuffer = (UINT8 *) Vtf1EndBuffer - SIZE_IA32_RESET_VECT;
memcpy (LocalVtfBuffer, Buffer, FileSize);
@@ -2121,7 +2118,6 @@ Returns:
FILE *Fp;
UINT64 *StartAddressPtr;
UINTN FirstFwVSize;
- UINTN NumByte;
StartAddressPtr = malloc (sizeof (UINT64));
if (StartAddressPtr == NULL) {
@@ -2141,7 +2137,7 @@ Returns:
FirstFwVSize = _filelength (fileno (Fp));
fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET);
- NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);
+ fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);
if (Fp) {
fclose (Fp);
diff --git a/BaseTools/Source/C/GnuGenBootSector/GnuGenBootSector.c b/BaseTools/Source/C/GnuGenBootSector/GnuGenBootSector.c
index 1ce22fc8fa..b0ec271b05 100644
--- a/BaseTools/Source/C/GnuGenBootSector/GnuGenBootSector.c
+++ b/BaseTools/Source/C/GnuGenBootSector/GnuGenBootSector.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -305,7 +305,6 @@ main (
char *argv[]
)
{
- CHAR8 *AppName;
INTN Index;
BOOLEAN ProcessMbr;
ERROR_STATUS Status;
@@ -319,7 +318,6 @@ main (
ZeroMem(&InputPathInfo, sizeof(PATH_INFO));
ZeroMem(&OutputPathInfo, sizeof(PATH_INFO));
- AppName = *argv;
argv ++;
argc --;
diff --git a/BaseTools/Source/C/Include/Common/BuildVersion.h b/BaseTools/Source/C/Include/Common/BuildVersion.h
index ec4acc338a..6619780239 100644
--- a/BaseTools/Source/C/Include/Common/BuildVersion.h
+++ b/BaseTools/Source/C/Include/Common/BuildVersion.h
@@ -1,3 +1,3 @@
//This file is for build version number auto generation
//
-#define __BUILD_VERSION "Build 2361"
+#define __BUILD_VERSION "Build 2386"
diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
index 529fd98f87..7272272784 100644
--- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
+++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
@@ -1,5 +1,18 @@
-/* LzmaEnc.c -- LZMA Encoder
-2009-02-02 : Igor Pavlov : Public domain */
+/** @file
+ Based on LZMA SDK 4.65:
+ LzmaEnc.c -- LZMA Encoder
+ 2009-02-02 : Igor Pavlov : Public domain
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
#include <string.h>
@@ -1919,11 +1932,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{
UInt32 beforeSize = kNumOpts;
+ #ifdef COMPRESS_MF_MT
Bool btMode;
+ #endif
if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM;
- btMode = (p->matchFinderBase.btMode != 0);
#ifdef COMPRESS_MF_MT
+ btMode = (p->matchFinderBase.btMode != 0);
p->mtMode = (p->multiThread && !p->fastMode && btMode);
#endif
diff --git a/BaseTools/Source/C/Makefiles/ms.app b/BaseTools/Source/C/Makefiles/ms.app
index 84173e5da4..7812175e7f 100644
--- a/BaseTools/Source/C/Makefiles/ms.app
+++ b/BaseTools/Source/C/Makefiles/ms.app
@@ -1,12 +1,12 @@
-## @file
-#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+## @file
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
!INCLUDE ..\Makefiles\ms.common
@@ -19,8 +19,8 @@ $(APPLICATION) : $(OBJECTS)
-@if not exist $(BIN_PATH) mkdir $(BIN_PATH)
$(LD) /nologo /debug /incremental:no /nodefaultlib:libc.lib /out:$@ $(LIBS) $**
-$(OBJECTS) : ..\Include\Common\BuildVersion.h
-
+$(OBJECTS) : ..\Include\Common\BuildVersion.h
+
.PHONY:clean
.PHONY:cleanall
diff --git a/BaseTools/Source/C/Split/Split.c b/BaseTools/Source/C/Split/Split.c
index 9b81eeb762..544da91f4b 100644
--- a/BaseTools/Source/C/Split/Split.c
+++ b/BaseTools/Source/C/Split/Split.c
@@ -2,7 +2,7 @@
Split a file into two pieces at the request offset.
-Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 1999 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -26,7 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ParseInf.h"
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"
-
//
// Utility Name
//
@@ -230,7 +229,6 @@ Returns:
CHAR8 *CurrentDir = NULL;
UINT64 Index;
CHAR8 CharC;
- BOOLEAN QuietFlag = TRUE;
UINT64 DebugLevel = 0;
UINT64 VerboseLevel = 0;
@@ -308,7 +306,6 @@ Returns:
}
if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
- QuietFlag = TRUE;
argc --;
argv ++;
continue;
diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
index f0678ca3cb..94ad55b1bb 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
@@ -662,6 +662,13 @@ CFormPkg::DeclarePendingQuestion (
CNObj.SetQuestionId (QId);
CNObj.SetVarStoreInfo (&Info);
+ //
+ // Numeric doesn't support BOOLEAN data type.
+ // BOOLEAN type has the same data size to UINT8.
+ //
+ if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
+ Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
+ }
CNObj.SetFlags (0, Info.mVarType);
//
diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
index f908718c02..92e47d97a3 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
@@ -847,7 +847,7 @@ private:
public:
CIfrImage () : CIfrObj (EFI_IFR_IMAGE_OP, (CHAR8 **)&mImage),
- CIfrOpHeader (EFI_IFR_FORM_OP, &mImage->Header) {
+ CIfrOpHeader (EFI_IFR_IMAGE_OP, &mImage->Header) {
mImage->Id = EFI_IMAGE_ID_INVALID;
}
@@ -1061,12 +1061,8 @@ public:
mRef2->FormId = FormId;
}
- EFI_VFR_RETURN_CODE SetQuestionId (IN EFI_QUESTION_ID QuestionId) {
- if (QuestionId == EFI_QUESTION_ID_INVALID) {
- return VFR_RETURN_UNDEFINED;
- }
+ VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {
mRef2->QuestionId = QuestionId;
- return VFR_RETURN_SUCCESS;
}
};
diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index d9f8dd99a7..f27f05b689 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -524,28 +524,28 @@ vfrFormSetDefinition :
FSObj->SetClassGuid(&DefaultClassGuid);
if (mOverrideClassGuid != NULL) {
FSObj->SetClassGuid(mOverrideClassGuid);
- }
+ }
break;
case 1:
if (mOverrideClassGuid != NULL) {
ClassGuidNum ++;
- }
+ }
FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
FSObj->SetClassGuid(&ClassGuid1);
if (mOverrideClassGuid != NULL) {
FSObj->SetClassGuid(mOverrideClassGuid);
- }
+ }
break;
case 2:
if (mOverrideClassGuid != NULL) {
ClassGuidNum ++;
- }
+ }
FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
FSObj->SetClassGuid(&ClassGuid1);
FSObj->SetClassGuid(&ClassGuid2);
if (mOverrideClassGuid != NULL) {
FSObj->SetClassGuid(mOverrideClassGuid);
- }
+ }
break;
case 3:
FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
@@ -1646,6 +1646,7 @@ vfrStatementGoto :
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
UINT32 BitMask;
CIfrQuestionHeader *QHObj = NULL;
+ CIfrOpHeader *OHObj = NULL;
CIfrRef *R1Obj = NULL;
CIfrRef2 *R2Obj = NULL;
CIfrRef3 *R3Obj = NULL;
@@ -1682,8 +1683,13 @@ vfrStatementGoto :
FormId "=" F3:Number "," << RefType = 2; FId = _STOFID(F3->getText()); >>
Question "="
(
- QN3:StringIdentifier "," << mCVfrQuestionDB.GetQuestionId (QN3->getText (), NULL, QId, BitMask); >>
- | QN3:Number "," << QId = _STOQID(QN3->getText()); >>
+ QN3:StringIdentifier "," <<
+ mCVfrQuestionDB.GetQuestionId (QN3->getText (), NULL, QId, BitMask);
+ if (QId == EFI_QUESTION_ID_INVALID) {
+ _PCATCH(VFR_RETURN_UNDEFINED, QN3);
+ }
+ >>
+ | QN4:Number "," << QId = _STOQID(QN4->getText()); >>
)
)
|
@@ -1700,6 +1706,7 @@ vfrStatementGoto :
{
R5Obj = new CIfrRef5;
QHObj = R5Obj;
+ OHObj = R5Obj;
R5Obj->SetLineNo(G->getLine());
break;
}
@@ -1707,6 +1714,7 @@ vfrStatementGoto :
{
R4Obj = new CIfrRef4;
QHObj = R4Obj;
+ OHObj = R4Obj;
R4Obj->SetLineNo(G->getLine());
R4Obj->SetDevicePath (DevPath);
R4Obj->SetFormSetId (FSId);
@@ -1718,6 +1726,7 @@ vfrStatementGoto :
{
R3Obj = new CIfrRef3;
QHObj = R3Obj;
+ OHObj = R3Obj;
R3Obj->SetLineNo(G->getLine());
R3Obj->SetFormSetId (FSId);
R3Obj->SetFormId (FId);
@@ -1728,15 +1737,17 @@ vfrStatementGoto :
{
R2Obj = new CIfrRef2;
QHObj = R2Obj;
+ OHObj = R2Obj;
R2Obj->SetLineNo(G->getLine());
R2Obj->SetFormId (FId);
- _PCATCH(R2Obj->SetQuestionId (QId), QN3);
+ R2Obj->SetQuestionId (QId);
break;
}
case 1:
{
R1Obj = new CIfrRef;
QHObj = R1Obj;
+ OHObj = R1Obj;
R1Obj->SetLineNo(G->getLine());
R1Obj->SetFormId (FId);
break;
@@ -1745,11 +1756,14 @@ vfrStatementGoto :
}
>>
vfrQuestionHeader[*QHObj, QUESTION_REF]
- { "," vfrStatementStatTagList }
{ "," F:FLAGS "=" vfrGotoFlags[QHObj, F->getLine()] }
{
"," Key "=" KN:Number << AssignQuestionKey (*QHObj, KN); >>
}
+ {
+ E:","
+ vfrStatementQuestionOptionList << OHObj->SetScope(1); CRT_END_OP (E);>>
+ }
";" << if (R1Obj != NULL) {delete R1Obj;} if (R2Obj != NULL) {delete R2Obj;} if (R3Obj != NULL) {delete R3Obj;} if (R4Obj != NULL) {delete R4Obj;} if (R5Obj != NULL) {delete R5Obj;}>>
;
@@ -3615,6 +3629,7 @@ vfrExpressionUnaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
| question2refExp[$RootLevel, $ExpOpCount]
| stringref2Exp[$RootLevel, $ExpOpCount]
| toboolExp[$RootLevel, $ExpOpCount]
+ | tostringExp[$RootLevel, $ExpOpCount]
| unintExp[$RootLevel, $ExpOpCount]
| toupperExp[$RootLevel, $ExpOpCount]
| tolwerExp[$RootLevel, $ExpOpCount]
diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c
index 78c6cf6561..f514ba8c38 100644
--- a/BaseTools/Source/C/VolInfo/VolInfo.c
+++ b/BaseTools/Source/C/VolInfo/VolInfo.c
@@ -30,7 +30,6 @@ Abstract:
#include <Common/UefiCapsule.h>
#include <Common/PiFirmwareFile.h>
#include <Common/PiFirmwareVolume.h>
-
#include <Guid/PiFirmwareFileSystem.h>
#include <IndustryStandard/PeImage.h>
#include <Protocol/GuidedSectionExtraction.h>
diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 8150ea0b69..2def474b17 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -180,16 +180,16 @@ class WorkspaceAutoGen(AutoGen):
Fvs = []
if Caps is None:
Caps = []
- self.MetaFile = ActivePlatform.MetaFile
+ self.BuildDatabase = MetaFileDb
+ self.MetaFile = ActivePlatform
self.WorkspaceDir = WorkspaceDir
- self.Platform = ActivePlatform
+ self.Platform = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain]
self.BuildTarget = Target
self.ToolChain = Toolchain
self.ArchList = ArchList
self.SkuId = SkuId
self.UniFlag = UniFlag
- self.BuildDatabase = MetaFileDb
self.TargetTxt = BuildConfig
self.ToolDef = ToolDefinition
self.FdfFile = FlashDefinitionFile
@@ -201,30 +201,74 @@ class WorkspaceAutoGen(AutoGen):
# there's many relative directory operations, so ...
os.chdir(self.WorkspaceDir)
+ #
+ # 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("\nArch [%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:
+ EdkLogger.error("build", PARAMETER_INVALID,
+ ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"
+ % (self.BuildTarget, " ".join(self.Platform.BuildTargets)))
+
+ # Validate SKU ID
+ if not self.SkuId:
+ self.SkuId = 'DEFAULT'
+
+ if self.SkuId not in self.Platform.SkuIds:
+ EdkLogger.error("build", PARAMETER_INVALID,
+ ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
+ % (self.SkuId, " ".join(self.Platform.SkuIds.keys())))
+
# parse FDF file to get PCDs in it, if any
- if self.FdfFile != None and self.FdfFile != '':
- #
- # Make global macros available when parsing FDF file
- #
- InputMacroDict.update(self.BuildDatabase.WorkspaceDb._GlobalMacros)
+ if not self.FdfFile:
+ self.FdfFile = self.Platform.FlashDefinition
+ EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)
+
+ if self.FdfFile:
#
# Mark now build in AutoGen Phase
#
- GlobalData.gAutoGenPhase = True
+ GlobalData.gAutoGenPhase = True
Fdf = FdfParser(self.FdfFile.Path)
Fdf.ParseFile()
- GlobalData.gAutoGenPhase = False
+ GlobalData.gAutoGenPhase = False
PcdSet = Fdf.Profile.PcdDict
ModuleList = Fdf.Profile.InfList
self.FdfProfile = Fdf.Profile
+ 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)
else:
PcdSet = {}
ModuleList = []
self.FdfProfile = None
+ 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 = []
# apply SKU and inject PCDs from Flash Definition file
for Arch in self.ArchList:
- Platform = self.BuildDatabase[self.MetaFile, Arch]
+ Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
Platform.SkuName = self.SkuId
for Name, Guid in PcdSet:
Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
@@ -971,7 +1015,7 @@ class PlatformAutoGen(AutoGen):
## Return the platform build data object
def _GetPlatform(self):
if self._Platform == None:
- self._Platform = self.BuildDatabase[self.MetaFile, self.Arch]
+ self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
return self._Platform
## Return platform name
@@ -1309,7 +1353,7 @@ class PlatformAutoGen(AutoGen):
File=self.MetaFile,
ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
- LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]
+ LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]
# for those forced library instance (NULL library), add a fake library class
if LibraryClassName.startswith("NULL"):
LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
@@ -1907,6 +1951,7 @@ class ModuleAutoGen(AutoGen):
self._Macro["ARCH" ] = self.Arch
self._Macro["TOOLCHAIN" ] = self.ToolChain
self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain
+ self._Macro["TOOL_CHAIN_TAG" ] = self.ToolChain
self._Macro["TARGET" ] = self.BuildTarget
self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir
@@ -1920,7 +1965,7 @@ class ModuleAutoGen(AutoGen):
## Return the module build data object
def _GetModule(self):
if self._Module == None:
- self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch]
+ self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
return self._Module
## Return the module name
@@ -2279,7 +2324,7 @@ class ModuleAutoGen(AutoGen):
if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:
# Skip all files that are not binary libraries
if not self.IsLibrary:
- continue
+ continue
RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
elif FileType in self.BuildRules:
RuleObject = self.BuildRules[FileType]
@@ -2672,7 +2717,7 @@ class ModuleAutoGen(AutoGen):
DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
if len(Dpx.PostfixNotation) <> 0:
- self.DepexGenerated = True
+ self.DepexGenerated = True
if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
AutoGenList.append(str(DpxFile))
diff --git a/BaseTools/Source/Python/AutoGen/BuildEngine.py b/BaseTools/Source/Python/AutoGen/BuildEngine.py
index 73b4a97417..45a560448e 100644
--- a/BaseTools/Source/Python/AutoGen/BuildEngine.py
+++ b/BaseTools/Source/Python/AutoGen/BuildEngine.py
@@ -137,7 +137,7 @@ class FileBuildRule:
self.MacroList = []
self.CommandList = []
for CmdLine in Command:
- self.MacroList.extend(gMacroPattern.findall(CmdLine))
+ self.MacroList.extend(gMacroRefPattern.findall(CmdLine))
# replace path separator with native one
self.CommandList.append(CmdLine)
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index f733ac3e8d..c6b65f4924 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -956,6 +956,14 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
Value = Pcd.DefaultValue
Unicode = False
ValueNumber = 0
+
+ if Pcd.DatumType == 'BOOLEAN':
+ BoolValue = Value.upper()
+ if BoolValue == 'TRUE':
+ Value = 1
+ elif BoolValue == 'FALSE':
+ Value = 0
+
if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']:
try:
if Value.upper().startswith('0X'):
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 3720c8bfed..478ab0f01b 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -493,7 +493,7 @@ cleanlib:
# convert source files and binary files to build targets
self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
- if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
+ if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
ExtraData="[%s]" % str(self._AutoGenObject))
@@ -1253,7 +1253,7 @@ ${END}\t@cd $(BUILD_DIR)
#
fds: init
\t-@cd $(FV_DIR)
-${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list}${END}${BEGIN}${extra_options}${END}${BEGIN} -r ${fd}${END}${BEGIN} -i ${fv}${END}${BEGIN} -C ${cap}${END}${BEGIN} -D${macro}${END}
+${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}
#
# run command for emulator platform only
@@ -1320,6 +1320,11 @@ ${END}\t@cd $(BUILD_DIR)\n
MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName]))
else:
MacroList.append('"%s"' % MacroName)
+ for MacroName in GlobalData.gCommandLineDefines:
+ if GlobalData.gCommandLineDefines[MacroName] != "":
+ MacroList.append('"%s=%s"' % (MacroName, GlobalData.gCommandLineDefines[MacroName]))
+ else:
+ MacroList.append('"%s"' % MacroName)
else:
FdfFileList = []
@@ -1335,9 +1340,6 @@ ${END}\t@cd $(BUILD_DIR)\n
if GlobalData.gCaseInsensitive:
ExtraOption += " -c"
- ExtraOptionList = []
- if ExtraOption:
- ExtraOptionList.append(ExtraOption)
MakefileName = self._FILE_NAME_[self._FileType]
SubBuildCommandList = []
@@ -1369,7 +1371,7 @@ ${END}\t@cd $(BUILD_DIR)\n
"fd" : PlatformInfo.FdTargetList,
"fv" : PlatformInfo.FvTargetList,
"cap" : PlatformInfo.CapTargetList,
- "extra_options" : ExtraOptionList,
+ "extra_options" : ExtraOption,
"macro" : MacroList,
}
diff --git a/BaseTools/Source/Python/Common/BuildVersion.py b/BaseTools/Source/Python/Common/BuildVersion.py
index fecc40e84a..82597c0945 100644
--- a/BaseTools/Source/Python/Common/BuildVersion.py
+++ b/BaseTools/Source/Python/Common/BuildVersion.py
@@ -1,3 +1,3 @@
#This file is for build version number auto generation
#
-gBUILD_VERSION = "Build 2361"
+gBUILD_VERSION = "Build 2386"
diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index 9a2556749a..fc0a7ad026 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -360,6 +360,7 @@ TAB_DSC_DEFINES_ISO_LANGUAGES = 'ISO_LANGUAGES'
TAB_DSC_DEFINES_DEFINE = 'DEFINE'
TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID'
TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'
+TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL'
#
# TargetTxt Definitions
diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py
new file mode 100644
index 0000000000..e2889a8dd3
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Expression.py
@@ -0,0 +1,555 @@
+## @file
+# This file is used to parse and evaluate expression in directive or PCD value.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+## Import Modules
+#
+from Common.GlobalData import *
+from CommonDataClass.Exceptions import BadExpression
+from CommonDataClass.Exceptions import SymbolNotFound
+from CommonDataClass.Exceptions import WrnExpression
+from Misc import GuidStringToGuidStructureString
+
+ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'
+ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].'
+ERR_MATCH = 'No matching right parenthesis.'
+ERR_STRING_TOKEN = 'Bad string token: [%s].'
+ERR_MACRO_TOKEN = 'Bad macro token: [%s].'
+ERR_EMPTY_TOKEN = 'Empty token is not allowed.'
+ERR_PCD_RESOLVE = 'PCD token cannot be resolved: [%s].'
+ERR_VALID_TOKEN = 'No more valid token found from rest of string: [%s].'
+ERR_EXPR_TYPE = 'Different types found in expression.'
+ERR_OPERATOR_UNSUPPORT = 'Unsupported operator: [%s]'
+ERR_REL_NOT_IN = 'Expect "IN" after "not" operator.'
+WRN_BOOL_EXPR = 'Operand of boolean type cannot be used in arithmetic expression.'
+WRN_EQCMP_STR_OTHERS = '== Comparison between Operand of string type and Boolean/Number Type always return False.'
+WRN_NECMP_STR_OTHERS = '!= Comparison between Operand of string type and Boolean/Number Type always return True.'
+ERR_RELCMP_STR_OTHERS = 'Operator taking Operand of string type and Boolean/Number Type is not allowed: [%s].'
+ERR_STRING_CMP = 'Unicode string and general string cannot be compared: [%s %s %s]'
+ERR_ARRAY_TOKEN = 'Bad C array or C format GUID token: [%s].'
+ERR_ARRAY_ELE = 'This must be HEX value for NList or Array: [%s].'
+
+## SplitString
+# Split string to list according double quote
+# For example: abc"de\"f"ghi"jkl"mn will be: ['abc', '"de\"f"', 'ghi', '"jkl"', 'mn']
+#
+def SplitString(String):
+ # There might be escaped quote: "abc\"def\\\"ghi"
+ Str = String.replace('\\\\', '//').replace('\\\"', '\\\'')
+ RetList = []
+ InQuote = False
+ Item = ''
+ for i, ch in enumerate(Str):
+ if ch == '"':
+ InQuote = not InQuote
+ if not InQuote:
+ Item += String[i]
+ RetList.append(Item)
+ Item = ''
+ continue
+ if Item:
+ RetList.append(Item)
+ Item = ''
+ Item += String[i]
+ if InQuote:
+ raise BadExpression(ERR_STRING_TOKEN % Item)
+ if Item:
+ RetList.append(Item)
+ return RetList
+
+## ReplaceExprMacro
+#
+def ReplaceExprMacro(String, Macros, ExceptionList = None):
+ StrList = SplitString(String)
+ for i, String in enumerate(StrList):
+ InQuote = False
+ if String.startswith('"'):
+ InQuote = True
+ MacroStartPos = String.find('$(')
+ if MacroStartPos < 0:
+ continue
+ RetStr = ''
+ while MacroStartPos >= 0:
+ RetStr = String[0:MacroStartPos]
+ MacroEndPos = String.find(')', MacroStartPos)
+ if MacroEndPos < 0:
+ raise BadExpression(ERR_MACRO_TOKEN % String[MacroStartPos:])
+ Macro = String[MacroStartPos+2:MacroEndPos]
+ if Macro not in Macros:
+ # From C reference manual:
+ # If an undefined macro name appears in the constant-expression of
+ # !if or !elif, it is replaced by the integer constant 0.
+ RetStr += '0'
+ elif not InQuote and ExceptionList and Macro in ExceptionList:
+ # Make sure the macro in exception list is encapsulated by double quote
+ # For example: DEFINE ARCH = IA32 X64
+ # $(ARCH) is replaced with "IA32 X64"
+ RetStr += '"' + Macros[Macro] + '"'
+ else:
+ if Macros[Macro].strip() != "":
+ RetStr += Macros[Macro]
+ else:
+ RetStr += '""'
+ RetStr += String[MacroEndPos+1:]
+ String = RetStr
+ MacroStartPos = String.find('$(')
+ StrList[i] = RetStr
+ return ''.join(StrList)
+
+class ValueExpression(object):
+ # Logical operator mapping
+ LogicalOperators = {
+ '&&' : 'and', '||' : 'or',
+ '!' : 'not', 'AND': 'and',
+ 'OR' : 'or' , 'NOT': 'not',
+ 'XOR': '^' , 'xor': '^',
+ 'EQ' : '==' , 'NE' : '!=',
+ 'GT' : '>' , 'LT' : '<',
+ 'GE' : '>=' , 'LE' : '<=',
+ 'IN' : 'in'
+ }
+
+ NonLetterOpLst = ['+', '-', '&', '|', '^', '!', '=', '>', '<']
+
+ PcdPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]*$')
+ HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
+ RegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')
+
+ SymbolPattern = re.compile("("
+ "\$\([A-Z][A-Z0-9_]*\)|\$\(\w+\.\w+\)|\w+\.\w+|"
+ "&&|\|\||!(?!=)|"
+ "(?<=\W)AND(?=\W)|(?<=\W)OR(?=\W)|(?<=\W)NOT(?=\W)|(?<=\W)XOR(?=\W)|"
+ "(?<=\W)EQ(?=\W)|(?<=\W)NE(?=\W)|(?<=\W)GT(?=\W)|(?<=\W)LT(?=\W)|(?<=\W)GE(?=\W)|(?<=\W)LE(?=\W)"
+ ")")
+
+ @staticmethod
+ def Eval(Operator, Oprand1, Oprand2 = None):
+ WrnExp = None
+
+ if Operator not in ["==", "!=", ">=", "<=", ">", "<", "in", "not in"] and \
+ (type(Oprand1) == type('') or type(Oprand2) == type('')):
+ raise BadExpression(ERR_STRING_EXPR % Operator)
+
+ TypeDict = {
+ type(0) : 0,
+ type(0L) : 0,
+ type('') : 1,
+ type(True) : 2
+ }
+
+ EvalStr = ''
+ if Operator in ["!", "NOT", "not"]:
+ if type(Oprand1) == type(''):
+ raise BadExpression(ERR_STRING_EXPR % Operator)
+ EvalStr = 'not Oprand1'
+ else:
+ if Operator in ["+", "-"] and (type(True) in [type(Oprand1), type(Oprand2)]):
+ # Boolean in '+'/'-' will be evaluated but raise warning
+ WrnExp = WrnExpression(WRN_BOOL_EXPR)
+ elif type('') in [type(Oprand1), type(Oprand2)] and type(Oprand1)!= type(Oprand2):
+ # == between string and number/boolean will always return False, != return True
+ if Operator == "==":
+ WrnExp = WrnExpression(WRN_EQCMP_STR_OTHERS)
+ WrnExp.result = False
+ raise WrnExp
+ elif Operator == "!=":
+ WrnExp = WrnExpression(WRN_NECMP_STR_OTHERS)
+ WrnExp.result = True
+ raise WrnExp
+ else:
+ raise BadExpression(ERR_RELCMP_STR_OTHERS % Operator)
+ elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]:
+ if Operator in ["==", "!=", ">=", "<=", ">", "<"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
+ # comparison between number and boolean is allowed
+ pass
+ elif Operator in ['&', '|', '^', "&&", "||"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):
+ # bitwise and logical operation between number and boolean is allowed
+ pass
+ else:
+ raise BadExpression(ERR_EXPR_TYPE)
+ if type(Oprand1) == type('') and type(Oprand2) == type(''):
+ if (Oprand1.startswith('L"') and not Oprand2.startswith('L"')) or \
+ (not Oprand1.startswith('L"') and Oprand2.startswith('L"')):
+ raise BadExpression(ERR_STRING_CMP % (Oprand1, Operator, Oprand2))
+ if 'in' in Operator and type(Oprand2) == type(''):
+ Oprand2 = Oprand2.split()
+ EvalStr = 'Oprand1 ' + Operator + ' Oprand2'
+
+ # Local symbols used by built in eval function
+ Dict = {
+ 'Oprand1' : Oprand1,
+ 'Oprand2' : Oprand2
+ }
+ try:
+ Val = eval(EvalStr, {}, Dict)
+ except Exception, Excpt:
+ raise BadExpression(str(Excpt))
+
+ if Operator in ['and', 'or']:
+ if Val:
+ Val = True
+ else:
+ Val = False
+
+ if WrnExp:
+ WrnExp.result = Val
+ raise WrnExp
+ return Val
+
+ def __init__(self, Expression, SymbolTable={}):
+ self._NoProcess = False
+ if type(Expression) != type(''):
+ self._Expr = Expression
+ self._NoProcess = True
+ return
+
+ self._Expr = ReplaceExprMacro(Expression.strip(),
+ SymbolTable,
+ ['TARGET', 'TOOL_CHAIN_TAG', 'ARCH'])
+
+ if not self._Expr.strip():
+ self._NoProcess = True
+ return
+
+ #
+ # The symbol table including PCD and macro mapping
+ #
+ self._Symb = SymbolTable
+ self._Symb.update(self.LogicalOperators)
+ self._Idx = 0
+ self._Len = len(self._Expr)
+ self._Token = ''
+
+ # Literal token without any conversion
+ self._LiteralToken = ''
+
+ # Public entry for this class
+ def __call__(self):
+ if self._NoProcess:
+ return self._Expr
+
+ Val = self._OrExpr()
+ if type(Val) == type('') and Val == 'L""':
+ Val = ''
+
+ # The expression has been parsed, but the end of expression is not reached
+ # It means the rest does not comply EBNF of <Expression>
+ if self._Idx != self._Len:
+ raise BadExpression(ERR_SNYTAX % self._Expr[self._Idx:])
+
+ return Val
+
+ # Template function to parse binary operators which have same precedence
+ # Expr [Operator Expr]*
+ def _ExprFuncTemplate(self, EvalFunc, OpLst):
+ Val = EvalFunc()
+ while self._IsOperator(OpLst):
+ Op = self._Token
+ Val = self.Eval(Op, Val, EvalFunc())
+ return Val
+
+ # A [|| B]*
+ def _OrExpr(self):
+ return self._ExprFuncTemplate(self._AndExpr, ["OR", "or", "||"])
+
+ # A [&& B]*
+ def _AndExpr(self):
+ return self._ExprFuncTemplate(self._BitOr, ["AND", "and", "&&"])
+
+ # A [ | B]*
+ def _BitOr(self):
+ return self._ExprFuncTemplate(self._BitXor, ["|"])
+
+ # A [ ^ B]*
+ def _BitXor(self):
+ return self._ExprFuncTemplate(self._BitAnd, ["XOR", "xor", "^"])
+
+ # A [ & B]*
+ def _BitAnd(self):
+ return self._ExprFuncTemplate(self._EqExpr, ["&"])
+
+ # A [ == B]*
+ def _EqExpr(self):
+ Val = self._RelExpr()
+ while self._IsOperator(["==", "!=", "EQ", "NE", "IN", "in", "!", "NOT", "not"]):
+ Op = self._Token
+ if Op in ["!", "NOT", "not"]:
+ if not self._IsOperator(["IN", "in"]):
+ raise BadExpression(ERR_REL_NOT_IN)
+ Op += ' ' + self._Token
+ Val = self.Eval(Op, Val, self._RelExpr())
+ return Val
+
+ # A [ > B]*
+ def _RelExpr(self):
+ return self._ExprFuncTemplate(self._AddExpr, ["<=", ">=", "<", ">", "LE", "GE", "LT", "GT"])
+
+ # A [ + B]*
+ def _AddExpr(self):
+ return self._ExprFuncTemplate(self._UnaryExpr, ["+", "-"])
+
+ # [!]*A
+ def _UnaryExpr(self):
+ if self._IsOperator(["!", "NOT", "not"]):
+ Val = self._UnaryExpr()
+ return self.Eval('not', Val)
+ return self._IdenExpr()
+
+ # Parse identifier or encapsulated expression
+ def _IdenExpr(self):
+ Tk = self._GetToken()
+ if Tk == '(':
+ Val = self._OrExpr()
+ try:
+ # _GetToken may also raise BadExpression
+ if self._GetToken() != ')':
+ raise BadExpression(ERR_MATCH)
+ except BadExpression:
+ raise BadExpression(ERR_MATCH)
+ return Val
+ return Tk
+
+ # Skip whitespace or tab
+ def __SkipWS(self):
+ for Char in self._Expr[self._Idx:]:
+ if Char not in ' \t':
+ break
+ self._Idx += 1
+
+ # Try to convert string to number
+ def __IsNumberToken(self):
+ Radix = 10
+ if self._Token.lower()[0:2] == '0x' and len(self._Token) > 2:
+ Radix = 16
+ try:
+ self._Token = int(self._Token, Radix)
+ return True
+ except ValueError:
+ return False
+ except TypeError:
+ return False
+
+ # Parse array: {...}
+ def __GetArray(self):
+ Token = '{'
+ self._Idx += 1
+ self.__GetNList(True)
+ Token += self._LiteralToken
+ if self._Idx >= self._Len or self._Expr[self._Idx] != '}':
+ raise BadExpression(ERR_ARRAY_TOKEN % Token)
+ Token += '}'
+
+ # All whitespace and tabs in array are already stripped.
+ IsArray = IsGuid = False
+ if len(Token.split(',')) == 11 and len(Token.split(',{')) == 2 \
+ and len(Token.split('},')) == 1:
+ HexLen = [11,6,6,5,4,4,4,4,4,4,6]
+ HexList= Token.split(',')
+ if HexList[3].startswith('{') and \
+ not [Index for Index, Hex in enumerate(HexList) if len(Hex) > HexLen[Index]]:
+ IsGuid = True
+ if Token.lstrip('{').rstrip('}').find('{') == -1:
+ if not [Hex for Hex in Token.lstrip('{').rstrip('}').split(',') if len(Hex) > 4]:
+ IsArray = True
+ if not IsArray and not IsGuid:
+ raise BadExpression(ERR_ARRAY_TOKEN % Token)
+ self._Idx += 1
+ self._Token = self._LiteralToken = Token
+ return self._Token
+
+ # Parse string, the format must be: "..."
+ def __GetString(self):
+ Idx = self._Idx
+
+ # Skip left quote
+ self._Idx += 1
+
+ # Replace escape \\\", \"
+ Expr = self._Expr[self._Idx:].replace('\\\\', '//').replace('\\\"', '\\\'')
+ for Ch in Expr:
+ self._Idx += 1
+ if Ch == '"':
+ break
+ self._Token = self._LiteralToken = self._Expr[Idx:self._Idx]
+ if not self._Token.endswith('"'):
+ raise BadExpression(ERR_STRING_TOKEN % self._Token)
+ self._Token = self._Token[1:-1]
+ return self._Token
+
+ # Get token that is comprised by alphanumeric, underscore or dot(used by PCD)
+ # @param IsAlphaOp: Indicate if parsing general token or script operator(EQ, NE...)
+ def __GetIdToken(self, IsAlphaOp = False):
+ IdToken = ''
+ for Ch in self._Expr[self._Idx:]:
+ if not self.__IsIdChar(Ch):
+ break
+ self._Idx += 1
+ IdToken += Ch
+
+ self._Token = self._LiteralToken = IdToken
+ if not IsAlphaOp:
+ self.__ResolveToken()
+ return self._Token
+
+ # Try to resolve token
+ def __ResolveToken(self):
+ if not self._Token:
+ raise BadExpression(ERR_EMPTY_TOKEN)
+
+ # PCD token
+ if self.PcdPattern.match(self._Token):
+ if self._Token not in self._Symb:
+ raise SymbolNotFound(ERR_PCD_RESOLVE % self._Token)
+ self._Token = ValueExpression(self._Symb[self._Token], self._Symb)()
+ if type(self._Token) != type(''):
+ self._LiteralToken = hex(self._Token)
+ return
+
+ if self._Token.startswith('"'):
+ self._Token = self._Token[1:-1]
+ elif self._Token in ["FALSE", "false", "False"]:
+ self._Token = False
+ elif self._Token in ["TRUE", "true", "True"]:
+ self._Token = True
+ else:
+ self.__IsNumberToken()
+
+ def __GetNList(self, InArray=False):
+ self._GetSingleToken()
+ if not self.__IsHexLiteral():
+ if InArray:
+ raise BadExpression(ERR_ARRAY_ELE % self._Token)
+ return self._Token
+
+ self.__SkipWS()
+ Expr = self._Expr[self._Idx:]
+ if not Expr.startswith(','):
+ return self._Token
+
+ NList = self._LiteralToken
+ while Expr.startswith(','):
+ NList += ','
+ self._Idx += 1
+ self.__SkipWS()
+ self._GetSingleToken()
+ if not self.__IsHexLiteral():
+ raise BadExpression(ERR_ARRAY_ELE % self._Token)
+ NList += self._LiteralToken
+ self.__SkipWS()
+ Expr = self._Expr[self._Idx:]
+ self._Token = self._LiteralToken = NList
+ return self._Token
+
+ def __IsHexLiteral(self):
+ if self._LiteralToken.startswith('{') and \
+ self._LiteralToken.endswith('}'):
+ return True
+
+ if self.HexPattern.match(self._LiteralToken):
+ Token = self._LiteralToken[2:]
+ Token = Token.lstrip('0')
+ if not Token:
+ self._LiteralToken = '0x0'
+ else:
+ self._LiteralToken = '0x' + Token
+ return True
+ return False
+
+ def _GetToken(self):
+ return self.__GetNList()
+
+ @staticmethod
+ def __IsIdChar(Ch):
+ return Ch in '._/:' or Ch.isalnum()
+
+ # Parse operand
+ def _GetSingleToken(self):
+ self.__SkipWS()
+ Expr = self._Expr[self._Idx:]
+ if Expr.startswith('L"'):
+ # Skip L
+ self._Idx += 1
+ UStr = self.__GetString()
+ self._Token = 'L"' + UStr + '"'
+ return self._Token
+
+ self._Token = ''
+ if Expr:
+ Ch = Expr[0]
+ Match = self.RegGuidPattern.match(Expr)
+ if Match and not Expr[Match.end():Match.end()+1].isalnum() \
+ and Expr[Match.end():Match.end()+1] != '_':
+ self._Idx += Match.end()
+ self._Token = ValueExpression(GuidStringToGuidStructureString(Expr[0:Match.end()]))()
+ return self._Token
+ elif self.__IsIdChar(Ch):
+ return self.__GetIdToken()
+ elif Ch == '"':
+ return self.__GetString()
+ elif Ch == '{':
+ return self.__GetArray()
+ elif Ch == '(' or Ch == ')':
+ self._Idx += 1
+ self._Token = Ch
+ return self._Token
+
+ raise BadExpression(ERR_VALID_TOKEN % Expr)
+
+ # Parse operator
+ def _GetOperator(self):
+ self.__SkipWS()
+ LegalOpLst = ['&&', '||', '!=', '==', '>=', '<='] + self.NonLetterOpLst
+
+ self._Token = ''
+ Expr = self._Expr[self._Idx:]
+
+ # Reach end of expression
+ if not Expr:
+ return ''
+
+ # Script operator: LT, GT, LE, GE, EQ, NE, and, or, xor, not
+ if Expr[0].isalpha():
+ return self.__GetIdToken(True)
+
+ # Start to get regular operator: +, -, <, > ...
+ if Expr[0] not in self.NonLetterOpLst:
+ return ''
+
+ OpToken = ''
+ for Ch in Expr:
+ if Ch in self.NonLetterOpLst:
+ if '!' == Ch and OpToken in ['!=', '!']:
+ break
+ self._Idx += 1
+ OpToken += Ch
+ else:
+ break
+
+ if OpToken not in LegalOpLst:
+ raise BadExpression(ERR_OPERATOR_UNSUPPORT % OpToken)
+ self._Token = OpToken
+ return OpToken
+
+ # Check if current token matches the operators given from OpList
+ def _IsOperator(self, OpList):
+ Idx = self._Idx
+ self._GetOperator()
+ if self._Token in OpList:
+ if self._Token in self.LogicalOperators:
+ self._Token = self.LogicalOperators[self._Token]
+ return True
+ self._Idx = Idx
+ return False
+
+if __name__ == '__main__':
+ pass
+
+
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py
index 37ae2d33eb..bc7e047676 100644
--- a/BaseTools/Source/Python/Common/GlobalData.py
+++ b/BaseTools/Source/Python/Common/GlobalData.py
@@ -22,9 +22,11 @@ gEcpSource = "EdkCompatibilityPkg"
gOptions = None
gCaseInsensitive = False
-gGlobalDefines = {}
gAllFiles = None
+gGlobalDefines = {}
+gPlatformDefines = {}
+gCommandLineDefines = {}
gEdkGlobal = {}
gOverrideDir = {}
@@ -33,8 +35,13 @@ gProcessingFile = ''
gBuildingModule = ''
## Regular expression for matching macro used in DSC/DEC/INF file inclusion
-gMacroPattern = re.compile("\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE)
+gMacroRefPattern = re.compile("\$\(([A-Z][_A-Z0-9]*)\)", re.UNICODE)
+gMacroDefPattern = re.compile("^(DEFINE|EDK_GLOBAL)[ \t]+")
+gMacroNamePattern = re.compile("^[A-Z][A-Z0-9_]*$")
+# C-style wide string pattern
+gWideStringPattern = re.compile('(\W|\A)L"')
#
# A global variable for whether current build in AutoGen phase or not.
#
gAutoGenPhase = False
+
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 731bbf1458..50504aa73c 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -156,7 +156,7 @@ def GuidStructureStringToGuidValueName(GuidValue):
guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "")
guidValueList = guidValueString.split(",")
if len(guidValueList) != 11:
- EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
+ EdkLogger.error(None, FORMAT_INVALID, "Invalid GUID value string [%s]" % GuidValue)
return "%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x" % (
int(guidValueList[0], 16),
int(guidValueList[1], 16),
@@ -1431,6 +1431,9 @@ class PathClass(object):
self._Key = self.Path.upper() # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target
return self._Key
+ def _GetTimeStamp(self):
+ return os.stat(self.Path)[8]
+
def Validate(self, Type='', CaseSensitive=True):
if GlobalData.gCaseInsensitive:
CaseSensitive = False
@@ -1465,6 +1468,7 @@ class PathClass(object):
return ErrorCode, ErrorInfo
Key = property(_GetFileKey)
+ TimeStamp = property(_GetTimeStamp)
## Parse PE image to get the required PE informaion.
#
@@ -1482,7 +1486,7 @@ class PeImageClass():
self.SectionHeaderList = []
self.ErrorInfo = ''
try:
- PeObject = open(PeFile, 'rb')
+ PeObject = open(PeFile, 'rb')
except:
self.ErrorInfo = self.FileName + ' can not be found\n'
return
diff --git a/BaseTools/Source/Python/Common/String.py b/BaseTools/Source/Python/Common/String.py
index 4880768866..a35f728dc0 100644
--- a/BaseTools/Source/Python/Common/String.py
+++ b/BaseTools/Source/Python/Common/String.py
@@ -22,6 +22,7 @@ import EdkLogger as EdkLogger
import GlobalData
from BuildToolError import *
+from CommonDataClass.Exceptions import *
gHexVerPatt = re.compile('0x[a-f0-9]{4}[a-f0-9]{4}$',re.IGNORECASE)
gHumanReadableVerPatt = re.compile(r'([1-9][0-9]*|0)\.[0-9]{1,2}$')
@@ -39,7 +40,52 @@ gHumanReadableVerPatt = re.compile(r'([1-9][0-9]*|0)\.[0-9]{1,2}$')
# @retval list() A list for splitted string
#
def GetSplitValueList(String, SplitTag = DataType.TAB_VALUE_SPLIT, MaxSplit = -1):
- return map(lambda l: l.strip(), String.split(SplitTag, MaxSplit))
+ ValueList = []
+ Last = 0
+ Escaped = False
+ InString = False
+ for Index in range(0, len(String)):
+ Char = String[Index]
+
+ if not Escaped:
+ # Found a splitter not in a string, split it
+ if not InString and Char == SplitTag:
+ ValueList.append(String[Last:Index].strip())
+ Last = Index+1
+ if MaxSplit > 0 and len(ValueList) >= MaxSplit:
+ break
+
+ if Char == '\\' and InString:
+ Escaped = True
+ elif Char == '"':
+ if not InString:
+ InString = True
+ else:
+ InString = False
+ else:
+ Escaped = False
+
+ if Last < len(String):
+ ValueList.append(String[Last:].strip())
+ elif Last == len(String):
+ ValueList.append('')
+
+ return ValueList
+
+## GetSplitList
+#
+# Get a value list from a string with multiple values splited with SplitString
+# The default SplitTag is DataType.TAB_VALUE_SPLIT
+# 'AAA|BBB|CCC' -> ['AAA', 'BBB', 'CCC']
+#
+# @param String: The input string to be splitted
+# @param SplitStr: The split key, default is DataType.TAB_VALUE_SPLIT
+# @param MaxSplit: The max number of split values, default is -1
+#
+# @retval list() A list for splitted string
+#
+def GetSplitList(String, SplitStr = DataType.TAB_VALUE_SPLIT, MaxSplit = -1):
+ return map(lambda l: l.strip(), String.split(SplitStr, MaxSplit))
## MergeArches
#
@@ -210,16 +256,18 @@ def ReplaceMacros(StringList, MacroDefinitions={}, SelfReplacement = False):
#
# @retval string The string whose macros are replaced
#
-def ReplaceMacro(String, MacroDefinitions={}, SelfReplacement = False):
+def ReplaceMacro(String, MacroDefinitions={}, SelfReplacement=False, RaiseError=False):
LastString = String
- while MacroDefinitions:
- MacroUsed = GlobalData.gMacroPattern.findall(String)
+ while String and MacroDefinitions:
+ MacroUsed = GlobalData.gMacroRefPattern.findall(String)
# no macro found in String, stop replacing
if len(MacroUsed) == 0:
break
for Macro in MacroUsed:
if Macro not in MacroDefinitions:
+ if RaiseError:
+ raise SymbolNotFound("%s not defined" % Macro)
if SelfReplacement:
String = String.replace("$(%s)" % Macro, '')
continue
diff --git a/BaseTools/Source/Python/CommonDataClass/DataClass.py b/BaseTools/Source/Python/CommonDataClass/DataClass.py
index ebb0358b0b..3d971c84cd 100644
--- a/BaseTools/Source/Python/CommonDataClass/DataClass.py
+++ b/BaseTools/Source/Python/CommonDataClass/DataClass.py
@@ -89,11 +89,13 @@ MODEL_META_DATA_COMPONENT = 5009
MODEL_META_DATA_USER_EXTENSION = 5010
MODEL_META_DATA_PACKAGE = 5011
MODEL_META_DATA_NMAKE = 5012
-MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF = 50013
+MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF = 5013
MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF = 5014
MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH = 5015
MODEL_META_DATA_COMMENT = 5016
MODEL_META_DATA_GLOBAL_DEFINE = 5017
+MODEL_META_DATA_SECTION_HEADER = 5100
+MODEL_META_DATA_SUBSECTION_HEADER = 5200
MODEL_EXTERNAL_DEPENDENCY = 10000
diff --git a/BaseTools/Source/Python/CommonDataClass/Exceptions.py b/BaseTools/Source/Python/CommonDataClass/Exceptions.py
new file mode 100644
index 0000000000..50541e80f2
--- /dev/null
+++ b/BaseTools/Source/Python/CommonDataClass/Exceptions.py
@@ -0,0 +1,29 @@
+## @file
+# This file is used to define common Exceptions class used in python tools
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+## Exceptions used in Expression
+class EvaluationException(Exception):
+ pass
+
+class BadExpression(EvaluationException):
+ pass
+
+class WrnExpression(Exception):
+ pass
+
+## Exceptions used in macro replacements
+class MacroException(Exception):
+ pass
+
+class SymbolNotFound(MacroException):
+ pass
+
diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py
index bb40d756c8..a6dace82a6 100644
--- a/BaseTools/Source/Python/GenFds/AprioriSection.py
+++ b/BaseTools/Source/Python/GenFds/AprioriSection.py
@@ -79,11 +79,11 @@ class AprioriSection (AprioriSectionClassObject):
InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch)
if Arch != None:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch]
+ Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
Guid = Inf.Guid
else:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON']
+ Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
Guid = Inf.Guid
self.BinFileList = Inf.Module.Binaries
diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py
index 39678b23e9..b7b1ae7d93 100644
--- a/BaseTools/Source/Python/GenFds/DepexSection.py
+++ b/BaseTools/Source/Python/GenFds/DepexSection.py
@@ -39,7 +39,10 @@ class DepexSection (DepexSectionClassObject):
def __FindGuidValue(self, CName):
for Arch in GenFdsGlobalVariable.ArchList:
- for PkgDb in GenFdsGlobalVariable.WorkSpace.PackageList:
+ for PkgDb in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
+ Arch,
+ GenFdsGlobalVariable.TargetName,
+ GenFdsGlobalVariable.ToolChainTag):
if CName in PkgDb.Ppis:
return PkgDb.Ppis[CName]
if CName in PkgDb.Protocols:
diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py
index cbfd6715ca..aa4d2e8262 100644
--- a/BaseTools/Source/Python/GenFds/Fd.py
+++ b/BaseTools/Source/Python/GenFds/Fd.py
@@ -71,11 +71,11 @@ class FD(FDClassObject):
for RegionObj in self.RegionList :
if RegionObj.RegionType == 'CAPSULE':
- continue
+ continue
if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
- pass
+ pass
elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
- pass
+ pass
elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
PadRegion = Region.Region()
@@ -88,7 +88,7 @@ class FD(FDClassObject):
# Call each region's AddToBuffer function
#
if PreviousRegionSize > self.Size:
- pass
+ pass
GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 4f555e32bb..e3a018c66c 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -15,6 +15,8 @@
##
# Import Modules
#
+import re
+
import Fd
import Region
import Fv
@@ -45,6 +47,8 @@ from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import PathClass
from Common.String import NormPath
+import Common.GlobalData as GlobalData
+from Common.Expression import *
from Common import GlobalData
import re
@@ -68,6 +72,9 @@ T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_
SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
+RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
+RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
+
IncludeFileList = []
# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
InputMacroDict = {}
@@ -211,6 +218,10 @@ class FdfParser:
if GenFdsGlobalVariable.WorkSpaceDir == '':
GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
+ InputMacroDict.update(GlobalData.gPlatformDefines)
+ InputMacroDict.update(GlobalData.gGlobalDefines)
+ InputMacroDict.update(GlobalData.gCommandLineDefines)
+
## __IsWhiteSpace() method
#
# Whether char at current FileBufferPos is whitespace
@@ -317,10 +328,10 @@ class FdfParser:
#
def __GetOneChar(self):
if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
- self.CurrentLineNumber += 1
- self.CurrentOffsetWithinLine = 0
+ self.CurrentLineNumber += 1
+ self.CurrentOffsetWithinLine = 0
else:
- self.CurrentOffsetWithinLine += 1
+ self.CurrentOffsetWithinLine += 1
## __CurrentChar() method
#
@@ -564,7 +575,7 @@ class FdfParser:
self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
self.Rewind()
-
+
def __GetIfListCurrentItemStat(self, IfList):
if len(IfList) == 0:
return True
@@ -574,8 +585,7 @@ class FdfParser:
return False
return True
-
-
+
## PreprocessConditionalStatement() method
#
# Preprocess conditional statement.
@@ -586,9 +596,10 @@ class FdfParser:
def PreprocessConditionalStatement(self):
# IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
IfList = []
+ RegionLayoutLine = 0
while self.__GetNextToken():
if self.__Token == 'DEFINE':
- if self.__GetIfListCurrentItemStat(IfList):
+ if self.__GetIfListCurrentItemStat(IfList):
DefineLine = self.CurrentLineNumber - 1
DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
if not self.__GetNextToken():
@@ -609,60 +620,48 @@ class FdfParser:
MacProfile.MacroName = Macro
MacProfile.MacroValue = Value
AllMacroList.append(MacProfile)
+ InputMacroDict[MacProfile.MacroName] = MacProfile.MacroValue
self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
+ elif self.__Token == 'SET':
+ PcdPair = self.__GetNextPcdName()
+ PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+ if not self.__GetNextToken():
+ raise Warning("expected value", self.FileName, self.CurrentLineNumber)
+
+ Value = self.__Token
+ if Value.startswith("{"):
+ # deal with value with {}
+ if not self.__SkipToToken( "}"):
+ raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
+ Value += self.__SkippedChars
+
+ InputMacroDict[PcdName] = Value
elif self.__Token in ('!ifdef', '!ifndef', '!if'):
IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
IfList.append([IfStartPos, None, None])
+
CondLabel = self.__Token
+ Expression = self.__GetExpression()
- MacroName, NotFlag = self.__GetMacroName()
- NotDefineFlag = False
- if CondLabel == '!ifndef':
- NotDefineFlag = True
- if CondLabel == '!ifdef' or CondLabel == '!ifndef':
- if NotFlag:
- raise Warning("'NOT' operation not allowed for Macro name", self.FileName, self.CurrentLineNumber)
-
if CondLabel == '!if':
-
- if not self.__GetNextOp():
- raise Warning("expected !endif", self.FileName, self.CurrentLineNumber)
-
- if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
- Op = self.__Token
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
- if self.__GetStringData():
- pass
- MacroValue = self.__Token
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
- BranchDetermined = ConditionSatisfied
- else:
- self.CurrentOffsetWithinLine -= len(self.__Token)
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
- BranchDetermined = ConditionSatisfied
- IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
- if ConditionSatisfied:
- self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
-
+ ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
else:
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1)
- if NotDefineFlag:
+ ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
+ if CondLabel == '!ifndef':
ConditionSatisfied = not ConditionSatisfied
- BranchDetermined = ConditionSatisfied
- IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
- if ConditionSatisfied:
- self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
+ BranchDetermined = ConditionSatisfied
+ IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
+ if ConditionSatisfied:
+ self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
elif self.__Token in ('!elseif', '!else'):
ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
if len(IfList) <= 0:
raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
+
if IfList[-1][1]:
IfList[-1] = [ElseStartPos, False, True]
self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
@@ -670,27 +669,8 @@ class FdfParser:
self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
if self.__Token == '!elseif':
- MacroName, NotFlag = self.__GetMacroName()
- if not self.__GetNextOp():
- raise Warning("expected !endif", self.FileName, self.CurrentLineNumber)
-
- if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
- Op = self.__Token
- if not self.__GetNextToken():
- raise Warning("expected value", self.FileName, self.CurrentLineNumber)
- if self.__GetStringData():
- pass
- MacroValue = self.__Token
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
-
- else:
- self.CurrentOffsetWithinLine -= len(self.__Token)
- ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
- if NotFlag:
- ConditionSatisfied = not ConditionSatisfied
-
+ Expression = self.__GetExpression()
+ ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
if IfList[-1][1]:
@@ -699,8 +679,6 @@ class FdfParser:
else:
IfList[-1][2] = True
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
-
-
elif self.__Token == '!endif':
if IfList[-1][1]:
self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
@@ -708,106 +686,48 @@ class FdfParser:
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
IfList.pop()
+ elif not IfList: # Don't use PCDs inside conditional directive
+ if self.CurrentLineNumber <= RegionLayoutLine:
+ # Don't try the same line twice
+ continue
+ RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
+ if not RegionSize:
+ RegionLayoutLine = self.CurrentLineNumber
+ continue
+ RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
+ if not RegionSizeGuid:
+ RegionLayoutLine = self.CurrentLineNumber + 1
+ continue
+ InputMacroDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
+ InputMacroDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
+ RegionLayoutLine = self.CurrentLineNumber + 1
-
- if len(IfList) > 0:
+ if IfList:
raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
self.Rewind()
- def __EvaluateConditional(self, Name, Line, Op = None, Value = None):
-
+ def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):
FileLineTuple = GetRealFileLine(self.FileName, Line)
- if Name in InputMacroDict:
- MacroValue = InputMacroDict[Name]
- if Op == None:
- if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE':
- return False
- return True
- elif Op == '!=':
- if Value != MacroValue:
- return True
- else:
- return False
- elif Op == '==':
- if Value == MacroValue:
- return True
- else:
- return False
- else:
- if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())):
- InputVal = long(Value, 0)
- MacroVal = long(MacroValue, 0)
- if Op == '>':
- if MacroVal > InputVal:
- return True
- else:
- return False
- elif Op == '>=':
- if MacroVal >= InputVal:
- return True
- else:
- return False
- elif Op == '<':
- if MacroVal < InputVal:
- return True
- else:
- return False
- elif Op == '<=':
- if MacroVal <= InputVal:
- return True
- else:
- return False
- else:
- return False
- else:
- raise Warning("Value %s is not a number", self.FileName, Line)
-
- for Profile in AllMacroList:
- if Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]:
- if Op == None:
- if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE':
- return False
- return True
- elif Op == '!=':
- if Value != Profile.MacroValue:
- return True
- else:
- return False
- elif Op == '==':
- if Value == Profile.MacroValue:
- return True
- else:
- return False
- else:
- if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())):
- InputVal = long(Value, 0)
- MacroVal = long(Profile.MacroValue, 0)
- if Op == '>':
- if MacroVal > InputVal:
- return True
- else:
- return False
- elif Op == '>=':
- if MacroVal >= InputVal:
- return True
- else:
- return False
- elif Op == '<':
- if MacroVal < InputVal:
- return True
- else:
- return False
- elif Op == '<=':
- if MacroVal <= InputVal:
- return True
- else:
- return False
- else:
- return False
- else:
- raise Warning("Value %s is not a number", self.FileName, Line)
-
- return False
+ if Op == 'eval':
+ try:
+ return ValueExpression(Expression, InputMacroDict)()
+ except SymbolNotFound:
+ return False
+ except WrnExpression, Excpt:
+ #
+ # Catch expression evaluation warning here. We need to report
+ # the precise number of line and return the evaluation result
+ #
+ EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
+ File=self.FileName, ExtraData=self.__CurrentLine(),
+ Line=Line)
+ return Excpt.result
+ except Exception, Excpt:
+ raise Warning("Invalid expression", *FileLineTuple)
+ else:
+ if Expression.startswith('$(') and Expression[-1] == ')':
+ Expression = Expression[2:-1]
+ return Expression in InputMacroDict
## __IsToken() method
#
@@ -866,6 +786,16 @@ class FdfParser:
return True
return False
+ def __GetExpression(self):
+ Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
+ Index = len(Line) - 1
+ while Line[Index] in ['\r', '\n']:
+ Index -= 1
+ ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
+ self.CurrentOffsetWithinLine += len(ExpressionString)
+ ExpressionString = ExpressionString.strip()
+ return ExpressionString
+
## __GetNextWord() method
#
# Get next C name from file lines
@@ -1208,7 +1138,7 @@ class FdfParser:
for Pos in self.__WipeOffArea:
self.__ReplaceFragment(Pos[0], Pos[1])
self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
-
+
while self.__GetDefines():
pass
@@ -2014,8 +1944,8 @@ class FdfParser:
if not IsValidBaseAddrValue.match(self.__Token.upper()):
raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
Obj.FvBaseAddress = self.__Token
- return True
-
+ return True
+
## __GetFvForceRebase() method
#
# Get FvForceRebase for FV
@@ -2047,7 +1977,8 @@ class FdfParser:
Obj.FvForceRebase = None
return True
-
+
+
## __GetFvAttributes() method
#
# Get attributes for FV
@@ -2475,6 +2406,7 @@ class FdfParser:
if ErrorCode != 0:
EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
+
if not self.__IsToken( "}"):
raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
index b858549361..04527fe00f 100644
--- a/BaseTools/Source/Python/GenFds/FfsFileStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
@@ -71,7 +71,7 @@ class FileStatement (FileStatementClassObject) :
OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid)
if not os.path.exists(OutputDir):
- os.makedirs(OutputDir)
+ os.makedirs(OutputDir)
Dict.update(self.DefineVarDict)
SectionAlignments = None
@@ -98,7 +98,7 @@ class FileStatement (FileStatementClassObject) :
SectionFiles = []
Index = 0
SectionAlignments = []
- for section in self.SectionList:
+ for section in self.SectionList :
Index = Index + 1
SecIndex = '%d' %Index
# process the inside FvImage from FvSection or GuidSection
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
index c6f29f6ddd..96e212cae7 100644
--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
@@ -163,7 +163,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
if self.CurrentArch != None:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch]
+ Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
#
# Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
#
@@ -181,7 +181,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.ShadowFromInfFile = Inf.Shadow
else:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON']
+ Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
self.BaseName = Inf.BaseName
self.ModuleGuid = Inf.Guid
self.ModuleType = Inf.ModuleType
@@ -363,27 +363,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
DscArchList = []
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32']
+ PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
if PlatformDataBase != None:
if InfFileKey in PlatformDataBase.Modules:
DscArchList.append ('IA32')
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64']
+ PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
if PlatformDataBase != None:
if InfFileKey in PlatformDataBase.Modules:
DscArchList.append ('X64')
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF']
+ PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
if PlatformDataBase != None:
if InfFileKey in (PlatformDataBase.Modules):
DscArchList.append ('IPF')
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM']
+ PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
if PlatformDataBase != None:
if InfFileKey in (PlatformDataBase.Modules):
DscArchList.append ('ARM')
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC']
+ PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
if PlatformDataBase != None:
if InfFileKey in (PlatformDataBase.Modules):
DscArchList.append ('EBC')
diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py
index f186ab0e73..fd5ad0e9ac 100644
--- a/BaseTools/Source/Python/GenFds/Fv.py
+++ b/BaseTools/Source/Python/GenFds/Fv.py
@@ -48,7 +48,7 @@ class FV (FvClassObject):
self.CapsuleName = None
self.FvBaseAddress = None
self.FvForceRebase = None
-
+
## AddToBuffer()
#
# Generate Fv and add it to the Buffer
@@ -83,13 +83,13 @@ class FV (FvClassObject):
elif RegionData.upper() + 'fv' in GenFds.ImageBinDict.keys():
continue
elif self.UiFvName.upper() == RegionData.upper():
- GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
+ GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
if self.FvBaseAddress != None:
- BaseAddress = self.FvBaseAddress
-
+ BaseAddress = self.FvBaseAddress
+
self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
#
# First Process the Apriori section
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index cadd36c922..0219783b03 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -161,20 +161,22 @@ def main():
if len(List) == 2:
if List[0].strip() == "EFI_SOURCE":
GlobalData.gEfiSource = List[1].strip()
+ GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource
continue
elif List[0].strip() == "EDK_SOURCE":
GlobalData.gEdkSource = List[1].strip()
+ GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource
continue
+ elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:
+ GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()
else:
- GlobalData.gEdkGlobal[List[0].strip()] = List[1].strip()
- FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()
+ GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()
else:
- FdfParser.InputMacroDict[List[0].strip()] = ""
+ GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"
+ os.environ["WORKSPACE"] = Workspace
"""call Workspace build create database"""
- os.environ["WORKSPACE"] = Workspace
- FdfParser.InputMacroDict["WORKSPACE"] = Workspace
- BuildWorkSpace = WorkspaceDatabase(':memory:', FdfParser.InputMacroDict)
+ BuildWorkSpace = WorkspaceDatabase(None)
BuildWorkSpace.InitDatabase()
#
@@ -187,15 +189,15 @@ def main():
ArchList = Options.archList.split(',')
else:
# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")
- ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList
+ ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList
- TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList) & set(ArchList)
+ TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)
if len(TargetArchList) == 0:
EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))
for Arch in ArchList:
- GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].OutputDirectory)
- GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].PlatformName
+ GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)
+ GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName
if (Options.outputDir):
OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)
@@ -276,7 +278,8 @@ def main():
ExtraData="Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!\n",
RaiseError=False
)
- EdkLogger.quiet(traceback.format_exc())
+ if Options.debug != None:
+ EdkLogger.quiet(traceback.format_exc())
ReturnCode = CODE_ERROR
return ReturnCode
@@ -482,7 +485,7 @@ class GenFds :
# @retval None
#
def PreprocessImage(BuildDb, DscFile):
- PcdDict = BuildDb.BuildObject[DscFile, 'COMMON'].Pcds
+ PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds
PcdValue = ''
for Key in PcdDict:
PcdObj = PcdDict[Key]
@@ -501,20 +504,20 @@ class GenFds :
if Int64PcdValue > 0:
TopAddress = Int64PcdValue
- ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON'].Modules
+ ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules
for Key in ModuleDict:
- ModuleObj = BuildDb.BuildObject[Key, 'COMMON']
+ ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType
def GenerateGuidXRefFile(BuildDb, ArchList):
GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")
GuidXRefFile = StringIO.StringIO('')
for Arch in ArchList:
- PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch]
+ PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
for ModuleFile in PlatformDataBase.Modules:
- Module = BuildDb.BuildObject[ModuleFile, Arch]
+ Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))
- SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)
+ SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)
GuidXRefFile.close()
GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index 236283751e..ea6b191bc1 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -117,7 +117,7 @@ class GenFdsGlobalVariable:
if not BuildRuleDatabase:
return {}
- PathClassObj = PathClass(str(Inf.MetaFile).lstrip(GenFdsGlobalVariable.WorkSpaceDir),
+ PathClassObj = PathClass(Inf.MetaFile.File,
GenFdsGlobalVariable.WorkSpaceDir)
Macro = {}
Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir
@@ -135,6 +135,7 @@ class GenFdsGlobalVariable:
Macro["ARCH" ] = Arch
Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag
Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
+ Macro["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
Macro["TARGET" ] = GenFdsGlobalVariable.TargetName
Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch]
@@ -280,8 +281,8 @@ class GenFdsGlobalVariable:
FvAddressFile.writelines("[options]" + T_CHAR_LF)
BsAddress = '0'
for Arch in ArchList:
- if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress:
- BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress
+ if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
+ BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
break
FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
@@ -290,8 +291,8 @@ class GenFdsGlobalVariable:
RtAddress = '0'
for Arch in ArchList:
- if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress:
- RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress
+ if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:
+ RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress
FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
RtAddress + \
@@ -345,10 +346,6 @@ class GenFdsGlobalVariable:
@staticmethod
def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None):
- if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
- return
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
Cmd = ["GenSec"]
if Type not in [None, '']:
Cmd += ["-s", Type]
@@ -388,6 +385,13 @@ class GenFdsGlobalVariable:
else:
Cmd += ["-o", Output]
Cmd += Input
+
+ CommandFile = Output + '.txt'
+ SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
+ if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
+ return
+ GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
+
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
@staticmethod
@@ -402,10 +406,6 @@ class GenFdsGlobalVariable:
@staticmethod
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
SectionAlign=None):
- if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
- return
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
Cmd = ["GenFfs", "-t", Type, "-g", Guid]
if Fixed == True:
Cmd += ["-x"]
@@ -419,6 +419,13 @@ class GenFdsGlobalVariable:
Cmd += ("-i", Input[I])
if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
Cmd += ("-n", SectionAlign[I])
+
+ CommandFile = Output + '.txt'
+ SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
+ if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
+ return
+ GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
+
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
@staticmethod
@@ -436,7 +443,7 @@ class GenFdsGlobalVariable:
Cmd +=["-F", "FALSE"]
elif ForceRebase == True:
Cmd +=["-F", "TRUE"]
-
+
if Capsule:
Cmd += ["-c"]
if Dump:
@@ -653,25 +660,9 @@ class GenFdsGlobalVariable:
TokenCName = PcdPair[1]
PcdValue = ''
- for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList:
- #
- # Only process platform which match current build option.
- #
- if Platform.MetaFile == GenFdsGlobalVariable.ActivePlatform:
- PcdDict = Platform.Pcds
- for Key in PcdDict:
- PcdObj = PcdDict[Key]
- if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
- if PcdObj.Type != 'FixedAtBuild':
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
- if PcdObj.DatumType != 'VOID*':
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
-
- PcdValue = PcdObj.DefaultValue
- return PcdValue
-
- for Package in GenFdsGlobalVariable.WorkSpace.PackageList:
- PcdDict = Package.Pcds
+ for Arch in GenFdsGlobalVariable.ArchList:
+ Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
+ PcdDict = Platform.Pcds
for Key in PcdDict:
PcdObj = PcdDict[Key]
if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
@@ -682,6 +673,22 @@ class GenFdsGlobalVariable:
PcdValue = PcdObj.DefaultValue
return PcdValue
+
+ for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
+ Arch,
+ GenFdsGlobalVariable.TargetName,
+ GenFdsGlobalVariable.ToolChainTag):
+ PcdDict = Package.Pcds
+ for Key in PcdDict:
+ PcdObj = PcdDict[Key]
+ if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
+ if PcdObj.Type != 'FixedAtBuild':
+ EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
+ if PcdObj.DatumType != 'VOID*':
+ EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
+
+ PcdValue = PcdObj.DefaultValue
+ return PcdValue
return PcdValue
diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py
index ef9720a660..6f57ad5681 100644
--- a/BaseTools/Source/Python/GenFds/Section.py
+++ b/BaseTools/Source/Python/GenFds/Section.py
@@ -1,7 +1,7 @@
## @file
# section base class
#
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007-2011, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
diff --git a/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py b/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
index a8c36ea3c3..3f6c575128 100644
--- a/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
+++ b/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
@@ -23,7 +23,6 @@ from optparse import make_option
from Common.BuildToolError import *
import Common.EdkLogger as EdkLogger
from Common.BuildVersion import gBUILD_VERSION
-
import array
# Version and Copyright
diff --git a/BaseTools/Source/Python/UPT/Library/ParserValidate.py b/BaseTools/Source/Python/UPT/Library/ParserValidate.py
index d6b9a096c7..8efb56a61a 100644
--- a/BaseTools/Source/Python/UPT/Library/ParserValidate.py
+++ b/BaseTools/Source/Python/UPT/Library/ParserValidate.py
@@ -17,6 +17,7 @@ PaserValidate
import os.path
import re
+import platform
from Library.DataType import MODULE_LIST
from Library.DataType import COMPONENT_TYPE_LIST
@@ -281,9 +282,14 @@ def IsValidPath(Path, Root):
# @param Path: path to be checked
#
def IsValidInstallPath(Path):
- if os.path.isabs(Path):
- return False
-
+ if platform.platform().find("Windows") >= 0:
+ if os.path.isabs(Path):
+ return False
+ else:
+ if Path[1:2] == ':' or Path.find('\\') >=0:
+ return False
+ if os.path.isabs(Path):
+ return False
if Path.startswith('.'):
return False
diff --git a/BaseTools/Source/Python/Workspace/MetaDataTable.py b/BaseTools/Source/Python/Workspace/MetaDataTable.py
index 64f0480c37..34ef4903df 100644
--- a/BaseTools/Source/Python/Workspace/MetaDataTable.py
+++ b/BaseTools/Source/Python/Workspace/MetaDataTable.py
@@ -140,6 +140,10 @@ class Table(object):
def SetEndFlag(self):
self.Exec("insert into %s values(%s)" % (self.Table, self._DUMMY_))
+ #
+ # Need to execution commit for table data changed.
+ #
+ self.Cur.connection.commit()
def IsIntegral(self):
Result = self.Exec("select min(ID) from %s" % (self.Table))
@@ -147,6 +151,9 @@ class Table(object):
return False
return True
+ def GetAll(self):
+ return self.Exec("select * from %s where ID > 0 order by ID" % (self.Table))
+
## TableFile
#
# This class defined a table used for file
@@ -198,19 +205,15 @@ class TableFile(Table):
#
# @retval FileID: The ID after record is inserted
#
- def InsertFile(self, FileFullPath, Model):
- (Filepath, Name) = os.path.split(FileFullPath)
- (Root, Ext) = os.path.splitext(FileFullPath)
- TimeStamp = os.stat(FileFullPath)[8]
- File = FileClass(-1, Name, Ext, Filepath, FileFullPath, Model, '', [], [], [])
+ def InsertFile(self, File, Model):
return self.Insert(
- Name,
- Ext,
- Filepath,
- FileFullPath,
- Model,
- TimeStamp
- )
+ File.Name,
+ File.Ext,
+ File.Dir,
+ File.Path,
+ Model,
+ File.TimeStamp
+ )
## Get ID of a given file
#
@@ -218,8 +221,8 @@ class TableFile(Table):
#
# @retval ID ID value of given file in the table
#
- def GetFileId(self, FilePath):
- QueryScript = "select ID from %s where FullPath = '%s'" % (self.Table, FilePath)
+ def GetFileId(self, File):
+ QueryScript = "select ID from %s where FullPath = '%s'" % (self.Table, str(File))
RecordList = self.Exec(QueryScript)
if len(RecordList) == 0:
return None
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 4bad21298a..bfa7054396 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -15,14 +15,75 @@
# Import Modules
#
import os
+import re
import time
import copy
import Common.EdkLogger as EdkLogger
+import Common.GlobalData as GlobalData
+
from CommonDataClass.DataClass import *
from Common.DataType import *
from Common.String import *
-from Common.Misc import Blist, GuidStructureStringToGuidString, CheckPcdDatum
+from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData
+from Common.Expression import *
+from CommonDataClass.Exceptions import *
+
+from MetaFileTable import MetaFileStorage
+
+## A decorator used to parse macro definition
+def ParseMacro(Parser):
+ def MacroParser(self):
+ Match = gMacroDefPattern.match(self._CurrentLine)
+ if not Match:
+ # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
+ Parser(self)
+ return
+
+ TokenList = GetSplitValueList(self._CurrentLine[Match.end(1):], TAB_EQUAL_SPLIT, 1)
+ # Syntax check
+ if not TokenList[0]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ if len(TokenList) < 2:
+ TokenList.append('')
+
+ Type = Match.group(1)
+ Name, Value = TokenList
+ # Global macros can be only defined via environment variable
+ if Name in GlobalData.gGlobalDefines:
+ EdkLogger.error('Parser', FORMAT_INVALID, "%s can only be defined via environment variable" % Name,
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ # Only upper case letters, digit and '_' are allowed
+ if not gMacroNamePattern.match(Name):
+ EdkLogger.error('Parser', FORMAT_INVALID, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+
+ self._ItemType = self.DataType[Type]
+ # DEFINE defined macros
+ if self._ItemType == MODEL_META_DATA_DEFINE:
+ if self._SectionType == MODEL_META_DATA_HEADER:
+ self._FileLocalMacros[Name] = Value
+ else:
+ SectionDictKey = self._SectionType, self._Scope[0][0], self._Scope[0][1]
+ if SectionDictKey not in self._SectionsMacroDict:
+ self._SectionsMacroDict[SectionDictKey] = {}
+ SectionLocalMacros = self._SectionsMacroDict[SectionDictKey]
+ SectionLocalMacros[Name] = Value
+ # EDK_GLOBAL defined macros
+ elif type(self) != DscParser:
+ EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used in .dsc file",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ elif self._SectionType != MODEL_META_DATA_HEADER:
+ EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used under [Defines] section",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ elif (Name in self._FileLocalMacros) and (self._FileLocalMacros[Name] != Value):
+ EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+
+ self._ValueList = [Type, Name, Value]
+
+ return MacroParser
## Base class of parser
#
@@ -73,23 +134,21 @@ class MetaFileParser(object):
# @param Owner Owner ID (for sub-section parsing)
# @param From ID from which the data comes (for !INCLUDE directive)
#
- def __init__(self, FilePath, FileType, Table, Macros=None, Owner=-1, From=-1):
- # prevent re-initialization
- if hasattr(self, "_Table"):
- return
+ def __init__(self, FilePath, FileType, Table, Owner=-1, From=-1):
self._Table = Table
+ self._RawTable = Table
self._FileType = FileType
self.MetaFile = FilePath
- self._FileDir = os.path.dirname(self.MetaFile)
- self._Macros = copy.copy(Macros)
- self._Macros["WORKSPACE"] = os.environ["WORKSPACE"]
+ self._FileDir = self.MetaFile.Dir
+ self._Defines = {}
+ self._FileLocalMacros = {}
+ self._SectionsMacroDict = {}
# for recursive parsing
- self._Owner = Owner
+ self._Owner = [Owner]
self._From = From
# parsr status for parsing
- self._Content = None
self._ValueList = ['', '', '', '', '']
self._Scope = []
self._LineIndex = 0
@@ -99,9 +158,13 @@ class MetaFileParser(object):
self._InSubsection = False
self._SubsectionType = MODEL_UNKNOWN
self._SubsectionName = ''
+ self._ItemType = MODEL_UNKNOWN
self._LastItem = -1
self._Enabled = 0
self._Finished = False
+ self._PostProcessed = False
+ # Different version of meta-file has different way to parse.
+ self._Version = 0
## Store the parsed data in table
def _Store(self, *Args):
@@ -111,6 +174,10 @@ class MetaFileParser(object):
def Start(self):
raise NotImplementedError
+ ## Notify a post-process is needed
+ def DoPostProcess(self):
+ self._PostProcessed = False
+
## Set parsing complete flag in both class and table
def _Done(self):
self._Finished = True
@@ -118,15 +185,8 @@ class MetaFileParser(object):
if self._From == -1:
self._Table.SetEndFlag()
- ## Return the table containg parsed data
- #
- # If the parse complete flag is not set, this method will try to parse the
- # file before return the table
- #
- def _GetTable(self):
- if not self._Finished:
- self.Start()
- return self._Table
+ def _PostProcess(self):
+ self._PostProcessed = True
## Get the parse complete flag
def _GetFinished(self):
@@ -138,12 +198,30 @@ class MetaFileParser(object):
## Use [] style to query data in table, just for readability
#
- # DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)]
+ # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
#
def __getitem__(self, DataInfo):
if type(DataInfo) != type(()):
DataInfo = (DataInfo,)
- return self.Table.Query(*DataInfo)
+
+ # Parse the file first, if necessary
+ if not self._Finished:
+ if self._RawTable.IsIntegrity():
+ self._Finished = True
+ else:
+ self._Table = self._RawTable
+ self._PostProcessed = False
+ self.Start()
+
+ # No specific ARCH or Platform given, use raw data
+ if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] == None):
+ return self._RawTable.Query(*DataInfo)
+
+ # Do post-process if necessary
+ if not self._PostProcessed:
+ self._PostProcess()
+
+ return self._Table.Query(*DataInfo)
## Data parser for the common format in different type of file
#
@@ -151,6 +229,7 @@ class MetaFileParser(object):
#
# xxx1 | xxx2 | xxx3
#
+ @ParseMacro
def _CommonParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
self._ValueList[0:len(TokenList)] = TokenList
@@ -159,15 +238,14 @@ class MetaFileParser(object):
#
# Only path can have macro used. So we need to replace them before use.
#
+ @ParseMacro
def _PathParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
self._ValueList[0:len(TokenList)] = TokenList
- if len(self._Macros) > 0:
- for Index in range(0, len(self._ValueList)):
- Value = self._ValueList[Index]
- if Value == None or Value == '':
- continue
- self._ValueList[Index] = NormPath(Value, self._Macros)
+ # Don't do macro replacement for dsc file at this point
+ if type(self) != DscParser:
+ Macros = self._Macros
+ self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
## Skip unsupported data
def _Skip(self):
@@ -217,47 +295,47 @@ class MetaFileParser(object):
if 'COMMON' in ArchList and len(ArchList) > 1:
EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
File=self.MetaFile, Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+ # If the section information is needed later, it should be stored in database
+ self._ValueList[0] = self._SectionName
## [defines] section parser
+ @ParseMacro
def _DefineParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- self._ValueList[0:len(TokenList)] = TokenList
- if self._ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
+ self._ValueList[1:len(TokenList)] = TokenList
+ if not self._ValueList[1]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
-
- ## DEFINE name=value parser
- def _MacroParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
- MacroType = TokenList[0]
- if len(TokenList) < 2 or TokenList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No macro name/value given",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
- TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1)
- if TokenList[0] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",
+ if not self._ValueList[2]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
- # Macros defined in the command line override ones defined in the meta-data file
- if not TokenList[0] in self._Macros:
- if len(TokenList) == 1:
- self._Macros[TokenList[0]] = ''
- else:
- # keep the macro definition for later use
- self._Macros[TokenList[0]] = ReplaceMacro(TokenList[1], self._Macros, False)
+ Name, Value = self._ValueList[1], self._ValueList[2]
+ # Sometimes, we need to make differences between EDK and EDK2 modules
+ if Name == 'INF_VERSION':
+ try:
+ self._Version = int(Value, 0)
+ except:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
- return TokenList[0], self._Macros[TokenList[0]]
+ Value = ReplaceMacro(Value, self._Macros)
+ if type(self) == InfParser and self._Version < 0x00010005:
+ # EDK module allows using defines as macros
+ self._FileLocalMacros[Name] = Value
+ self._Defines[Name] = Value
## [BuildOptions] section parser
+ @ParseMacro
def _BuildOptionParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
if len(TokenList2) == 2:
- self._ValueList[0] = TokenList2[0] # toolchain family
- self._ValueList[1] = TokenList2[1] # keys
+ self._ValueList[0] = TokenList2[0] # toolchain family
+ self._ValueList[1] = TokenList2[1] # keys
else:
self._ValueList[1] = TokenList[0]
- if len(TokenList) == 2: # value
+ if len(TokenList) == 2 and type(self) != DscParser: # value
self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)
if self._ValueList[1].count('_') != 4:
@@ -270,9 +348,27 @@ class MetaFileParser(object):
Line=self._LineIndex+1
)
+ def _GetMacros(self):
+ Macros = {}
+ Macros.update(self._FileLocalMacros)
+ Macros.update(self._GetApplicableSectionMacro())
+ return Macros
+
+
+ ## Get section Macros that are applicable to current line, which may come from other sections
+ ## that share the same name while scope is wider
+ def _GetApplicableSectionMacro(self):
+ Macros = {}
+
+ for SectionType, Scope1, Scope2 in self._SectionsMacroDict:
+ if (SectionType == self._SectionType) and (Scope1 == self._Scope[0][0] or Scope1 == "COMMON") and (Scope2 == self._Scope[0][1] or Scope2 == "COMMON"):
+ Macros.update(self._SectionsMacroDict[(SectionType, Scope1, Scope2)])
+
+ return Macros
+
_SectionParser = {}
- Table = property(_GetTable)
Finished = property(_GetFinished, _SetFinished)
+ _Macros = property(_GetMacros)
## INF file parser class
@@ -287,6 +383,7 @@ class InfParser(MetaFileParser):
DataType = {
TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,
+ TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
@@ -316,26 +413,30 @@ class InfParser(MetaFileParser):
# @param Table Database used to retrieve module/package information
# @param Macros Macros used for replacement in file
#
- def __init__(self, FilePath, FileType, Table, Macros=None):
- MetaFileParser.__init__(self, FilePath, FileType, Table, Macros)
+ def __init__(self, FilePath, FileType, Table):
+ # prevent re-initialization
+ if hasattr(self, "_Table"):
+ return
+ MetaFileParser.__init__(self, FilePath, FileType, Table)
## Parser starter
def Start(self):
NmakeLine = ''
+ Content = ''
try:
- self._Content = open(self.MetaFile, 'r').readlines()
+ Content = open(str(self.MetaFile), 'r').readlines()
except:
EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
# parse the file line by line
IsFindBlockComment = False
- for Index in range(0, len(self._Content)):
+ for Index in range(0, len(Content)):
# skip empty, commented, block commented lines
- Line = CleanString(self._Content[Index], AllowCppStyleComment=True)
+ Line = CleanString(Content[Index], AllowCppStyleComment=True)
NextLine = ''
- if Index + 1 < len(self._Content):
- NextLine = CleanString(self._Content[Index + 1])
+ if Index + 1 < len(Content):
+ NextLine = CleanString(Content[Index + 1])
if Line == '':
continue
if Line.find(DataType.TAB_COMMENT_EDK_START) > -1:
@@ -353,6 +454,29 @@ class InfParser(MetaFileParser):
# section header
if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
self._SectionHeaderParser()
+ # Check invalid sections
+ if self._Version < 0x00010005:
+ if self._SectionType in [MODEL_META_DATA_BUILD_OPTION,
+ MODEL_EFI_LIBRARY_CLASS,
+ MODEL_META_DATA_PACKAGE,
+ MODEL_PCD_FIXED_AT_BUILD,
+ MODEL_PCD_PATCHABLE_IN_MODULE,
+ MODEL_PCD_FEATURE_FLAG,
+ MODEL_PCD_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC,
+ MODEL_EFI_GUID,
+ MODEL_EFI_PROTOCOL,
+ MODEL_EFI_PPI,
+ MODEL_META_DATA_USER_EXTENSION]:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "Section [%s] is not allowed in inf file without version" % (self._SectionName),
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ elif self._SectionType in [MODEL_EFI_INCLUDE,
+ MODEL_EFI_LIBRARY_INSTANCE,
+ MODEL_META_DATA_NMAKE]:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "Section [%s] is not allowed in inf file with version 0x%08x" % (self._SectionName, self._Version),
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
continue
# merge two lines specified by '\' in section NMAKE
elif self._SectionType == MODEL_META_DATA_NMAKE:
@@ -370,10 +494,6 @@ class InfParser(MetaFileParser):
else:
self._CurrentLine = NmakeLine + Line
NmakeLine = ''
- elif Line.upper().startswith('DEFINE '):
- # file private macros
- self._MacroParser()
- continue
# section content
self._ValueList = ['','','']
@@ -392,7 +512,7 @@ class InfParser(MetaFileParser):
self._ValueList[2],
Arch,
Platform,
- self._Owner,
+ self._Owner[-1],
self._LineIndex+1,
-1,
self._LineIndex+1,
@@ -411,9 +531,13 @@ class InfParser(MetaFileParser):
def _IncludeParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
self._ValueList[0:len(TokenList)] = TokenList
- if len(self._Macros) > 0:
+ Macros = self._Macros
+ if Macros:
for Index in range(0, len(self._ValueList)):
Value = self._ValueList[Index]
+ if not Value:
+ continue
+
if Value.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
Value = '$(EDK_SOURCE)' + Value[17:]
if Value.find('$(EFI_SOURCE)') > -1 or Value.find('$(EDK_SOURCE)') > -1:
@@ -425,34 +549,30 @@ class InfParser(MetaFileParser):
else:
Value = '$(EFI_SOURCE)/' + Value
- if Value == None or Value == '':
- continue
- self._ValueList[Index] = NormPath(Value, self._Macros)
+ self._ValueList[Index] = ReplaceMacro(Value, Macros)
## Parse [Sources] section
#
# Only path can have macro used. So we need to replace them before use.
#
+ @ParseMacro
def _SourceFileParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
self._ValueList[0:len(TokenList)] = TokenList
+ Macros = self._Macros
# For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
- if 'COMPONENT_TYPE' in self._Macros:
- if self._Macros['COMPONENT_TYPE'].upper() == 'ACPITABLE':
+ if 'COMPONENT_TYPE' in Macros:
+ if self._Defines['COMPONENT_TYPE'].upper() == 'ACPITABLE':
self._ValueList[0] = GetSplitValueList(self._ValueList[0], ' ', 1)[0]
- if self._Macros['BASE_NAME'] == 'Microcode':
+ if self._Defines['BASE_NAME'] == 'Microcode':
pass
- if len(self._Macros) > 0:
- for Index in range(0, len(self._ValueList)):
- Value = self._ValueList[Index]
- if Value == None or Value == '':
- continue
- self._ValueList[Index] = NormPath(Value, self._Macros)
+ self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
## Parse [Binaries] section
#
# Only path can have macro used. So we need to replace them before use.
#
+ @ParseMacro
def _BinaryFileParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 2)
if len(TokenList) < 2:
@@ -468,27 +588,19 @@ class InfParser(MetaFileParser):
ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
File=self.MetaFile, Line=self._LineIndex+1)
self._ValueList[0:len(TokenList)] = TokenList
- self._ValueList[1] = NormPath(self._ValueList[1], self._Macros)
+ self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
- ## [defines] section parser
- def _DefineParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- self._ValueList[0:len(TokenList)] = TokenList
- if self._ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
- self._Macros[TokenList[0]] = ReplaceMacro(TokenList[1], self._Macros, False)
-
- ## [nmake] section parser (EDK.x style only)
+ ## [nmake] section parser (Edk.x style only)
def _NmakeParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
self._ValueList[0:len(TokenList)] = TokenList
# remove macros
- self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, False)
+ self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
# remove self-reference in macro setting
#self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
+ @ParseMacro
def _PcdParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
ValueList = GetSplitValueList(TokenList[0], TAB_SPLIT)
@@ -503,6 +615,7 @@ class InfParser(MetaFileParser):
EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
File=self.MetaFile, Line=self._LineIndex+1)
+
# if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
if self._ValueList[2] != '':
InfPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
@@ -512,18 +625,19 @@ class InfParser(MetaFileParser):
self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '0', 1);
## [depex] section parser
+ @ParseMacro
def _DepexParser(self):
self._ValueList[0:1] = [self._CurrentLine]
_SectionParser = {
MODEL_UNKNOWN : MetaFileParser._Skip,
- MODEL_META_DATA_HEADER : _DefineParser,
+ MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser,
- MODEL_EFI_INCLUDE : _IncludeParser, # for EDK.x modules
- MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for EDK.x modules
+ MODEL_EFI_INCLUDE : _IncludeParser, # for Edk.x modules
+ MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for Edk.x modules
MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
MODEL_META_DATA_PACKAGE : MetaFileParser._PathParser,
- MODEL_META_DATA_NMAKE : _NmakeParser, # for EDK.x modules
+ MODEL_META_DATA_NMAKE : _NmakeParser, # for Edk.x modules
MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
MODEL_PCD_FEATURE_FLAG : _PcdParser,
@@ -566,6 +680,8 @@ class DscParser(MetaFileParser):
TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
TAB_COMPONENTS_SOURCE_OVERRIDE_PATH.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH,
TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER,
+ TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
+ TAB_DSC_DEFINES_EDKGLOBAL : MODEL_META_DATA_GLOBAL_DEFINE,
TAB_INCLUDE.upper() : MODEL_META_DATA_INCLUDE,
TAB_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
TAB_IF_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
@@ -575,37 +691,26 @@ class DscParser(MetaFileParser):
TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
}
- # sections which allow "!include" directive
- _IncludeAllowedSection = [
- TAB_COMMON_DEFINES.upper(),
- TAB_LIBRARIES.upper(),
- TAB_LIBRARY_CLASSES.upper(),
- TAB_SKUIDS.upper(),
- TAB_COMPONENTS.upper(),
- TAB_BUILD_OPTIONS.upper(),
- TAB_PCDS_FIXED_AT_BUILD_NULL.upper(),
- TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(),
- TAB_PCDS_FEATURE_FLAG_NULL.upper(),
- TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper(),
- TAB_PCDS_DYNAMIC_HII_NULL.upper(),
- TAB_PCDS_DYNAMIC_VPD_NULL.upper(),
- TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper(),
- TAB_PCDS_DYNAMIC_EX_HII_NULL.upper(),
- TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(),
- ]
-
- # operators which can be used in "!if/!ifdef/!ifndef" directives
- _OP_ = {
- "!" : lambda a: not a,
- "!=" : lambda a,b: a!=b,
- "==" : lambda a,b: a==b,
- ">" : lambda a,b: a>b,
- "<" : lambda a,b: a<b,
- "=>" : lambda a,b: a>=b,
- ">=" : lambda a,b: a>=b,
- "<=" : lambda a,b: a<=b,
- "=<" : lambda a,b: a<=b,
- }
+ # Valid names in define section
+ DefineKeywords = [
+ "DSC_SPECIFICATION",
+ "PLATFORM_NAME",
+ "PLATFORM_GUID",
+ "PLATFORM_VERSION",
+ "SKUID_IDENTIFIER",
+ "SUPPORTED_ARCHITECTURES",
+ "BUILD_TARGETS",
+ "OUTPUT_DIRECTORY",
+ "FLASH_DEFINITION",
+ "BUILD_NUMBER",
+ "RFC_LANGUAGES",
+ "ISO_LANGUAGES",
+ "TIME_STAMP_FILE",
+ "VPD_TOOL_GUID",
+ "FIX_LOAD_TOP_MEMORY_ADDRESS"
+ ]
+
+ SymbolPattern = ValueExpression.SymbolPattern
## Constructor of DscParser
#
@@ -618,162 +723,99 @@ class DscParser(MetaFileParser):
# @param Owner Owner ID (for sub-section parsing)
# @param From ID from which the data comes (for !INCLUDE directive)
#
- def __init__(self, FilePath, FileType, Table, Macros=None, Owner=-1, From=-1):
- MetaFileParser.__init__(self, FilePath, FileType, Table, Macros, Owner, From)
+ def __init__(self, FilePath, FileType, Table, Owner=-1, From=-1):
+ # prevent re-initialization
+ if hasattr(self, "_Table"):
+ return
+ MetaFileParser.__init__(self, FilePath, FileType, Table, Owner, From)
+ self._Version = 0x00010005 # Only EDK2 dsc file is supported
# to store conditional directive evaluation result
- self._Eval = Blist()
+ self._DirectiveStack = []
+ self._DirectiveEvalStack = []
+ self._Enabled = 1
+
+ # Final valid replacable symbols
+ self._Symbols = {}
+ #
+ # Map the ID between the original table and new table to track
+ # the owner item
+ #
+ self._IdMapping = {-1:-1}
## Parser starter
def Start(self):
+ Content = ''
try:
- if self._Content == None:
- self._Content = open(self.MetaFile, 'r').readlines()
+ Content = open(str(self.MetaFile), 'r').readlines()
except:
EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
- for Index in range(0, len(self._Content)):
- Line = CleanString(self._Content[Index])
+ for Index in range(0, len(Content)):
+ Line = CleanString(Content[Index])
# skip empty line
if Line == '':
continue
+
self._CurrentLine = Line
self._LineIndex = Index
- if self._InSubsection and self._Owner == -1:
- self._Owner = self._LastItem
+ if self._InSubsection and self._Owner[-1] == -1:
+ self._Owner.append(self._LastItem)
# section header
if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
- self._SectionHeaderParser()
- continue
+ self._SectionType = MODEL_META_DATA_SECTION_HEADER
# subsection ending
- elif Line[0] == '}':
+ elif Line[0] == '}' and self._InSubsection:
self._InSubsection = False
self._SubsectionType = MODEL_UNKNOWN
self._SubsectionName = ''
- self._Owner = -1
+ self._Owner.pop()
continue
# subsection header
elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:
- self._SubsectionHeaderParser()
- continue
+ self._SubsectionType = MODEL_META_DATA_SUBSECTION_HEADER
# directive line
elif Line[0] == '!':
self._DirectiveParser()
continue
- # file private macros
- elif Line.upper().startswith('DEFINE '):
- if self._Enabled < 0:
- # Do not parse the macro and add it to self._Macros dictionary if directives
- # statement is evaluated to false.
- continue
-
- (Name, Value) = self._MacroParser()
- # Make the defined macro in DSC [Defines] section also
- # available for FDF file.
- if self._SectionName == TAB_COMMON_DEFINES.upper():
- self._LastItem = self._Store(
- MODEL_META_DATA_GLOBAL_DEFINE,
- Name,
- Value,
- '',
- 'COMMON',
- 'COMMON',
- self._Owner,
- self._From,
- self._LineIndex+1,
- -1,
- self._LineIndex+1,
- -1,
- self._Enabled
- )
- continue
- elif Line.upper().startswith('EDK_GLOBAL '):
- if self._Enabled < 0:
- # Do not parse the macro and add it to self._Macros dictionary
- # if previous directives statement is evaluated to false.
- continue
-
- (Name, Value) = self._MacroParser()
- for Arch, ModuleType in self._Scope:
- self._LastItem = self._Store(
- MODEL_META_DATA_DEFINE,
- Name,
- Value,
- '',
- Arch,
- 'COMMON',
- self._Owner,
- self._From,
- self._LineIndex+1,
- -1,
- self._LineIndex+1,
- -1,
- self._Enabled
- )
- continue
- # section content
if self._InSubsection:
SectionType = self._SubsectionType
- SectionName = self._SubsectionName
else:
SectionType = self._SectionType
- SectionName = self._SectionName
+ self._ItemType = SectionType
self._ValueList = ['', '', '']
self._SectionParser[SectionType](self)
if self._ValueList == None:
continue
-
#
# Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
# LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
#
for Arch, ModuleType in self._Scope:
self._LastItem = self._Store(
- SectionType,
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- Arch,
- ModuleType,
- self._Owner,
- self._From,
- self._LineIndex+1,
- -1,
- self._LineIndex+1,
- -1,
- self._Enabled
- )
+ self._ItemType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ Arch,
+ ModuleType,
+ self._Owner[-1],
+ self._From,
+ self._LineIndex+1,
+ -1,
+ self._LineIndex+1,
+ -1,
+ self._Enabled
+ )
+
+ if self._DirectiveStack:
+ Type, Line, Text = self._DirectiveStack[-1]
+ EdkLogger.error('Parser', FORMAT_INVALID, "No matching '!endif' found",
+ ExtraData=Text, File=self.MetaFile, Line=Line)
self._Done()
- ## [defines] section parser
- def _DefineParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
- if len(TokenList) < 2:
- EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
- # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing
- if TokenList[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:
- TokenList[1] = NormPath(TokenList[1], self._Macros)
- self._ValueList[0:len(TokenList)] = TokenList
- # Treat elements in the [defines] section as global macros for FDF file.
- self._LastItem = self._Store(
- MODEL_META_DATA_GLOBAL_DEFINE,
- TokenList[0],
- TokenList[1],
- '',
- 'COMMON',
- 'COMMON',
- self._Owner,
- self._From,
- self._LineIndex+1,
- -1,
- self._LineIndex+1,
- -1,
- self._Enabled
- )
-
## <subsection_header> parser
def _SubsectionHeaderParser(self):
self._SubsectionName = self._CurrentLine[1:-1].upper()
@@ -782,13 +824,16 @@ class DscParser(MetaFileParser):
else:
self._SubsectionType = MODEL_UNKNOWN
EdkLogger.warn("Parser", "Unrecognized sub-section", File=self.MetaFile,
- Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+ Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+ self._ValueList[0] = self._SubsectionName
## Directive statement parser
def _DirectiveParser(self):
self._ValueList = ['','','']
TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
self._ValueList[0:len(TokenList)] = TokenList
+
+ # Syntax check
DirectiveName = self._ValueList[0].upper()
if DirectiveName not in self.DataType:
EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName,
@@ -797,134 +842,89 @@ class DscParser(MetaFileParser):
EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression",
File=self.MetaFile, Line=self._LineIndex+1,
ExtraData=self._CurrentLine)
- # keep the directive in database first
- self._LastItem = self._Store(
- self.DataType[DirectiveName],
- self._ValueList[0],
- self._ValueList[1],
- self._ValueList[2],
- 'COMMON',
- 'COMMON',
- self._Owner,
- self._From,
- self._LineIndex + 1,
- -1,
- self._LineIndex + 1,
- -1,
- 0
- )
-
- # process the directive
- if DirectiveName == "!INCLUDE":
- if not self._SectionName in self._IncludeAllowedSection:
- EdkLogger.error("Parser", FORMAT_INVALID, File=self.MetaFile, Line=self._LineIndex+1,
- ExtraData="'!include' is not allowed under section [%s]" % self._SectionName)
- # the included file must be relative to workspace
- IncludedFile = os.path.join(os.environ["WORKSPACE"], NormPath(self._ValueList[1], self._Macros))
- Parser = DscParser(IncludedFile, self._FileType, self._Table, self._Macros, From=self._LastItem)
- # set the parser status with current status
- Parser._SectionName = self._SectionName
- Parser._SectionType = self._SectionType
- Parser._Scope = self._Scope
- Parser._Enabled = self._Enabled
- try:
- Parser.Start()
- except:
- EdkLogger.error("Parser", PARSER_ERROR, File=self.MetaFile, Line=self._LineIndex+1,
- ExtraData="Failed to parse content in file %s" % IncludedFile)
- # insert an imaginary token in the DSC table to indicate its external dependency on another file
- self._Store(MODEL_EXTERNAL_DEPENDENCY, IncludedFile, str(os.stat(IncludedFile)[8]), "")
- # update current status with sub-parser's status
- self._SectionName = Parser._SectionName
- self._SectionType = Parser._SectionType
- self._Scope = Parser._Scope
- self._Enabled = Parser._Enabled
- self._Macros.update(Parser._Macros)
- else:
- if DirectiveName in ["!IF", "!IFDEF", "!IFNDEF"]:
- # evaluate the expression
- Result = self._Evaluate(self._ValueList[1])
- if DirectiveName == "!IFNDEF":
- Result = not Result
- self._Eval.append(Result)
- elif DirectiveName in ["!ELSEIF"]:
- # evaluate the expression
- self._Eval[-1] = (not self._Eval[-1]) & self._Evaluate(self._ValueList[1])
- elif DirectiveName in ["!ELSE"]:
- self._Eval[-1] = not self._Eval[-1]
- elif DirectiveName in ["!ENDIF"]:
- if len(self._Eval) > 0:
- self._Eval.pop()
- else:
- EdkLogger.error("Parser", FORMAT_INVALID, "!IF..[!ELSE]..!ENDIF doesn't match",
- File=self.MetaFile, Line=self._LineIndex+1)
- if self._Eval.Result == False:
- self._Enabled = 0 - len(self._Eval)
- else:
- self._Enabled = len(self._Eval)
- ## Evaluate the Token for its value; for now only macros are supported.
- def _EvaluateToken(self, TokenName, Expression):
- if TokenName.startswith("$(") and TokenName.endswith(")"):
- Name = TokenName[2:-1]
- return self._Macros.get(Name)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "Unknown operand '%(Token)s', "
- "please use '$(%(Token)s)' if '%(Token)s' is a macro" % {"Token" : TokenName},
- File=self.MetaFile, Line=self._LineIndex+1, ExtraData=Expression)
-
- ## Evaluate the value of expression in "if/ifdef/ifndef" directives
- def _Evaluate(self, Expression):
- TokenList = Expression.split()
- TokenNumber = len(TokenList)
- # one operand, guess it's just a macro name
- if TokenNumber == 1:
- TokenValue = self._EvaluateToken(TokenList[0], Expression)
- return TokenValue != None
- # two operands, suppose it's "!xxx" format
- elif TokenNumber == 2:
- Op = TokenList[0]
- if Op not in self._OP_:
- EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator [%s]" % Op, File=self.MetaFile,
- Line=self._LineIndex+1, ExtraData=Expression)
- if TokenList[1].upper() == 'TRUE':
- Value = True
+ ItemType = self.DataType[DirectiveName]
+ if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
+ # Remove all directives between !if and !endif, including themselves
+ while self._DirectiveStack:
+ # Remove any !else or !elseif
+ DirectiveInfo = self._DirectiveStack.pop()
+ if DirectiveInfo[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
+ break
else:
- Value = False
- return self._OP_[Op](Value)
- # three operands
- elif TokenNumber == 3:
- TokenValue = TokenList[0]
- if TokenValue != "":
- if TokenValue[0] in ["'", '"'] and TokenValue[-1] in ["'", '"']:
- TokenValue = TokenValue[1:-1]
- if TokenValue.startswith("$(") and TokenValue.endswith(")"):
- TokenValue = self._EvaluateToken(TokenValue, Expression)
- if TokenValue == None:
- return False
- if TokenValue != "":
- if TokenValue[0] in ["'", '"'] and TokenValue[-1] in ["'", '"']:
- TokenValue = TokenValue[1:-1]
-
- Value = TokenList[2]
- if Value != "":
- if Value[0] in ["'", '"'] and Value[-1] in ["'", '"']:
- Value = Value[1:-1]
- if Value.startswith("$(") and Value.endswith(")"):
- Value = self._EvaluateToken(Value, Expression)
- if Value == None:
- return False
- if Value != "":
- if Value[0] in ["'", '"'] and Value[-1] in ["'", '"']:
- Value = Value[1:-1]
- Op = TokenList[1]
- if Op not in self._OP_:
- EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator [%s]" % Op, File=self.MetaFile,
- Line=self._LineIndex+1, ExtraData=Expression)
- return self._OP_[Op](TokenValue, Value)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, File=self.MetaFile, Line=self._LineIndex+1,
- ExtraData=Expression)
+ EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",
+ File=self.MetaFile, Line=self._LineIndex+1,
+ ExtraData=self._CurrentLine)
+ elif ItemType != MODEL_META_DATA_INCLUDE:
+ # Break if there's a !else is followed by a !elseif
+ if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \
+ self._DirectiveStack and \
+ self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
+ EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'",
+ File=self.MetaFile, Line=self._LineIndex+1,
+ ExtraData=self._CurrentLine)
+ self._DirectiveStack.append((ItemType, self._LineIndex+1, self._CurrentLine))
+ elif self._From > 0:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "No '!include' allowed in included file",
+ ExtraData=self._CurrentLine, File=self.MetaFile,
+ Line=self._LineIndex+1)
+
+ #
+ # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
+ # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
+ #
+ self._LastItem = self._Store(
+ ItemType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ 'COMMON',
+ 'COMMON',
+ self._Owner[-1],
+ self._From,
+ self._LineIndex+1,
+ -1,
+ self._LineIndex+1,
+ -1,
+ 0
+ )
+
+ ## [defines] section parser
+ @ParseMacro
+ def _DefineParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ self._ValueList[1:len(TokenList)] = TokenList
+
+ # Syntax check
+ if not self._ValueList[1]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ if not self._ValueList[2]:
+ EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ if not self._ValueList[1] in self.DefineKeywords:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "Unknown keyword found: %s. "
+ "If this is a macro you must "
+ "add it as a DEFINE in the DSC" % self._ValueList[1],
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ self._Defines[self._ValueList[1]] = self._ValueList[2]
+ self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]
+
+ @ParseMacro
+ def _SkuIdParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+ if len(TokenList) != 2:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Integer>|<UiName>'",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1)
+ self._ValueList[0:len(TokenList)] = TokenList
+
+ ## Parse Edk style of library modules
+ def _LibraryInstanceParser(self):
+ self._ValueList[0] = self._CurrentLine
## PCD sections parser
#
@@ -940,8 +940,9 @@ class DscParser(MetaFileParser):
# [PcdsDynamicVpd]
# [PcdsDynamicHii]
#
+ @ParseMacro
def _PcdParser(self):
- TokenList = GetSplitValueList(ReplaceMacro(self._CurrentLine, self._Macros), TAB_VALUE_SPLIT, 1)
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
if len(TokenList) == 2:
self._ValueList[2] = TokenList[1]
@@ -959,17 +960,18 @@ class DscParser(MetaFileParser):
self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1);
elif DscPcdValueList[0] in ['False', 'false', 'FALSE']:
self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1);
-
+
## [components] section parser
+ @ParseMacro
def _ComponentParser(self):
if self._CurrentLine[-1] == '{':
self._ValueList[0] = self._CurrentLine[0:-1].strip()
self._InSubsection = True
else:
self._ValueList[0] = self._CurrentLine
- if len(self._Macros) > 0:
- self._ValueList[0] = NormPath(self._ValueList[0], self._Macros)
+ ## [LibraryClasses] section
+ @ParseMacro
def _LibraryClassParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
if len(TokenList) < 2:
@@ -984,35 +986,357 @@ class DscParser(MetaFileParser):
EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified",
ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
File=self.MetaFile, Line=self._LineIndex+1)
+
self._ValueList[0:len(TokenList)] = TokenList
- if len(self._Macros) > 0:
- self._ValueList[1] = NormPath(self._ValueList[1], self._Macros)
def _CompponentSourceOverridePathParser(self):
- if len(self._Macros) > 0:
- self._ValueList[0] = NormPath(self._CurrentLine, self._Macros)
+ self._ValueList[0] = self._CurrentLine
+
+ ## [BuildOptions] section parser
+ @ParseMacro
+ def _BuildOptionParser(self):
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+ TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
+ if len(TokenList2) == 2:
+ self._ValueList[0] = TokenList2[0] # toolchain family
+ self._ValueList[1] = TokenList2[1] # keys
+ else:
+ self._ValueList[1] = TokenList[0]
+ if len(TokenList) == 2: # value
+ self._ValueList[2] = TokenList[1]
+
+ if self._ValueList[1].count('_') != 4:
+ EdkLogger.error(
+ 'Parser',
+ FORMAT_INVALID,
+ "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
+ ExtraData=self._CurrentLine,
+ File=self.MetaFile,
+ Line=self._LineIndex+1
+ )
+
+ ## Override parent's method since we'll do all macro replacements in parser
+ def _GetMacros(self):
+ Macros = {}
+ Macros.update(self._FileLocalMacros)
+ Macros.update(self._GetApplicableSectionMacro())
+ Macros.update(GlobalData.gEdkGlobal)
+ Macros.update(GlobalData.gPlatformDefines)
+ Macros.update(GlobalData.gCommandLineDefines)
+ # PCD cannot be referenced in macro definition
+ if self._ItemType not in [MODEL_META_DATA_DEFINE, MODEL_META_DATA_GLOBAL_DEFINE]:
+ Macros.update(self._Symbols)
+ return Macros
+
+ def _PostProcess(self):
+ Processer = {
+ MODEL_META_DATA_SECTION_HEADER : self.__ProcessSectionHeader,
+ MODEL_META_DATA_SUBSECTION_HEADER : self.__ProcessSubsectionHeader,
+ MODEL_META_DATA_HEADER : self.__ProcessDefine,
+ MODEL_META_DATA_DEFINE : self.__ProcessDefine,
+ MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine,
+ MODEL_META_DATA_INCLUDE : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF : self.__ProcessDirective,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF : self.__ProcessDirective,
+ MODEL_EFI_SKU_ID : self.__ProcessSkuId,
+ MODEL_EFI_LIBRARY_INSTANCE : self.__ProcessLibraryInstance,
+ MODEL_EFI_LIBRARY_CLASS : self.__ProcessLibraryClass,
+ MODEL_PCD_FIXED_AT_BUILD : self.__ProcessPcd,
+ MODEL_PCD_PATCHABLE_IN_MODULE : self.__ProcessPcd,
+ MODEL_PCD_FEATURE_FLAG : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_DEFAULT : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_HII : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_VPD : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_EX_HII : self.__ProcessPcd,
+ MODEL_PCD_DYNAMIC_EX_VPD : self.__ProcessPcd,
+ MODEL_META_DATA_COMPONENT : self.__ProcessComponent,
+ MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : self.__ProcessSourceOverridePath,
+ MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption,
+ MODEL_UNKNOWN : self._Skip,
+ MODEL_META_DATA_USER_EXTENSION : self._Skip,
+ }
+
+ self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True)
+ self._Table.Create()
+ self._DirectiveStack = []
+ self._DirectiveEvalStack = []
+ self._FileWithError = self.MetaFile
+ self._FileLocalMacros = {}
+ self._SectionsMacroDict = {}
+ GlobalData.gPlatformDefines = {}
+
+ # Get all macro and PCD which has straitforward value
+ self.__RetrievePcdValue()
+ self._Content = self._RawTable.GetAll()
+ self._ContentIndex = 0
+ while self._ContentIndex < len(self._Content) :
+ Id, self._ItemType, V1, V2, V3, S1, S2, Owner, self._From, \
+ LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]
+
+ if self._From < 0:
+ self._FileWithError = self.MetaFile
+
+ self._ContentIndex += 1
+
+ self._Scope = [[S1, S2]]
+ self._LineIndex = LineStart - 1
+ self._ValueList = [V1, V2, V3]
+
+ try:
+ Processer[self._ItemType]()
+ except EvaluationException, Excpt:
+ #
+ # Only catch expression evaluation error here. We need to report
+ # the precise number of line on which the error occurred
+ #
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex+1)
+ except MacroException, Excpt:
+ EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex+1)
+
+ if self._ValueList == None:
+ continue
+
+ NewOwner = self._IdMapping.get(Owner, -1)
+ self._Enabled = int((not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack))
+ self._LastItem = self._Store(
+ self._ItemType,
+ self._ValueList[0],
+ self._ValueList[1],
+ self._ValueList[2],
+ S1,
+ S2,
+ NewOwner,
+ self._From,
+ self._LineIndex+1,
+ -1,
+ self._LineIndex+1,
+ -1,
+ self._Enabled
+ )
+ self._IdMapping[Id] = self._LastItem
+
+ GlobalData.gPlatformDefines.update(self._FileLocalMacros)
+ self._PostProcessed = True
+ self._Content = None
+
+ def __ProcessSectionHeader(self):
+ self._SectionName = self._ValueList[0]
+ if self._SectionName in self.DataType:
+ self._SectionType = self.DataType[self._SectionName]
+ else:
+ self._SectionType = MODEL_UNKNOWN
+
+ def __ProcessSubsectionHeader(self):
+ self._SubsectionName = self._ValueList[0]
+ if self._SubsectionName in self.DataType:
+ self._SubsectionType = self.DataType[self._SubsectionName]
+ else:
+ self._SubsectionType = MODEL_UNKNOWN
+
+ def __RetrievePcdValue(self):
+ Records = self._RawTable.Query(MODEL_PCD_FEATURE_FLAG, BelongsToItem=-1.0)
+ for TokenSpaceGuid,PcdName,Value,Dummy2,Dummy3,ID,Line in Records:
+ Value, DatumType, MaxDatumSize = AnalyzePcdData(Value)
+ # Only use PCD whose value is straitforward (no macro and PCD)
+ if self.SymbolPattern.findall(Value):
+ continue
+ Name = TokenSpaceGuid + '.' + PcdName
+ # Don't use PCD with different values.
+ if Name in self._Symbols and self._Symbols[Name] != Value:
+ self._Symbols.pop(Name)
+ continue
+ self._Symbols[Name] = Value
+
+ Records = self._RawTable.Query(MODEL_PCD_FIXED_AT_BUILD, BelongsToItem=-1.0)
+ for TokenSpaceGuid,PcdName,Value,Dummy2,Dummy3,ID,Line in Records:
+ Value, DatumType, MaxDatumSize = AnalyzePcdData(Value)
+ # Only use PCD whose value is straitforward (no macro and PCD)
+ if self.SymbolPattern.findall(Value):
+ continue
+ Name = TokenSpaceGuid+'.'+PcdName
+ # Don't use PCD with different values.
+ if Name in self._Symbols and self._Symbols[Name] != Value:
+ self._Symbols.pop(Name)
+ continue
+ self._Symbols[Name] = Value
+
+ def __ProcessDefine(self):
+ if not self._Enabled:
+ return
+
+ Type, Name, Value = self._ValueList
+ Value = ReplaceMacro(Value, self._Macros, False)
+ if self._ItemType == MODEL_META_DATA_DEFINE:
+ if self._SectionType == MODEL_META_DATA_HEADER:
+ self._FileLocalMacros[Name] = Value
+ else:
+ SectionDictKey = self._SectionType, self._Scope[0][0], self._Scope[0][1]
+ if SectionDictKey not in self._SectionsMacroDict:
+ self._SectionsMacroDict[SectionDictKey] = {}
+ SectionLocalMacros = self._SectionsMacroDict[SectionDictKey]
+ SectionLocalMacros[Name] = Value
+ elif self._ItemType == MODEL_META_DATA_GLOBAL_DEFINE:
+ GlobalData.gEdkGlobal[Name] = Value
+
+ #
+ # Keyword in [Defines] section can be used as Macros
+ #
+ if (self._ItemType == MODEL_META_DATA_HEADER) and (self._SectionType == MODEL_META_DATA_HEADER):
+ self._FileLocalMacros[Name] = Value
+
+ self._ValueList = [Type, Name, Value]
+
+ def __ProcessDirective(self):
+ Result = None
+ if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF]:
+ Macros = self._Macros
+ Macros.update(GlobalData.gGlobalDefines)
+ try:
+ Result = ValueExpression(self._ValueList[1], Macros)()
+ except SymbolNotFound, Exc:
+ EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1])
+ Result = False
+ except WrnExpression, Excpt:
+ #
+ # Catch expression evaluation warning here. We need to report
+ # the precise number of line and return the evaluation result
+ #
+ EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
+ File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+ Line=self._LineIndex+1)
+ Result = Excpt.result
+
+ if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
+ self._DirectiveStack.append(self._ItemType)
+ if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IF:
+ Result = bool(Result)
+ else:
+ Macro = self._ValueList[1]
+ Macro = Macro[2:-1] if (Macro.startswith("$(") and Macro.endswith(")")) else Macro
+ Result = Macro in self._Macros
+ if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF:
+ Result = not Result
+ self._DirectiveEvalStack.append(Result)
+ elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF:
+ self._DirectiveStack.append(self._ItemType)
+ self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
+ self._DirectiveEvalStack.append(bool(Result))
+ elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
+ self._DirectiveStack[-1] = self._ItemType
+ self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
+ elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
+ # Back to the nearest !if/!ifdef/!ifndef
+ while self._DirectiveStack:
+ self._DirectiveEvalStack.pop()
+ Directive = self._DirectiveStack.pop()
+ if Directive in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
+ break
+ elif self._ItemType == MODEL_META_DATA_INCLUDE:
+ # The included file must be relative to workspace
+ IncludedFile = NormPath(ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True))
+ IncludedFile = PathClass(IncludedFile, GlobalData.gWorkspace)
+ ErrorCode, ErrorInfo = IncludedFile.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('parser', ErrorCode, File=self._FileWithError,
+ Line=self._LineIndex+1, ExtraData=ErrorInfo)
+
+ self._FileWithError = IncludedFile
+
+ IncludedFileTable = MetaFileStorage(self._Table.Cur, IncludedFile, MODEL_FILE_DSC, False)
+ Owner = self._Content[self._ContentIndex-1][0]
+ Parser = DscParser(IncludedFile, self._FileType, IncludedFileTable,
+ Owner=Owner, From=Owner)
+
+ # set the parser status with current status
+ Parser._SectionName = self._SectionName
+ Parser._SectionType = self._SectionType
+ Parser._Scope = self._Scope
+ Parser._Enabled = self._Enabled
+ # Parse the included file
+ Parser.Start()
+
+ # update current status with sub-parser's status
+ self._SectionName = Parser._SectionName
+ self._SectionType = Parser._SectionType
+ self._Scope = Parser._Scope
+ self._Enabled = Parser._Enabled
+
+ # Insert all records in the table for the included file into dsc file table
+ Records = IncludedFileTable.GetAll()
+ if Records:
+ self._Content[self._ContentIndex:self._ContentIndex] = Records
+
+ def __ProcessSkuId(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
+ for Value in self._ValueList]
+
+ def __ProcessLibraryInstance(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
+
+ def __ProcessLibraryClass(self):
+ self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True)
+
+ def __ProcessPcd(self):
+ ValueList = GetSplitValueList(self._ValueList[2])
+ if len(ValueList) > 1 and ValueList[1] == 'VOID*':
+ PcdValue = ValueList[0]
+ ValueList[0] = ReplaceMacro(PcdValue, self._Macros)
+ else:
+ PcdValue = ValueList[-1]
+ ValueList[-1] = ReplaceMacro(PcdValue, self._Macros)
+
+ self._ValueList[2] = '|'.join(ValueList)
+
+ def __ProcessComponent(self):
+ self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
+
+ def __ProcessSourceOverridePath(self):
+ self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
+
+ def __ProcessBuildOption(self):
+ self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=False)
+ for Value in self._ValueList]
_SectionParser = {
- MODEL_META_DATA_HEADER : _DefineParser,
- MODEL_EFI_SKU_ID : MetaFileParser._CommonParser,
- MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._PathParser,
- MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser,
- MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
- MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
- MODEL_PCD_FEATURE_FLAG : _PcdParser,
- MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser,
- MODEL_PCD_DYNAMIC_HII : _PcdParser,
- MODEL_PCD_DYNAMIC_VPD : _PcdParser,
- MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser,
- MODEL_PCD_DYNAMIC_EX_HII : _PcdParser,
- MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser,
- MODEL_META_DATA_COMPONENT : _ComponentParser,
- MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : _CompponentSourceOverridePathParser,
- MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser,
- MODEL_UNKNOWN : MetaFileParser._Skip,
- MODEL_META_DATA_USER_EXTENSION : MetaFileParser._Skip,
+ MODEL_META_DATA_HEADER : _DefineParser,
+ MODEL_EFI_SKU_ID : _SkuIdParser,
+ MODEL_EFI_LIBRARY_INSTANCE : _LibraryInstanceParser,
+ MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser,
+ MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
+ MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
+ MODEL_PCD_FEATURE_FLAG : _PcdParser,
+ MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser,
+ MODEL_PCD_DYNAMIC_HII : _PcdParser,
+ MODEL_PCD_DYNAMIC_VPD : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX_HII : _PcdParser,
+ MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser,
+ MODEL_META_DATA_COMPONENT : _ComponentParser,
+ MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : _CompponentSourceOverridePathParser,
+ MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser,
+ MODEL_UNKNOWN : MetaFileParser._Skip,
+ MODEL_META_DATA_USER_EXTENSION : MetaFileParser._Skip,
+ MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser,
+ MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser,
}
+ _Macros = property(_GetMacros)
+
## DEC file parser class
#
# @param FilePath The path of platform description file
@@ -1045,20 +1369,24 @@ class DecParser(MetaFileParser):
# @param Table Database used to retrieve module/package information
# @param Macros Macros used for replacement in file
#
- def __init__(self, FilePath, FileType, Table, Macro=None):
- MetaFileParser.__init__(self, FilePath, FileType, Table, Macro, -1)
+ def __init__(self, FilePath, FileType, Table):
+ # prevent re-initialization
+ if hasattr(self, "_Table"):
+ return
+ MetaFileParser.__init__(self, FilePath, FileType, Table, -1)
self._Comments = []
+ self._Version = 0x00010005 # Only EDK2 dec file is supported
## Parser starter
def Start(self):
+ Content = ''
try:
- if self._Content == None:
- self._Content = open(self.MetaFile, 'r').readlines()
+ Content = open(str(self.MetaFile), 'r').readlines()
except:
EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
- for Index in range(0, len(self._Content)):
- Line, Comment = CleanString2(self._Content[Index])
+ for Index in range(0, len(Content)):
+ Line, Comment = CleanString2(Content[Index])
self._CurrentLine = Line
self._LineIndex = Index
@@ -1074,9 +1402,6 @@ class DecParser(MetaFileParser):
self._SectionHeaderParser()
self._Comments = []
continue
- elif Line.startswith('DEFINE '):
- self._MacroParser()
- continue
elif len(self._SectionType) == 0:
self._Comments = []
continue
@@ -1100,7 +1425,7 @@ class DecParser(MetaFileParser):
self._ValueList[2],
Arch,
ModuleType,
- self._Owner,
+ self._Owner[-1],
self._LineIndex+1,
-1,
self._LineIndex+1,
@@ -1180,6 +1505,7 @@ class DecParser(MetaFileParser):
File=self.MetaFile, Line=self._LineIndex+1, ExtraData=self._CurrentLine)
## [guids], [ppis] and [protocols] section parser
+ @ParseMacro
def _GuidParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
if len(TokenList) < 2:
@@ -1210,6 +1536,7 @@ class DecParser(MetaFileParser):
# [PcdsDynamicEx
# [PcdsDynamic]
#
+ @ParseMacro
def _PcdParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
@@ -1268,6 +1595,7 @@ class DecParser(MetaFileParser):
if not IsValid:
EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
File=self.MetaFile, Line=self._LineIndex+1)
+
if ValueList[0] in ['True', 'true', 'TRUE']:
ValueList[0] = '1'
elif ValueList[0] in ['False', 'false', 'FALSE']:
diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py
index d8dacacd64..f20eab9688 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileTable.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py
@@ -14,14 +14,59 @@
##
# Import Modules
#
+import uuid
+
import Common.EdkLogger as EdkLogger
-from MetaDataTable import Table
+
+from MetaDataTable import Table, TableFile
from MetaDataTable import ConvertToSqlString
+from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \
+ MODEL_FILE_OTHERS
-## Python class representation of table storing module data
-class ModuleTable(Table):
+class MetaFileTable(Table):
# TRICK: use file ID as the part before '.'
_ID_STEP_ = 0.00000001
+ _ID_MAX_ = 0.99999999
+
+ ## Constructor
+ def __init__(self, Cursor, MetaFile, FileType, Temporary):
+ self.MetaFile = MetaFile
+
+ self._FileIndexTable = TableFile(Cursor)
+ self._FileIndexTable.Create(False)
+
+ FileId = self._FileIndexTable.GetFileId(MetaFile)
+ if not FileId:
+ FileId = self._FileIndexTable.InsertFile(MetaFile, FileType)
+
+ if Temporary:
+ TableName = "_%s_%s_%s" % (FileType, FileId, uuid.uuid4().hex)
+ else:
+ TableName = "_%s_%s" % (FileType, FileId)
+
+ #Table.__init__(self, Cursor, TableName, FileId, False)
+ Table.__init__(self, Cursor, TableName, FileId, Temporary)
+ self.Create(not self.IsIntegrity())
+
+ def IsIntegrity(self):
+ try:
+ Result = self.Cur.execute("select ID from %s where ID<0" % (self.Table)).fetchall()
+ if not Result:
+ return False
+
+ TimeStamp = self.MetaFile.TimeStamp
+ if TimeStamp != self._FileIndexTable.GetFileTimeStamp(self.IdBase):
+ # update the timestamp in database
+ self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp)
+ return False
+ except Exception, Exc:
+ EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))
+ return False
+ return True
+
+## Python class representation of table storing module data
+class ModuleTable(MetaFileTable):
+ _ID_STEP_ = 0.00000001
_ID_MAX_ = 0.99999999
_COLUMN_ = '''
ID REAL PRIMARY KEY,
@@ -42,8 +87,8 @@ class ModuleTable(Table):
_DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"
## Constructor
- def __init__(self, Cursor, Name='Inf', IdBase=0, Temporary=False):
- Table.__init__(self, Cursor, Name, IdBase, Temporary)
+ def __init__(self, Cursor, MetaFile, Temporary):
+ MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_INF, Temporary)
## Insert a record into table Inf
#
@@ -100,9 +145,7 @@ class ModuleTable(Table):
return self.Exec(SqlCommand)
## Python class representation of table storing package data
-class PackageTable(Table):
- _ID_STEP_ = 0.00000001
- _ID_MAX_ = 0.99999999
+class PackageTable(MetaFileTable):
_COLUMN_ = '''
ID REAL PRIMARY KEY,
Model INTEGER NOT NULL,
@@ -122,8 +165,8 @@ class PackageTable(Table):
_DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"
## Constructor
- def __init__(self, Cursor, Name='Dec', IdBase=0, Temporary=False):
- Table.__init__(self, Cursor, Name, IdBase, Temporary)
+ def __init__(self, Cursor, MetaFile, Temporary):
+ MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)
## Insert table
#
@@ -179,9 +222,7 @@ class PackageTable(Table):
return self.Exec(SqlCommand)
## Python class representation of table storing platform data
-class PlatformTable(Table):
- _ID_STEP_ = 0.00000001
- _ID_MAX_ = 0.99999999
+class PlatformTable(MetaFileTable):
_COLUMN_ = '''
ID REAL PRIMARY KEY,
Model INTEGER NOT NULL,
@@ -202,8 +243,8 @@ class PlatformTable(Table):
_DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1"
## Constructor
- def __init__(self, Cursor, Name='Dsc', IdBase=0, Temporary=False):
- Table.__init__(self, Cursor, Name, IdBase, Temporary)
+ def __init__(self, Cursor, MetaFile, Temporary):
+ MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary)
## Insert table
#
@@ -254,7 +295,7 @@ class PlatformTable(Table):
# @retval: A recordSet of all found records
#
def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):
- ConditionString = "Model=%s AND Enabled>=0" % Model
+ ConditionString = "Model=%s AND Enabled>0" % Model
ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
if Scope1 != None and Scope1 != 'COMMON':
@@ -273,3 +314,36 @@ class PlatformTable(Table):
SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
return self.Exec(SqlCommand)
+## Factory class to produce different storage for different type of meta-file
+class MetaFileStorage(object):
+ _FILE_TABLE_ = {
+ MODEL_FILE_INF : ModuleTable,
+ MODEL_FILE_DEC : PackageTable,
+ MODEL_FILE_DSC : PlatformTable,
+ MODEL_FILE_OTHERS : MetaFileTable,
+ }
+
+ _FILE_TYPE_ = {
+ ".inf" : MODEL_FILE_INF,
+ ".dec" : MODEL_FILE_DEC,
+ ".dsc" : MODEL_FILE_DSC,
+ }
+
+ ## Constructor
+ def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False):
+ # no type given, try to find one
+ if not FileType:
+ if MetaFile.Type in self._FILE_TYPE_:
+ FileType = Class._FILE_TYPE_[MetaFile.Type]
+ else:
+ FileType = MODEL_FILE_OTHERS
+
+ # don't pass the type around if it's well known
+ if FileType == MODEL_FILE_OTHERS:
+ Args = (Cursor, MetaFile, FileType, Temporary)
+ else:
+ Args = (Cursor, MetaFile, Temporary)
+
+ # create the storage object and return it to caller
+ return Class._FILE_TABLE_[FileType](*Args)
+
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index ac2ca057cc..71e98a94be 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -92,20 +92,14 @@ class DscBuildData(PlatformBuildClassObject):
# @param Platform (not used for DscBuildData)
# @param Macros Macros used for replacement in DSC file
#
- def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):
+ def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
self.MetaFile = FilePath
self._RawData = RawData
self._Bdb = BuildDataBase
self._Arch = Arch
- self._Macros = Macros
+ self._Target = Target
+ self._Toolchain = Toolchain
self._Clear()
- RecordList = self._RawData[MODEL_META_DATA_DEFINE, self._Arch]
- for Record in RecordList:
- GlobalData.gEdkGlobal[Record[0]] = Record[1]
-
- RecordList = self._RawData[MODEL_META_DATA_GLOBAL_DEFINE, self._Arch]
- for Record in RecordList:
- GlobalData.gGlobalDefines[Record[0]] = Record[1]
## XXX[key] = value
def __setitem__(self, key, value):
@@ -145,6 +139,16 @@ class DscBuildData(PlatformBuildClassObject):
self._RFCLanguages = None
self._ISOLanguages = None
self._VpdToolGuid = None
+ self.__Macros = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ self.__Macros.update(GlobalData.gPlatformDefines)
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ self.__Macros.update(GlobalData.gCommandLineDefines)
+ return self.__Macros
## Get architecture
def _GetArch(self):
@@ -172,37 +176,40 @@ class DscBuildData(PlatformBuildClassObject):
def _GetHeaderInfo(self):
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
for Record in RecordList:
- Name = Record[0]
+ Name = Record[1]
# items defined _PROPERTY_ don't need additional processing
if Name in self:
- self[Name] = Record[1]
+ self[Name] = Record[2]
# some special items in [Defines] section need special treatment
elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
- self._OutputDirectory = NormPath(Record[1], self._Macros)
+ self._OutputDirectory = NormPath(Record[2], self._Macros)
if ' ' in self._OutputDirectory:
EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
File=self.MetaFile, Line=Record[-1],
ExtraData=self._OutputDirectory)
elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
- self._FlashDefinition = PathClass(NormPath(Record[1], self._Macros), GlobalData.gWorkspace)
+ self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
ExtraData=ErrorInfo)
elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
- self._SupArchList = GetSplitValueList(Record[1], TAB_VALUE_SPLIT)
+ self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
- self._BuildTargets = GetSplitValueList(Record[1])
+ self._BuildTargets = GetSplitValueList(Record[2])
elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
if self._SkuName == None:
- self._SkuName = Record[1]
+ self._SkuName = Record[2]
elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
- self._LoadFixAddress = Record[1]
+ try:
+ self._LoadFixAddress = int (Record[2], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
- if not Record[1] or Record[1][0] != '"' or Record[1][-1] != '"' or len(Record[1]) == 1:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
File=self.MetaFile, Line=Record[-1])
- LanguageCodes = Record[1][1:-1]
+ LanguageCodes = Record[2][1:-1]
if not LanguageCodes:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
File=self.MetaFile, Line=Record[-1])
@@ -213,10 +220,10 @@ class DscBuildData(PlatformBuildClassObject):
File=self.MetaFile, Line=Record[-1])
self._RFCLanguages = LanguageList
elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
- if not Record[1] or Record[1][0] != '"' or Record[1][-1] != '"' or len(Record[1]) == 1:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
File=self.MetaFile, Line=Record[-1])
- LanguageCodes = Record[1][1:-1]
+ LanguageCodes = Record[2][1:-1]
if not LanguageCodes:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
File=self.MetaFile, Line=Record[-1])
@@ -233,10 +240,10 @@ class DscBuildData(PlatformBuildClassObject):
# for VPD_TOOL_GUID is correct.
#
try:
- uuid.UUID(Record[1])
+ uuid.UUID(Record[2])
except:
EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
- self._VpdToolGuid = Record[1]
+ self._VpdToolGuid = Record[2]
# set _Header to non-None in order to avoid database re-querying
self._Header = 'DUMMY'
@@ -368,8 +375,18 @@ class DscBuildData(PlatformBuildClassObject):
if self._LoadFixAddress == None:
if self._Header == None:
self._GetHeaderInfo()
+
if self._LoadFixAddress == None:
- self._LoadFixAddress = ''
+ self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
+
+ try:
+ self._LoadFixAddress = int (self._LoadFixAddress, 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
+ if self._LoadFixAddress < 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value %s" % (self._LoadFixAddress))
+ if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value %s" % (self._LoadFixAddress))
return self._LoadFixAddress
## Retrieve RFCLanguage filter
@@ -389,7 +406,6 @@ class DscBuildData(PlatformBuildClassObject):
if self._ISOLanguages == None:
self._ISOLanguages = []
return self._ISOLanguages
-
## Retrieve the GUID string for VPD tool
def _GetVpdToolGuid(self):
if self._VpdToolGuid == None:
@@ -402,8 +418,8 @@ class DscBuildData(PlatformBuildClassObject):
## Retrieve [SkuIds] section information
def _GetSkuIds(self):
if self._SkuIds == None:
- self._SkuIds = {}
- RecordList = self._RawData[MODEL_EFI_SKU_ID]
+ self._SkuIds = sdict()
+ RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
for Record in RecordList:
if Record[0] in [None, '']:
EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
@@ -423,8 +439,8 @@ class DscBuildData(PlatformBuildClassObject):
self._Modules = sdict()
RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
for Record in RecordList:
ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
ModuleId = Record[5]
@@ -530,9 +546,8 @@ class DscBuildData(PlatformBuildClassObject):
LibraryClassDict = tdict(True, 3)
# track all library class names
LibraryClassSet = set()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
+ Macros = self._Macros
for Record in RecordList:
LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record
if LibraryClass == '' or LibraryClass == 'NULL':
@@ -564,7 +579,8 @@ class DscBuildData(PlatformBuildClassObject):
continue
self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
- # for EDK style library instances, which are listed in different section
+ # for Edk style library instances, which are listed in different section
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
@@ -581,14 +597,14 @@ class DscBuildData(PlatformBuildClassObject):
# to parse it here. (self._Bdb[] will trigger a file parse if it
# hasn't been parsed)
#
- Library = self._Bdb[File, self._Arch]
+ Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
return self._LibraryClasses
## Retrieve all PCD settings in platform
def _GetPcds(self):
if self._Pcds == None:
- self._Pcds = {}
+ self._Pcds = sdict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
@@ -603,17 +619,17 @@ class DscBuildData(PlatformBuildClassObject):
## Retrieve [BuildOptions]
def _GetBuildOptions(self):
if self._BuildOptions == None:
- self._BuildOptions = {}
+ self._BuildOptions = sdict()
#
# Retrieve build option for EDKII style module
#
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDKII_NAME]
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDKII_NAME]
for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option
#
# Retrieve build option for EDK style module
#
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDK_NAME]
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDK_NAME]
for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option
return self._BuildOptions
@@ -625,7 +641,7 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH
@@ -664,7 +680,7 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
@@ -706,7 +722,7 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicHiiPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
@@ -746,7 +762,7 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicVpdPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
@@ -814,6 +830,7 @@ class DscBuildData(PlatformBuildClassObject):
self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
self.Pcds[Name, Guid].DefaultValue = Value
+ _Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
Platform = property(_GetPlatformName)
PlatformName = property(_GetPlatformName)
@@ -884,13 +901,14 @@ class DecBuildData(PackageBuildClassObject):
# @param Platform (not used for DecBuildData)
# @param Macros Macros used for replacement in DSC file
#
- def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):
+ def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
self.MetaFile = File
self._PackageDir = File.Dir
self._RawData = RawData
self._Bdb = BuildDataBase
self._Arch = Arch
- self._Macros = Macros
+ self._Target = Target
+ self._Toolchain = Toolchain
self._Clear()
## XXX[key] = value
@@ -918,6 +936,14 @@ class DecBuildData(PackageBuildClassObject):
self._Includes = None
self._LibraryClasses = None
self._Pcds = None
+ self.__Macros = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ return self.__Macros
## Get architecture
def _GetArch(self):
@@ -943,11 +969,11 @@ class DecBuildData(PackageBuildClassObject):
# (Retriving all [Defines] information in one-shot is just to save time.)
#
def _GetHeaderInfo(self):
- RecordList = self._RawData[MODEL_META_DATA_HEADER]
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
for Record in RecordList:
- Name = Record[0]
+ Name = Record[1]
if Name in self:
- self[Name] = Record[1]
+ self[Name] = Record[2]
self._Header = 'DUMMY'
## Retrieve package name
@@ -1057,8 +1083,8 @@ class DecBuildData(PackageBuildClassObject):
if self._Includes == None:
self._Includes = []
RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
LineNo = Record[-1]
@@ -1082,8 +1108,7 @@ class DecBuildData(PackageBuildClassObject):
LibraryClassDict = tdict(True)
LibraryClassSet = set()
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:
File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
# check the file validation
@@ -1100,7 +1125,7 @@ class DecBuildData(PackageBuildClassObject):
## Retrieve PCD declarations
def _GetPcds(self):
if self._Pcds == None:
- self._Pcds = {}
+ self._Pcds = sdict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
@@ -1110,7 +1135,7 @@ class DecBuildData(PackageBuildClassObject):
## Retrieve PCD declarations for given type
def _GetPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special kind of dict, used for selecting correct
# PCD declaration for given ARCH
@@ -1150,6 +1175,7 @@ class DecBuildData(PackageBuildClassObject):
return Pcds
+ _Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
PackageName = property(_GetPackageName)
Guid = property(_GetFileGuid)
@@ -1194,7 +1220,7 @@ class InfBuildData(ModuleBuildClassObject):
#
# Optional Fields
#
- TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
+ #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
#TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
@@ -1249,14 +1275,15 @@ class InfBuildData(ModuleBuildClassObject):
# @param Platform The name of platform employing this module
# @param Macros Macros used for replacement in DSC file
#
- def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Platform='COMMON', Macros={}):
+ def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):
self.MetaFile = FilePath
self._ModuleDir = FilePath.Dir
self._RawData = RawData
self._Bdb = BuildDatabase
self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
self._Platform = 'COMMON'
- self._Macros = Macros
self._SourceOverridePath = None
if FilePath.Key in GlobalData.gOverrideDir:
self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]
@@ -1310,7 +1337,17 @@ class InfBuildData(ModuleBuildClassObject):
self._BuildOptions = None
self._Depex = None
self._DepexExpression = None
- #self._SourceOverridePath = None
+ self.__Macros = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ # EDK_GLOBAL defined macros can be applied to EDK modoule
+ if self.AutoGenVersion < 0x00010005:
+ self.__Macros.update(GlobalData.gEdkGlobal)
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ return self.__Macros
## Get architecture
def _GetArch(self):
@@ -1354,26 +1391,25 @@ class InfBuildData(ModuleBuildClassObject):
def _GetHeaderInfo(self):
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
- Name = Record[0]
+ Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)
# items defined _PROPERTY_ don't need additional processing
if Name in self:
- self[Name] = Record[1]
+ self[Name] = Value
# some special items in [Defines] section need special treatment
elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
Name = 'UEFI_SPECIFICATION_VERSION'
if self._Specification == None:
self._Specification = sdict()
- self._Specification[Name] = GetHexVerValue(Record[1])
+ self._Specification[Name] = GetHexVerValue(Value)
if self._Specification[Name] == None:
EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
- "'%s' format is not supported for %s" % (Record[1], Name),
+ "'%s' format is not supported for %s" % (Value, Name),
File=self.MetaFile, Line=Record[-1])
elif Name == 'LIBRARY_CLASS':
if self._LibraryClass == None:
self._LibraryClass = []
- ValueList = GetSplitValueList(Record[1])
+ ValueList = GetSplitValueList(Value)
LibraryClass = ValueList[0]
if len(ValueList) > 1:
SupModuleList = GetSplitValueList(ValueList[1], ' ')
@@ -1383,27 +1419,27 @@ class InfBuildData(ModuleBuildClassObject):
elif Name == 'ENTRY_POINT':
if self._ModuleEntryPointList == None:
self._ModuleEntryPointList = []
- self._ModuleEntryPointList.append(Record[1])
+ self._ModuleEntryPointList.append(Value)
elif Name == 'UNLOAD_IMAGE':
if self._ModuleUnloadImageList == None:
self._ModuleUnloadImageList = []
- if Record[1] == '':
+ if not Value:
continue
- self._ModuleUnloadImageList.append(Record[1])
+ self._ModuleUnloadImageList.append(Value)
elif Name == 'CONSTRUCTOR':
if self._ConstructorList == None:
self._ConstructorList = []
- if Record[1] == '':
+ if not Value:
continue
- self._ConstructorList.append(Record[1])
+ self._ConstructorList.append(Value)
elif Name == 'DESTRUCTOR':
if self._DestructorList == None:
self._DestructorList = []
- if Record[1] == '':
+ if not Value:
continue
- self._DestructorList.append(Record[1])
+ self._DestructorList.append(Value)
elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
- TokenList = GetSplitValueList(Record[1])
+ TokenList = GetSplitValueList(Value)
if self._CustomMakefile == None:
self._CustomMakefile = {}
if len(TokenList) < 2:
@@ -1418,25 +1454,25 @@ class InfBuildData(ModuleBuildClassObject):
else:
if self._Defs == None:
self._Defs = sdict()
- self._Defs[Name] = Record[1]
+ self._Defs[Name] = Value
#
- # Retrieve information in sections specific to EDK.x modules
+ # Retrieve information in sections specific to Edk.x modules
#
- if self._AutoGenVersion >= 0x00010005: # _AutoGenVersion may be None, which is less than anything
+ if self.AutoGenVersion >= 0x00010005:
if not self._ModuleType:
EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
"MODULE_TYPE is not given", File=self.MetaFile)
if self._ModuleType not in SUP_MODULE_LIST:
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
for Record in RecordList:
- Name = Record[0]
+ Name = Record[1]
if Name == "MODULE_TYPE":
LineNo = Record[6]
break
EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
"MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType,' '.join(l for l in SUP_MODULE_LIST)),
- File=self.MetaFile, Line=LineNo)
+ File=self.MetaFile, Line=LineNo)
if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
if self._ModuleType == SUP_MODULE_SMM_CORE:
EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)
@@ -1459,29 +1495,28 @@ class InfBuildData(ModuleBuildClassObject):
if self.Sources == None:
self._Sources = []
self._Sources.append(File)
- else:
- self._BuildType = self._ComponentType.upper()
+ else:
if not self._ComponentType:
EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
"COMPONENT_TYPE is not given", File=self.MetaFile)
+ self._BuildType = self._ComponentType.upper()
if self._ComponentType in self._MODULE_TYPE_:
self._ModuleType = self._MODULE_TYPE_[self._ComponentType]
if self._ComponentType == 'LIBRARY':
self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]
# make use some [nmake] section macros
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]
for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:
- Value = Value.replace('$(PROCESSOR)', self._Arch)
- Name = Name.replace('$(PROCESSOR)', self._Arch)
- Name, Value = ReplaceMacros((Name, Value), GlobalData.gEdkGlobal, True)
+ Value = ReplaceMacro(Value, Macros, True)
if Name == "IMAGE_ENTRY_POINT":
if self._ModuleEntryPointList == None:
self._ModuleEntryPointList = []
self._ModuleEntryPointList.append(Value)
elif Name == "DPX_SOURCE":
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
- File = PathClass(NormPath(Value, Macros), self._ModuleDir, Arch=self._Arch)
+ File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)
# check the file validation
ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
if ErrorCode != 0:
@@ -1505,9 +1540,9 @@ class InfBuildData(ModuleBuildClassObject):
else:
Tool = ToolList[0]
ToolChain = "*_*_*_%s_FLAGS" % Tool
- ToolChainFamily = 'MSFT' # EDK.x only support MSFT tool chain
+ ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain
#ignore not replaced macros in value
- ValueList = GetSplitValueList(' ' + Value, '/D')
+ ValueList = GetSplitList(' ' + Value, '/D')
Dummy = ValueList[0]
for Index in range(1, len(ValueList)):
if ValueList[Index][-1] == '=' or ValueList[Index] == '':
@@ -1525,8 +1560,11 @@ class InfBuildData(ModuleBuildClassObject):
## Retrieve file version
def _GetInfVersion(self):
if self._AutoGenVersion == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
+ for Record in RecordList:
+ if Record[1] == TAB_INF_DEFINES_INF_VERSION:
+ self._AutoGenVersion = int(Record[2], 0)
+ break
if self._AutoGenVersion == None:
self._AutoGenVersion = 0x00010000
return self._AutoGenVersion
@@ -1693,10 +1731,10 @@ class InfBuildData(ModuleBuildClassObject):
if self._Binaries == None:
self._Binaries = []
RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
FileType = Record[0]
LineNo = Record[-1]
Target = 'COMMON'
@@ -1721,17 +1759,17 @@ class InfBuildData(ModuleBuildClassObject):
if self._Sources == None:
self._Sources = []
RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
LineNo = Record[-1]
ToolChainFamily = Record[1]
TagName = Record[2]
ToolCode = Record[3]
FeatureFlag = Record[4]
- if self._AutoGenVersion < 0x00010005:
- # old module source files (EDK)
+ if self.AutoGenVersion < 0x00010005:
+ # old module source files (Edk)
File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,
'', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
# check the file validation
@@ -1760,23 +1798,22 @@ class InfBuildData(ModuleBuildClassObject):
self._LibraryClasses = sdict()
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
Lib = Record[0]
Instance = Record[1]
- if Instance != None and Instance != '':
+ if Instance:
Instance = NormPath(Instance, self._Macros)
self._LibraryClasses[Lib] = Instance
return self._LibraryClasses
- ## Retrieve library names (for EDK.x style of modules)
+ ## Retrieve library names (for Edk.x style of modules)
def _GetLibraryNames(self):
if self._Libraries == None:
self._Libraries = []
RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]
for Record in RecordList:
- # in case of name with '.lib' extension, which is unusual in EDK.x inf
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
- LibraryName = os.path.splitext(Record[0])[0]
+ LibraryName = ReplaceMacro(Record[0], self._Macros, False)
+ # in case of name with '.lib' extension, which is unusual in Edk.x inf
+ LibraryName = os.path.splitext(LibraryName)[0]
if LibraryName not in self._Libraries:
self._Libraries.append(LibraryName)
return self._Libraries
@@ -1829,23 +1866,23 @@ class InfBuildData(ModuleBuildClassObject):
self._Guids[CName] = Value
return self._Guids
- ## Retrieve include paths necessary for this module (for EDK.x style of modules)
+ ## Retrieve include paths necessary for this module (for Edk.x style of modules)
def _GetIncludes(self):
if self._Includes == None:
self._Includes = []
if self._SourceOverridePath:
self._Includes.append(self._SourceOverridePath)
+
+ Macros = self._Macros
+ if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():
+ Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']
+ else:
+ Macros['PROCESSOR'] = self._Arch
RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
- # [includes] section must be used only in old (EDK.x) inf file
- if self.AutoGenVersion >= 0x00010005 and len(RecordList) > 0:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, "No [include] section allowed",
- File=self.MetaFile, Line=RecordList[0][-1]-1)
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
- Record[0] = Record[0].replace('$(PROCESSOR)', self._Arch)
- Record[0] = ReplaceMacro(Record[0], {'EFI_SOURCE' : GlobalData.gEfiSource}, False)
if Record[0].find('EDK_SOURCE') > -1:
- File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEcpSource}, False), self._Macros)
+ Macros['EDK_SOURCE'] = GlobalData.gEcpSource
+ File = NormPath(Record[0], self._Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
@@ -1855,7 +1892,8 @@ class InfBuildData(ModuleBuildClassObject):
self._Includes.append(File)
#TRICK: let compiler to choose correct header file
- File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEdkSource}, False), self._Macros)
+ Macros['EDK_SOURCE'] = GlobalData.gEdkSource
+ File = NormPath(Record[0], self._Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
@@ -1864,7 +1902,7 @@ class InfBuildData(ModuleBuildClassObject):
if File:
self._Includes.append(File)
else:
- File = NormPath(Record[0], self._Macros)
+ File = NormPath(Record[0], Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
@@ -1879,8 +1917,8 @@ class InfBuildData(ModuleBuildClassObject):
if self._Packages == None:
self._Packages = []
RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros['EDK_SOURCE'] = GlobalData.gEcpSource
for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
LineNo = Record[-1]
@@ -1889,7 +1927,7 @@ class InfBuildData(ModuleBuildClassObject):
if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
# parse this package now. we need it to get protocol/ppi/guid value
- Package = self._Bdb[File, self._Arch]
+ Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
self._Packages.append(Package)
return self._Packages
@@ -1921,7 +1959,7 @@ class InfBuildData(ModuleBuildClassObject):
self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
return self._BuildOptions
- ## Retrieve depedency expression
+ ## Retrieve dependency expression
def _GetDepex(self):
if self._Depex == None:
self._Depex = tdict(False, 2)
@@ -1929,8 +1967,8 @@ class InfBuildData(ModuleBuildClassObject):
# If the module has only Binaries and no Sources, then ignore [Depex]
if self.Sources == None or self.Sources == []:
- if self.Binaries <> None and self.Binaries <> []:
- return self._Depex
+ if self.Binaries != None and self.Binaries != []:
+ return self._Depex
# PEIM and DXE drivers must have a valid [Depex] section
if len(self.LibraryClass) == 0 and len(RecordList) == 0:
@@ -1939,12 +1977,12 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
% self.ModuleType, File=self.MetaFile)
- Depex = {}
+ Depex = sdict()
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
+ DepexStr = ReplaceMacro(Record[0], self._Macros, False)
Arch = Record[3]
ModuleType = Record[4]
- TokenList = Record[0].split()
+ TokenList = DepexStr.split()
if (Arch, ModuleType) not in Depex:
Depex[Arch, ModuleType] = []
DepexList = Depex[Arch, ModuleType]
@@ -1980,12 +2018,12 @@ class InfBuildData(ModuleBuildClassObject):
if self._DepexExpression == None:
self._DepexExpression = tdict(False, 2)
RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
- DepexExpression = {}
+ DepexExpression = sdict()
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
+ DepexStr = ReplaceMacro(Record[0], self._Macros, False)
Arch = Record[3]
ModuleType = Record[4]
- TokenList = Record[0].split()
+ TokenList = DepexStr.split()
if (Arch, ModuleType) not in DepexExpression:
DepexExpression[Arch, ModuleType] = ''
for Token in TokenList:
@@ -2123,6 +2161,7 @@ class InfBuildData(ModuleBuildClassObject):
return Pcds
+ _Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
Platform = property(_GetPlatform, _SetPlatform)
@@ -2170,21 +2209,6 @@ class InfBuildData(ModuleBuildClassObject):
# @prarm RenewDb=False Create new database file if it's already there
#
class WorkspaceDatabase(object):
- # file parser
- _FILE_PARSER_ = {
- MODEL_FILE_INF : InfParser,
- MODEL_FILE_DEC : DecParser,
- MODEL_FILE_DSC : DscParser,
- MODEL_FILE_FDF : None, #FdfParser,
- MODEL_FILE_CIF : None
- }
-
- # file table
- _FILE_TABLE_ = {
- MODEL_FILE_INF : ModuleTable,
- MODEL_FILE_DEC : PackageTable,
- MODEL_FILE_DSC : PlatformTable,
- }
# default database file path
_DB_PATH_ = "Conf/.cache/build.db"
@@ -2194,11 +2218,18 @@ class WorkspaceDatabase(object):
# to avoid unnecessary re-parsing
#
class BuildObjectFactory(object):
+
_FILE_TYPE_ = {
".inf" : MODEL_FILE_INF,
".dec" : MODEL_FILE_DEC,
".dsc" : MODEL_FILE_DSC,
- ".fdf" : MODEL_FILE_FDF,
+ }
+
+ # file parser
+ _FILE_PARSER_ = {
+ MODEL_FILE_INF : InfParser,
+ MODEL_FILE_DEC : DecParser,
+ MODEL_FILE_DSC : DscParser,
}
# convert to xxxBuildData object
@@ -2206,7 +2237,6 @@ class WorkspaceDatabase(object):
MODEL_FILE_INF : InfBuildData,
MODEL_FILE_DEC : DecBuildData,
MODEL_FILE_DSC : DscBuildData,
- MODEL_FILE_FDF : None #FlashDefTable,
}
_CACHE_ = {} # (FilePath, Arch) : <object>
@@ -2215,46 +2245,61 @@ class WorkspaceDatabase(object):
def __init__(self, WorkspaceDb):
self.WorkspaceDb = WorkspaceDb
- # key = (FilePath, Arch='COMMON')
+ # key = (FilePath, Arch=None)
def __contains__(self, Key):
FilePath = Key[0]
- Arch = 'COMMON'
if len(Key) > 1:
Arch = Key[1]
+ else:
+ Arch = None
return (FilePath, Arch) in self._CACHE_
- # key = (FilePath, Arch='COMMON')
+ # key = (FilePath, Arch=None, Target=None, Toochain=None)
def __getitem__(self, Key):
FilePath = Key[0]
- Arch = 'COMMON'
- Platform = 'COMMON'
- if len(Key) > 1:
+ KeyLength = len(Key)
+ if KeyLength > 1:
Arch = Key[1]
- if len(Key) > 2:
- Platform = Key[2]
+ else:
+ Arch = None
+ if KeyLength > 2:
+ Target = Key[2]
+ else:
+ Target = None
+ if KeyLength > 3:
+ Toolchain = Key[3]
+ else:
+ Toolchain = None
# if it's generated before, just return the cached one
- Key = (FilePath, Arch)
+ Key = (FilePath, Arch, Target, Toolchain)
if Key in self._CACHE_:
return self._CACHE_[Key]
# check file type
- Ext = FilePath.Ext.lower()
+ Ext = FilePath.Type
if Ext not in self._FILE_TYPE_:
return None
FileType = self._FILE_TYPE_[Ext]
if FileType not in self._GENERATOR_:
return None
- # get table for current file
- MetaFile = self.WorkspaceDb[FilePath, FileType, self.WorkspaceDb._GlobalMacros]
+ # get the parser ready for this file
+ MetaFile = self._FILE_PARSER_[FileType](
+ FilePath,
+ FileType,
+ MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType)
+ )
+ # alwasy do post-process, in case of macros change
+ MetaFile.DoPostProcess()
+ # object the build is based on
BuildObject = self._GENERATOR_[FileType](
FilePath,
MetaFile,
self,
Arch,
- Platform,
- self.WorkspaceDb._GlobalMacros,
+ Target,
+ Toolchain
)
self._CACHE_[Key] = BuildObject
return BuildObject
@@ -2274,11 +2319,9 @@ class WorkspaceDatabase(object):
# @param GlobalMacros Global macros used for replacement during file parsing
# @prarm RenewDb=False Create new database file if it's already there
#
- def __init__(self, DbPath, GlobalMacros={}, RenewDb=False):
+ def __init__(self, DbPath, RenewDb=False):
self._DbClosedFlag = False
- self._GlobalMacros = GlobalMacros
-
- if DbPath == None or DbPath == '':
+ if not DbPath:
DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))
# don't create necessary path for db in memory
@@ -2306,6 +2349,7 @@ class WorkspaceDatabase(object):
# create table for internal uses
self.TblDataModel = TableDataModel(self.Cur)
self.TblFile = TableFile(self.Cur)
+ self.Platform = None
# conversion object for build or file format conversion purpose
self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)
@@ -2324,41 +2368,6 @@ class WorkspaceDatabase(object):
# @return Bool value for whether need renew workspace databse
#
def _CheckWhetherDbNeedRenew (self, force, DbPath):
- DbDir = os.path.split(DbPath)[0]
- MacroFilePath = os.path.normpath(os.path.join(DbDir, "build.mac"))
- MacroMatch = False
- if os.path.exists(MacroFilePath) and os.path.isfile(MacroFilePath):
- LastMacros = None
- try:
- f = open(MacroFilePath,'r')
- LastMacros = pickle.load(f)
- f.close()
- except IOError:
- pass
- except:
- f.close()
-
- if LastMacros != None and type(LastMacros) is DictType:
- if LastMacros == self._GlobalMacros:
- MacroMatch = True
- for Macro in LastMacros.keys():
- if not (Macro in self._GlobalMacros and LastMacros[Macro] == self._GlobalMacros[Macro]):
- MacroMatch = False;
- break;
-
- if not MacroMatch:
- # save command line macros to file
- try:
- f = open(MacroFilePath,'w')
- pickle.dump(self._GlobalMacros, f, 2)
- f.close()
- except IOError:
- pass
- except:
- f.close()
-
- force = True
-
# if database does not exist, we need do nothing
if not os.path.exists(DbPath): return False
@@ -2423,6 +2432,9 @@ determine whether database file is out of date!\n")
def QueryTable(self, Table):
Table.Query()
+ def __del__(self):
+ self.Close()
+
## Close entire database
#
# Commit all first
@@ -2435,83 +2447,28 @@ determine whether database file is out of date!\n")
self.Conn.close()
self._DbClosedFlag = True
- ## Get unique file ID for the gvien file
- def GetFileId(self, FilePath):
- return self.TblFile.GetFileId(FilePath)
-
- ## Get file type value for the gvien file ID
- def GetFileType(self, FileId):
- return self.TblFile.GetFileType(FileId)
-
- ## Get time stamp stored in file table
- def GetTimeStamp(self, FileId):
- return self.TblFile.GetFileTimeStamp(FileId)
-
- ## Update time stamp in file table
- def SetTimeStamp(self, FileId, TimeStamp):
- return self.TblFile.SetFileTimeStamp(FileId, TimeStamp)
-
- ## Check if a table integrity flag exists or not
- def CheckIntegrity(self, TableName):
- try:
- Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall()
- if Result[0][0] != -1:
- return False
- #
- # Check whether the meta data file has external dependency by comparing the time stamp
- #
- Sql = "select Value1, Value2 from %s where Model=%d" % (TableName, MODEL_EXTERNAL_DEPENDENCY)
- for Dependency in self.Cur.execute(Sql).fetchall():
- if str(os.stat(Dependency[0])[8]) != Dependency[1]:
- return False
- except:
- return False
- return True
-
- ## Compose table name for given file type and file ID
- def GetTableName(self, FileType, FileId):
- return "_%s_%s" % (FileType, FileId)
-
- ## Return a temp table containing all content of the given file
- #
- # @param FileInfo The tuple containing path and type of a file
- #
- def __getitem__(self, FileInfo):
- FilePath, FileType, Macros = FileInfo
- if FileType not in self._FILE_TABLE_:
- return None
-
- # flag used to indicate if it's parsed or not
- FilePath = str(FilePath)
- Parsed = False
- FileId = self.GetFileId(FilePath)
- if FileId != None:
- TimeStamp = os.stat(FilePath)[8]
- TableName = self.GetTableName(FileType, FileId)
- if TimeStamp != self.GetTimeStamp(FileId):
- # update the timestamp in database
- self.SetTimeStamp(FileId, TimeStamp)
- else:
- # if the table exists and is integrity, don't parse it
- Parsed = self.CheckIntegrity(TableName)
- else:
- FileId = self.TblFile.InsertFile(FilePath, FileType)
- TableName = self.GetTableName(FileType, FileId)
-
- FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)
- FileTable.Create(not Parsed)
- Parser = self._FILE_PARSER_[FileType](FilePath, FileType, FileTable, Macros)
- # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)
- Parser.Finished = Parsed
- return Parser
-
## Summarize all packages in the database
- def _GetPackageList(self):
- PackageList = []
- for Module in self.ModuleList:
- for Package in Module.Packages:
+ def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):
+ self.Platform = Platform
+ PackageList =[]
+ Pa = self.BuildObject[self.Platform, 'COMMON']
+ #
+ # Get Package related to Modules
+ #
+ for Module in Pa.Modules:
+ ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]
+ for Package in ModuleObj.Packages:
if Package not in PackageList:
PackageList.append(Package)
+ #
+ # Get Packages related to Libraries
+ #
+ for Lib in Pa.LibraryInstances:
+ LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]
+ for Package in LibObj.Packages:
+ if Package not in PackageList:
+ PackageList.append(Package)
+
return PackageList
## Summarize all platforms in the database
@@ -2526,21 +2483,7 @@ determine whether database file is out of date!\n")
PlatformList.append(Platform)
return PlatformList
- ## Summarize all modules in the database
- def _GetModuleList(self):
- ModuleList = []
- for ModuleFile in self.TblFile.GetFileList(MODEL_FILE_INF):
- try:
- Module = self.BuildObject[PathClass(ModuleFile), 'COMMON']
- except:
- Module = None
- if Module != None:
- ModuleList.append(Module)
- return ModuleList
-
PlatformList = property(_GetPlatformList)
- PackageList = property(_GetPackageList)
- ModuleList = property(_GetModuleList)
##
#
diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py
index c6e49f9999..f3555d705d 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -4,7 +4,7 @@
# This module contains the functionality to generate build report after
# build all target completes successfully.
#
-# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -184,16 +184,17 @@ class DepexParser(object):
#
def __init__(self, Wa):
self._GuidDb = {}
- for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:
- for Protocol in Package.Protocols:
- GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])
- self._GuidDb[GuidValue.upper()] = Protocol
- for Ppi in Package.Ppis:
- GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])
- self._GuidDb[GuidValue.upper()] = Ppi
- for Guid in Package.Guids:
- GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])
- self._GuidDb[GuidValue.upper()] = Guid
+ for Pa in Wa.AutoGenObjectList:
+ for Package in Pa.PackageList:
+ for Protocol in Package.Protocols:
+ GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])
+ self._GuidDb[GuidValue.upper()] = Protocol
+ for Ppi in Package.Ppis:
+ GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])
+ self._GuidDb[GuidValue.upper()] = Ppi
+ for Guid in Package.Guids:
+ GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])
+ self._GuidDb[GuidValue.upper()] = Guid
##
# Parse the binary dependency expression files.
@@ -486,7 +487,7 @@ class ModuleReport(object):
#
if ModuleType == "DXE_SMM_DRIVER":
PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")
- if int(PiSpec, 16) >= 0x0001000A:
+ if int(PiSpec, 0) >= 0x0001000A:
ModuleType = "SMM_DRIVER"
self.DriverType = gDriverTypeMap.get(ModuleType, "0x2 (FREE_FORM)")
self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "")
@@ -641,10 +642,11 @@ class PcdReport(object):
# Collect PCD DEC default value.
#
self.DecPcdDefault = {}
- for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:
- for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
- DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
- self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)
+ for Pa in Wa.AutoGenObjectList:
+ for Package in Pa.PackageList:
+ for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
+ DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
+ self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)
#
# Collect PCDs defined in DSC common section
#
@@ -1174,14 +1176,14 @@ class FdRegionReport(object):
self._DiscoverNestedFvList(FvName, Wa)
PlatformPcds = {}
-
#
# Collect PCDs declared in DEC files.
- #
- for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:
- for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
- DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
- PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue
+ #
+ for Pa in Wa.AutoGenObjectList:
+ for Package in Pa.PackageList:
+ for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
+ DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
+ PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue
#
# Collect PCDs defined in DSC common section
#
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 9502bf3364..0319103138 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -172,6 +172,12 @@ def CheckEnvVariable():
GlobalData.gEdkSource = EdkSourceDir
GlobalData.gEcpSource = EcpSourceDir
+ GlobalData.gGlobalDefines["WORKSPACE"] = WorkspaceDir
+ GlobalData.gGlobalDefines["EFI_SOURCE"] = EfiSourceDir
+ GlobalData.gGlobalDefines["EDK_SOURCE"] = EdkSourceDir
+ GlobalData.gGlobalDefines["ECP_SOURCE"] = EcpSourceDir
+ GlobalData.gGlobalDefines["EDK_TOOLS_PATH"] = os.environ["EDK_TOOLS_PATH"]
+
## Get normalized file path
#
# Convert the path to be local format, and remove the WORKSPACE path at the
@@ -301,10 +307,14 @@ class BuildUnit:
self.WorkingDir = WorkingDir
self.Target = Target
self.BuildCommand = BuildCommand
- if BuildCommand == None or len(BuildCommand) == 0:
- EdkLogger.error("build", OPTION_MISSING, "No build command found for",
+ if not BuildCommand:
+ EdkLogger.error("build", OPTION_MISSING,
+ "No build command found for this module. "
+ "Please check your setting of %s_%s_%s_MAKE_PATH in Conf/tools_def.txt file." %
+ (Obj.BuildTarget, Obj.ToolChain, Obj.Arch),
ExtraData=str(Obj))
+
## str() method
#
# It just returns the string representation of self.BuildObject
@@ -690,93 +700,59 @@ class Build():
#
# @param Target The build command target, one of gSupportedTarget
# @param WorkspaceDir The directory of workspace
- # @param Platform The DSC file of active platform
- # @param Module The INF file of active module, if any
- # @param Arch The Arch list of platform or module
- # @param ToolChain The name list of toolchain
- # @param BuildTarget The "DEBUG" or "RELEASE" build
- # @param FlashDefinition The FDF file of active platform
- # @param FdList=[] The FD names to be individually built
- # @param FvList=[] The FV names to be individually built
- # @param MakefileType The type of makefile (for MSFT make or GNU make)
- # @param SilentMode Indicate multi-thread build mode
- # @param ThreadNumber The maximum number of thread if in multi-thread build mode
- # @param SkipAutoGen Skip AutoGen step
- # @param Reparse Re-parse all meta files
- # @param SkuId SKU id from command line
- #
- def __init__(self, Target, WorkspaceDir, Platform, Module, Arch, ToolChain,
- BuildTarget, FlashDefinition, FdList=[], FvList=[], CapList=[],
- MakefileType="nmake", SilentMode=False, ThreadNumber=2,
- SkipAutoGen=False, Reparse=False, SkuId=None,
- ReportFile=None, ReportType=None, UniFlag=None):
-
- self.WorkspaceDir = WorkspaceDir
+ # @param BuildOptions Build options passed from command line
+ #
+ def __init__(self, Target, WorkspaceDir, BuildOptions):
+ self.WorkspaceDir = WorkspaceDir
self.Target = Target
- self.PlatformFile = Platform
- self.ModuleFile = Module
- self.ArchList = Arch
- self.ToolChainList = ToolChain
- self.BuildTargetList= BuildTarget
- self.Fdf = FlashDefinition
- self.FdList = FdList
- self.FvList = FvList
- self.CapList = CapList
- self.MakefileType = MakefileType
- self.SilentMode = SilentMode
- self.ThreadNumber = ThreadNumber
- self.SkipAutoGen = SkipAutoGen
- self.Reparse = Reparse
- self.SkuId = SkuId
+ self.PlatformFile = BuildOptions.PlatformFile
+ self.ModuleFile = BuildOptions.ModuleFile
+ self.ArchList = BuildOptions.TargetArch
+ self.ToolChainList = BuildOptions.ToolChain
+ self.BuildTargetList= BuildOptions.BuildTarget
+ self.Fdf = BuildOptions.FdfFile
+ self.FdList = BuildOptions.RomImage
+ self.FvList = BuildOptions.FvImage
+ self.CapList = BuildOptions.CapName
+ self.SilentMode = BuildOptions.SilentMode
+ self.ThreadNumber = BuildOptions.ThreadNumber
+ self.SkipAutoGen = BuildOptions.SkipAutoGen
+ self.Reparse = BuildOptions.Reparse
+ self.SkuId = BuildOptions.SkuId
self.SpawnMode = True
- self.BuildReport = BuildReport(ReportFile, ReportType)
+ self.BuildReport = BuildReport(BuildOptions.ReportFile, BuildOptions.ReportType)
self.TargetTxt = TargetTxtClassObject()
self.ToolDef = ToolDefClassObject()
- self.Db = WorkspaceDatabase(None, GlobalData.gGlobalDefines, self.Reparse)
- #self.Db = WorkspaceDatabase(None, {}, self.Reparse)
+ if BuildOptions.DisableCache:
+ self.Db = WorkspaceDatabase(":memory:")
+ else:
+ self.Db = WorkspaceDatabase(None, self.Reparse)
self.BuildDatabase = self.Db.BuildObject
self.Platform = None
self.LoadFixAddress = 0
- self.UniFlag = UniFlag
+ self.UniFlag = BuildOptions.Flag
# print dot character during doing some time-consuming work
self.Progress = Utils.Progressor()
- # parse target.txt, tools_def.txt, and platform file
- #self.RestoreBuildData()
- self.LoadConfiguration()
-
- #
- # @attention Treat $(TARGET)/$(TOOL_CHAIN_TAG) in meta data files as special macro when it has only one build target/toolchain.
- # This is not a complete support for $(TARGET)/$(TOOL_CHAIN_TAG) macro as it can only support one build target/toolchain in ONE
- # invocation of build command. However, it should cover the frequent usage model that $(TARGET)/$(TOOL_CHAIN_TAG) macro
- # is used in DSC/FDF files to specify different libraries & PCD setting for debug/release build.
- #
- if len(self.BuildTargetList) == 1:
- self.Db._GlobalMacros.setdefault("TARGET", self.BuildTargetList[0])
- if len(self.ToolChainList) == 1:
- self.Db._GlobalMacros.setdefault("TOOL_CHAIN_TAG", self.ToolChainList[0])
-
self.InitBuild()
# print current build environment and configuration
- EdkLogger.quiet("%-24s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))
- EdkLogger.quiet("%-24s = %s" % ("ECP_SOURCE", os.environ["ECP_SOURCE"]))
- EdkLogger.quiet("%-24s = %s" % ("EDK_SOURCE", os.environ["EDK_SOURCE"]))
- EdkLogger.quiet("%-24s = %s" % ("EFI_SOURCE", os.environ["EFI_SOURCE"]))
- EdkLogger.quiet("%-24s = %s" % ("EDK_TOOLS_PATH", os.environ["EDK_TOOLS_PATH"]))
-
- EdkLogger.info('\n%-24s = %s' % ("TARGET_ARCH", ' '.join(self.ArchList)))
- EdkLogger.info('%-24s = %s' % ("TARGET", ' '.join(self.BuildTargetList)))
- EdkLogger.info('%-24s = %s' % ("TOOL_CHAIN_TAG", ' '.join(self.ToolChainList)))
-
- EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.PlatformFile))
-
- if self.Fdf != None and self.Fdf != "":
- EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.Fdf))
-
- if self.ModuleFile != None and self.ModuleFile != "":
- EdkLogger.info('%-24s = %s' % ("Active Module", self.ModuleFile))
+ EdkLogger.quiet("%-16s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))
+ EdkLogger.quiet("%-16s = %s" % ("ECP_SOURCE", os.environ["ECP_SOURCE"]))
+ EdkLogger.quiet("%-16s = %s" % ("EDK_SOURCE", os.environ["EDK_SOURCE"]))
+ EdkLogger.quiet("%-16s = %s" % ("EFI_SOURCE", os.environ["EFI_SOURCE"]))
+ EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_PATH", os.environ["EDK_TOOLS_PATH"]))
+
+ EdkLogger.info("")
+ if self.ArchList:
+ EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList)))
+ EdkLogger.info('%-16s = %s' % ("Build target", ' '.join(self.BuildTargetList)))
+ EdkLogger.info('%-16s = %s' % ("Toolchain", ' '.join(self.ToolChainList)))
+
+ #EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.PlatformFile))
+ if self.ModuleFile:
+ EdkLogger.info('%-16s = %s' % ("Active Module", self.ModuleFile))
os.chdir(self.WorkspaceDir)
self.Progress.Start("\nProcessing meta-data")
@@ -805,15 +781,16 @@ class Build():
EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
# if no ARCH given in command line, get it from target.txt
- if self.ArchList == None or len(self.ArchList) == 0:
+ if not self.ArchList:
self.ArchList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET_ARCH]
+ self.ArchList = tuple(self.ArchList)
# if no build target given in command line, get it from target.txt
- if self.BuildTargetList == None or len(self.BuildTargetList) == 0:
+ if not self.BuildTargetList:
self.BuildTargetList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]
# if no tool chain given in command line, get it from target.txt
- if self.ToolChainList == None or len(self.ToolChainList) == 0:
+ if not self.ToolChainList:
self.ToolChainList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]
if self.ToolChainList == None or len(self.ToolChainList) == 0:
EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.\n")
@@ -859,9 +836,6 @@ class Build():
ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")
self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)
- ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc", False)
- if ErrorCode != 0:
- EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
## Initialize build configuration
#
@@ -869,90 +843,17 @@ class Build():
# command line and target.txt, then get the final build configurations.
#
def InitBuild(self):
- ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc")
+ # parse target.txt, tools_def.txt, and platform file
+ self.LoadConfiguration()
+
+ # Allow case-insensitive for those from command line or configuration file
+ ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc", False)
if ErrorCode != 0:
EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
# create metafile database
self.Db.InitDatabase()
- # we need information in platform description file to determine how to build
- self.Platform = self.BuildDatabase[self.PlatformFile, 'COMMON']
- if not self.Fdf:
- self.Fdf = self.Platform.FlashDefinition
-
- LoadFixAddressString = None
- if TAB_FIX_LOAD_TOP_MEMORY_ADDRESS in GlobalData.gGlobalDefines:
- LoadFixAddressString = GlobalData.gGlobalDefines[TAB_FIX_LOAD_TOP_MEMORY_ADDRESS]
- else:
- LoadFixAddressString = self.Platform.LoadFixAddress
-
- if LoadFixAddressString != None and LoadFixAddressString != '':
- try:
- if LoadFixAddressString.upper().startswith('0X'):
- self.LoadFixAddress = int (LoadFixAddressString, 16)
- else:
- self.LoadFixAddress = int (LoadFixAddressString)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (LoadFixAddressString))
- if self.LoadFixAddress < 0:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value %s" % (LoadFixAddressString))
- if self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress % 0x1000 != 0:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value %s" % (LoadFixAddressString))
-
- if self.SkuId == None or self.SkuId == '':
- self.SkuId = self.Platform.SkuName
-
- # check FD/FV build target
- if self.Fdf == None or self.Fdf == "":
- if self.FdList != []:
- EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdList))
- self.FdList = []
- if self.FvList != []:
- EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvList))
- self.FvList = []
- else:
- #
- # Mark now build in AutoGen Phase
- #
- GlobalData.gAutoGenPhase = True
- FdfParserObj = FdfParser(str(self.Fdf))
- for key in self.Db._GlobalMacros:
- InputMacroDict[key] = self.Db._GlobalMacros[key]
- FdfParserObj.ParseFile()
- for fvname in self.FvList:
- if fvname.upper() not in FdfParserObj.Profile.FvDict.keys():
- EdkLogger.error("build", OPTION_VALUE_INVALID,
- "No such an FV in FDF file: %s" % fvname)
- GlobalData.gAutoGenPhase = False
-
- #
- # Merge Arch
- #
- if self.ArchList == None or len(self.ArchList) == 0:
- ArchList = set(self.Platform.SupArchList)
- else:
- ArchList = set(self.ArchList) & set(self.Platform.SupArchList)
- if len(ArchList) == 0:
- EdkLogger.error("build", PARAMETER_INVALID,
- ExtraData = "Active platform supports [%s] only, but [%s] is given."
- % (" ".join(self.Platform.SupArchList), " ".join(self.ArchList)))
- elif len(ArchList) != len(self.ArchList):
- SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))
- EdkLogger.verbose("\nArch [%s] is ignored because active platform supports [%s] but [%s] is specified !"
- % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList), " ".join(self.ArchList)))
- self.ArchList = tuple(ArchList)
-
- # Merge build target
- if self.BuildTargetList == None or len(self.BuildTargetList) == 0:
- BuildTargetList = self.Platform.BuildTargets
- else:
- BuildTargetList = list(set(self.BuildTargetList) & set(self.Platform.BuildTargets))
- if BuildTargetList == []:
- EdkLogger.error("build", PARAMETER_INVALID, "Active platform only supports [%s], but [%s] is given"
- % (" ".join(self.Platform.BuildTargets), " ".join(self.BuildTargetList)))
- self.BuildTargetList = BuildTargetList
-
## Build a module or platform
#
# Create autogen code and makefile for a module or platform, and the launch
@@ -1000,7 +901,11 @@ class Build():
BuildCommand = AutoGenObject.BuildCommand
if BuildCommand == None or len(BuildCommand) == 0:
- EdkLogger.error("build", OPTION_MISSING, ExtraData="No MAKE command found for [%s, %s, %s]" % Key)
+ EdkLogger.error("build", OPTION_MISSING,
+ "No build command found for this module. "
+ "Please check your setting of %s_%s_%s_MAKE_PATH in Conf/tools_def.txt file." %
+ (AutoGenObject.BuildTarget, AutoGenObject.ToolChain, AutoGenObject.Arch),
+ ExtraData=str(AutoGenObject))
BuildCommand = BuildCommand + [Target]
LaunchCommand(BuildCommand, AutoGenObject.MakeFileDir)
@@ -1011,7 +916,7 @@ class Build():
#
# First should close DB.
#
- self.Db.Close()
+ self.Db.Close()
RemoveDirectory(gBuildCacheDir, True)
except WindowsError, X:
EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
@@ -1121,7 +1026,7 @@ class Build():
## Collect MAP information of all FVs
#
def _CollectFvMapBuffer (self, MapBuffer, Wa, ModuleList):
- if self.Fdf != '':
+ if self.Fdf:
# First get the XIP base address for FV map file.
GuidPattern = re.compile("[-a-fA-F0-9]+")
GuidName = re.compile("\(GUID=[-a-fA-F0-9]+")
@@ -1318,10 +1223,13 @@ class Build():
#
def _BuildPlatform(self):
for BuildTarget in self.BuildTargetList:
+ GlobalData.gGlobalDefines['TARGET'] = BuildTarget
for ToolChain in self.ToolChainList:
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = ToolChain
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = ToolChain
Wa = WorkspaceAutoGen(
self.WorkspaceDir,
- self.Platform,
+ self.PlatformFile,
BuildTarget,
ToolChain,
self.ArchList,
@@ -1335,18 +1243,21 @@ class Build():
self.SkuId,
self.UniFlag
)
+ self.Fdf = Wa.FdfFile
+ self.LoadFixAddress = Wa.Platform.LoadFixAddress
self.BuildReport.AddPlatformReport(Wa)
self.Progress.Stop("done!")
self._Build(self.Target, Wa)
# Create MAP file when Load Fix Address is enabled.
if self.Target in ["", "all", "fds"]:
- for Arch in self.ArchList:
+ for Arch in Wa.ArchList:
+ GlobalData.gGlobalDefines['ARCH'] = Arch
#
# Check whether the set fix address is above 4G for 32bit image.
#
if (Arch == 'IA32' or Arch == 'ARM') and self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress >= 0x100000000:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than or equal to 4G for the platorm with IA32 or ARM arch modules")
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than or equal to 4G for the platform with IA32 or ARM arch modules")
#
# Get Module List
#
@@ -1364,12 +1275,12 @@ class Build():
# Rebase module to the preferred memory address before GenFds
#
self._CollectModuleMapBuffer(MapBuffer, ModuleList)
- if self.Fdf != '':
+ if self.Fdf:
#
# create FDS again for the updated EFI image
#
self._Build("fds", Wa)
- if self.Fdf != '':
+ if self.Fdf:
#
# Create MAP file for all platform FVs after GenFds.
#
@@ -1383,14 +1294,17 @@ class Build():
#
def _BuildModule(self):
for BuildTarget in self.BuildTargetList:
+ GlobalData.gGlobalDefines['TARGET'] = BuildTarget
for ToolChain in self.ToolChainList:
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = ToolChain
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = ToolChain
#
# module build needs platform build information, so get platform
# AutoGen first
#
Wa = WorkspaceAutoGen(
self.WorkspaceDir,
- self.Platform,
+ self.PlatformFile,
BuildTarget,
ToolChain,
self.ArchList,
@@ -1404,10 +1318,13 @@ class Build():
self.SkuId,
self.UniFlag
)
+ self.Fdf = Wa.FdfFile
+ self.LoadFixAddress = Wa.Platform.LoadFixAddress
Wa.CreateMakeFile(False)
self.Progress.Stop("done!")
MaList = []
- for Arch in self.ArchList:
+ for Arch in Wa.ArchList:
+ GlobalData.gGlobalDefines['ARCH'] = Arch
Ma = ModuleAutoGen(Wa, self.ModuleFile, BuildTarget, ToolChain, Arch, self.PlatformFile)
if Ma == None: continue
MaList.append(Ma)
@@ -1421,12 +1338,12 @@ class Build():
"Module for [%s] is not a component of active platform."\
" Please make sure that the ARCH and inf file path are"\
" given in the same as in [%s]" %\
- (', '.join(self.ArchList), self.Platform),
+ (', '.join(Wa.ArchList), self.PlatformFile),
ExtraData=self.ModuleFile
)
# Create MAP file when Load Fix Address is enabled.
- if self.Target == "fds" and self.Fdf != '':
- for Arch in self.ArchList:
+ if self.Target == "fds" and self.Fdf:
+ for Arch in Wa.ArchList:
#
# Check whether the set fix address is above 4G for 32bit image.
#
@@ -1466,10 +1383,13 @@ class Build():
#
def _MultiThreadBuildPlatform(self):
for BuildTarget in self.BuildTargetList:
+ GlobalData.gGlobalDefines['TARGET'] = BuildTarget
for ToolChain in self.ToolChainList:
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = ToolChain
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = ToolChain
Wa = WorkspaceAutoGen(
self.WorkspaceDir,
- self.Platform,
+ self.PlatformFile,
BuildTarget,
ToolChain,
self.ArchList,
@@ -1483,13 +1403,16 @@ class Build():
self.SkuId,
self.UniFlag
)
+ self.Fdf = Wa.FdfFile
+ self.LoadFixAddress = Wa.Platform.LoadFixAddress
self.BuildReport.AddPlatformReport(Wa)
Wa.CreateMakeFile(False)
# multi-thread exit flag
ExitFlag = threading.Event()
ExitFlag.clear()
- for Arch in self.ArchList:
+ for Arch in Wa.ArchList:
+ GlobalData.gGlobalDefines['ARCH'] = Arch
Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch)
if Pa == None:
continue
@@ -1546,7 +1469,7 @@ class Build():
# Create MAP file when Load Fix Address is enabled.
if self.Target in ["", "all", "fds"]:
- for Arch in self.ArchList:
+ for Arch in Wa.ArchList:
#
# Check whether the set fix address is above 4G for 32bit image.
#
@@ -1569,7 +1492,7 @@ class Build():
if self.LoadFixAddress != 0:
self._CollectModuleMapBuffer(MapBuffer, ModuleList)
- if self.Fdf != '':
+ if self.Fdf:
#
# Generate FD image if there's a FDF file found
#
@@ -1586,20 +1509,32 @@ class Build():
## Generate GuidedSectionTools.txt in the FV directories.
#
def CreateGuidedSectionToolsFile(self):
- for Arch in self.ArchList:
- for BuildTarget in self.BuildTargetList:
- for ToolChain in self.ToolChainList:
- FvDir = os.path.join(
- self.WorkspaceDir,
- self.Platform.OutputDirectory,
- '_'.join((BuildTarget, ToolChain)),
- 'FV'
- )
- if not os.path.exists(FvDir):
- continue
+ for BuildTarget in self.BuildTargetList:
+ for ToolChain in self.ToolChainList:
+ Wa = WorkspaceAutoGen(
+ self.WorkspaceDir,
+ self.PlatformFile,
+ BuildTarget,
+ ToolChain,
+ self.ArchList,
+ self.BuildDatabase,
+ self.TargetTxt,
+ self.ToolDef,
+ self.Fdf,
+ self.FdList,
+ self.FvList,
+ self.CapList,
+ self.SkuId,
+ self.UniFlag
+ )
+ FvDir = Wa.FvDir
+ if not os.path.exists(FvDir):
+ continue
+
+ for Arch in self.ArchList:
# Build up the list of supported architectures for this build
prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch)
-
+
# Look through the tool definitions for GUIDed tools
guidAttribs = []
for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.iteritems():
@@ -1614,7 +1549,7 @@ class Build():
path = self.ToolDef.ToolsDefTxtDictionary[path]
path = self.GetFullPathOfTool(path)
guidAttribs.append((guid, toolName, path))
-
+
# Write out GuidedSecTools.txt
toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
toolsFile = open(toolsFile, 'wt')
@@ -1642,7 +1577,7 @@ class Build():
## Launch the module or platform build
#
def Launch(self):
- if self.ModuleFile == None or self.ModuleFile == "":
+ if not self.ModuleFile:
if not self.SpawnMode or self.Target not in ["", "all"]:
self.SpawnMode = False
self._BuildPlatform()
@@ -1687,8 +1622,13 @@ def ParseDefines(DefineList=[]):
if DefineList != None:
for Define in DefineList:
DefineTokenList = Define.split("=", 1)
+ if not GlobalData.gMacroNamePattern.match(DefineTokenList[0]):
+ EdkLogger.error('build', FORMAT_INVALID,
+ "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
+ ExtraData=DefineTokenList[0])
+
if len(DefineTokenList) == 1:
- DefineDict[DefineTokenList[0]] = ""
+ DefineDict[DefineTokenList[0]] = "TRUE"
else:
DefineDict[DefineTokenList[0]] = DefineTokenList[1].strip()
return DefineDict
@@ -1737,10 +1677,7 @@ def MyOptionParser():
Parser.add_option("-u", "--skip-autogen", action="store_true", dest="SkipAutoGen", help="Skip AutoGen step.")
Parser.add_option("-e", "--re-parse", action="store_true", dest="Reparse", help="Re-parse all meta-data files.")
- Parser.add_option("-c", "--case-insensitive", action="store_true", dest="CaseInsensitive", help="Don't check case of file name.")
-
- # Parser.add_option("-D", "--define", action="append", dest="Defines", metavar="NAME[=[VALUE]]",
- # help="Define global macro which can be used in DSC/DEC/INF files.")
+ Parser.add_option("-c", "--case-insensitive", action="store_true", dest="CaseInsensitive", default=False, help="Don't check case of file name.")
Parser.add_option("-w", "--warning-as-error", action="store_true", dest="WarningAsError", help="Treat warning in tools as error.")
Parser.add_option("-j", "--log", action="store", dest="LogFile", help="Put log in specified file as well as on console.")
@@ -1762,6 +1699,7 @@ def MyOptionParser():
help="Specify the specific option to parse EDK UNI file. Must be one of: [-c, -s]. -c is for EDK framework UNI file, and -s is for EDK UEFI UNI file. "\
"This option can also be specified by setting *_*_*_BUILD_FLAGS in [BuildOptions] section of platform DSC. If they are both specified, this value "\
"will override the setting in [BuildOptions] section of platform DSC.")
+ Parser.add_option("-N", "--no-cache", action="store_true", dest="DisableCache", default=False, help="Disable build cache mechanism")
(Opt, Args)=Parser.parse_args()
return (Opt, Args)
@@ -1826,11 +1764,12 @@ def Main():
EdkLogger.error("build", OPTION_NOT_SUPPORTED, "Not supported target [%s]." % Target,
ExtraData="Please select one of: %s" %(' '.join(gSupportedTarget)))
- GlobalData.gGlobalDefines = ParseDefines(Option.Macros)
#
# Check environment variable: EDK_TOOLS_PATH, WORKSPACE, PATH
#
CheckEnvVariable()
+ GlobalData.gCommandLineDefines.update(ParseDefines(Option.Macros))
+
Workspace = os.getenv("WORKSPACE")
#
# Get files real name in workspace dir
@@ -1861,9 +1800,6 @@ def Main():
if os.path.normcase (os.path.normpath(Option.PlatformFile)).find (Workspace) == 0:
Option.PlatformFile = NormFile(os.path.normpath(Option.PlatformFile), Workspace)
Option.PlatformFile = PathClass(Option.PlatformFile, Workspace)
- ErrorCode, ErrorInfo = Option.PlatformFile.Validate(".dsc", False)
- if ErrorCode != 0:
- EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
if Option.FdfFile != None:
if os.path.isabs (Option.FdfFile):
@@ -1877,12 +1813,7 @@ def Main():
if Option.Flag != None and Option.Flag not in ['-c', '-s']:
EdkLogger.error("build", OPTION_VALUE_INVALID, "UNI flag must be one of -c or -s")
- MyBuild = Build(Target, Workspace, Option.PlatformFile, Option.ModuleFile,
- Option.TargetArch, Option.ToolChain, Option.BuildTarget,
- Option.FdfFile, Option.RomImage, Option.FvImage, Option.CapName,
- None, Option.SilentMode, Option.ThreadNumber,
- Option.SkipAutoGen, Option.Reparse, Option.SkuId,
- Option.ReportFile, Option.ReportType, Option.Flag)
+ MyBuild = Build(Target, Workspace, Option)
MyBuild.Launch()
#MyBuild.DumpBuildData()
except FatalError, X:
@@ -1925,7 +1856,8 @@ def Main():
ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
RaiseError=False
)
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ if Option != None and Option.debug != None:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
ReturnCode = CODE_ERROR
finally:
Utils.Progressor.Abort()