Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11094 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 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
|
||||
@@ -35,18 +35,7 @@ Abstract:
|
||||
#define EFI_BASE_ADDRESS "EFI_BASE_ADDRESS"
|
||||
#define DEFAULT_FV_INF_DIR "FV" // default dir for where we create the FV INF file
|
||||
#define DEFAULT_FV_DIR "$(BUILD_DIR)" // where the FV file comes from
|
||||
#define MALLOC(size) malloc (size)
|
||||
#define FREE(ptr) free (ptr)
|
||||
|
||||
//
|
||||
// Disable warning for unused function arguments
|
||||
//
|
||||
#pragma warning(disable : 4100)
|
||||
//
|
||||
// Disable warning for while(1) code
|
||||
//
|
||||
// #pragma warning (disable : 4127)
|
||||
//
|
||||
typedef struct {
|
||||
char *ComponentType;
|
||||
char *Extension;
|
||||
@@ -196,8 +185,7 @@ static
|
||||
void
|
||||
AddFirmwareVolumes (
|
||||
char *FVs,
|
||||
int ComponentsInstance,
|
||||
FILE_LIST *FileListPtr
|
||||
int ComponentsInstance
|
||||
);
|
||||
|
||||
static
|
||||
@@ -503,7 +491,7 @@ Returns:
|
||||
// Add these firmware volumes to the list of known firmware
|
||||
// volume names.
|
||||
//
|
||||
AddFirmwareVolumes (FVs, ComponentsInstance, Ptr);
|
||||
AddFirmwareVolumes (FVs, ComponentsInstance);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -528,7 +516,7 @@ CFVDestructor (
|
||||
//
|
||||
while (mFVList != NULL) {
|
||||
mFVListLast = mFVList->Next;
|
||||
FREE (mFVList);
|
||||
free (mFVList);
|
||||
mFVList = mFVListLast;
|
||||
}
|
||||
}
|
||||
@@ -957,10 +945,10 @@ Returns:
|
||||
//
|
||||
// Now go through the list of all NonFFS FVs they specified and search for
|
||||
// a [build.fv.$(FV)] or [build.fv] command and emit the commands to the
|
||||
// output makefile. Add them to the "fvs" target as well.
|
||||
// output makefile. Add them to the "fvs_0" target as well.
|
||||
//
|
||||
if (mNonFfsFVList != NULL) {
|
||||
fprintf (MakeFptr, "fvs ::");
|
||||
fprintf (MakeFptr, "fvs_0 ::");
|
||||
FVPtr = mNonFfsFVList;
|
||||
while (FVPtr != NULL) {
|
||||
fprintf (MakeFptr, " %s%s.fv", FVDir, FVPtr->FVFileName);
|
||||
@@ -1022,43 +1010,40 @@ Returns:
|
||||
DSCFileRestorePosition (DSC);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Go through our list of firmware volumes and create an "fvs" target that
|
||||
// builds everything. It has to be a mix of components and FV's in order.
|
||||
// For example: fvs : components_0 fv\fv001.fv fv\fv002.fv components_1 fv\fv003.fv
|
||||
//
|
||||
ComponentsInstance = 0;
|
||||
ComponentCount = 0;
|
||||
fprintf (MakeFptr, "fvs ::");
|
||||
for (;;) {
|
||||
//
|
||||
// First see if we have any components for this section. If we don't,
|
||||
// then we're done
|
||||
//
|
||||
for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) {
|
||||
if (FileListPtr->ComponentsInstance == ComponentsInstance) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FileListPtr == NULL) {
|
||||
break;
|
||||
//
|
||||
// Get the components count
|
||||
//
|
||||
ComponentCount = -1;
|
||||
for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) {
|
||||
if (FileListPtr->ComponentsInstance > ComponentCount) {
|
||||
ComponentCount = FileListPtr->ComponentsInstance;
|
||||
}
|
||||
}
|
||||
ComponentCount++;
|
||||
|
||||
fprintf (MakeFptr, " components_%d", ComponentsInstance);
|
||||
ComponentCount++;
|
||||
//
|
||||
// Now print any firmware volumes that match this components instance
|
||||
//
|
||||
//
|
||||
// Now print firmware volumes build targets fvs_0, fvs_1 etc.
|
||||
//
|
||||
for (ComponentsInstance = 0; ComponentsInstance < ComponentCount; ComponentsInstance++) {
|
||||
fprintf (MakeFptr, "fvs_%d ::", ComponentsInstance);
|
||||
for (FVPtr = mFVList; FVPtr != NULL; FVPtr = FVPtr->Next) {
|
||||
if (FVPtr->ComponentsInstance == ComponentsInstance) {
|
||||
fprintf (MakeFptr, " %s%s.fv", FVDir, FVPtr->FVFileName);
|
||||
}
|
||||
}
|
||||
|
||||
ComponentsInstance++;
|
||||
fprintf (MakeFptr, "\n\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Create an "fvs" target that builds everything. It has to be a mix of
|
||||
// components and FV's in order. For example:
|
||||
// fvs :: components_0 fvs_0 components_1 fvs_1
|
||||
//
|
||||
fprintf (MakeFptr, "fvs ::");
|
||||
for (ComponentsInstance = 0; ComponentsInstance < ComponentCount; ComponentsInstance++) {
|
||||
fprintf (MakeFptr, " components_%d fvs_%d", ComponentsInstance, ComponentsInstance);
|
||||
}
|
||||
|
||||
fprintf (MakeFptr, "\n\n");
|
||||
|
||||
//
|
||||
@@ -1351,8 +1336,7 @@ static
|
||||
void
|
||||
AddFirmwareVolumes (
|
||||
char *FVs,
|
||||
int ComponentsInstance,
|
||||
FILE_LIST *FileListPtr
|
||||
int ComponentsInstance
|
||||
)
|
||||
{
|
||||
FV_LIST *FvPtr;
|
||||
@@ -1386,7 +1370,7 @@ AddFirmwareVolumes (
|
||||
// If we didn't find a match, then create a new one
|
||||
//
|
||||
if (FvPtr == NULL) {
|
||||
FvPtr = MALLOC (sizeof (FV_LIST));
|
||||
FvPtr = malloc (sizeof (FV_LIST));
|
||||
if (FvPtr == NULL) {
|
||||
Error (__FILE__, __LINE__, 0, "application error", "memory allocation failed");
|
||||
return ;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2004 - 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
|
||||
@@ -49,25 +49,31 @@ TARGET_EXE = $(EDK_TOOLS_OUTPUT)\ProcessDsc.exe
|
||||
|
||||
all: $(TARGET_EXE)
|
||||
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\DSCFile.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\FWVolume.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\Exceptions.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\Common.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\DSCFile.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\MultiThread.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\FWVolume.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\Exceptions.h $(INC_DEPS)
|
||||
INC_DEPS = $(TARGET_SRC_DIR)\Common.h $(INC_DEPS)
|
||||
|
||||
LIBS = $(LIBS) "$(EDK_TOOLS_OUTPUT)\Common.lib"
|
||||
|
||||
OBJECTS = $(EDK_TOOLS_OUTPUT)\DSCFile.obj \
|
||||
$(EDK_TOOLS_OUTPUT)\FWVolume.obj \
|
||||
$(EDK_TOOLS_OUTPUT)\ProcessDsc.obj \
|
||||
OBJECTS = $(EDK_TOOLS_OUTPUT)\DSCFile.obj \
|
||||
$(EDK_TOOLS_OUTPUT)\MultiThread.obj \
|
||||
$(EDK_TOOLS_OUTPUT)\FWVolume.obj \
|
||||
$(EDK_TOOLS_OUTPUT)\ProcessDsc.obj \
|
||||
$(EDK_TOOLS_OUTPUT)\Exceptions.obj
|
||||
|
||||
#
|
||||
# Compile each source file
|
||||
#
|
||||
C_FLAGS = $(C_FLAGS) /MT /wd4201
|
||||
|
||||
$(EDK_TOOLS_OUTPUT)\DSCFile.obj : $(TARGET_SRC_DIR)\DSCFile.c $(INC_DEPS)
|
||||
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\DSCFile.c /Fo$@
|
||||
|
||||
$(EDK_TOOLS_OUTPUT)\MultiThread.obj : $(TARGET_SRC_DIR)\MultiThread.c $(INC_DEPS)
|
||||
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\MultiThread.c /Fo$@
|
||||
|
||||
$(EDK_TOOLS_OUTPUT)\FWVolume.obj : $(TARGET_SRC_DIR)\FWVolume.c $(INC_DEPS)
|
||||
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\FWVolume.c /Fo$@
|
||||
|
||||
@@ -88,7 +94,9 @@ $(TARGET_EXE): $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).exe
|
||||
copy $(EFI_PLATFORM_BIN)\Tools\$(TARGET_NAME).pdb $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).pdb /Y
|
||||
!ELSE
|
||||
$(TARGET_EXE) : $(OBJECTS) $(LIBS)
|
||||
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) shlwapi.lib \
|
||||
/NODEFAULTLIB:libc.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib \
|
||||
/NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib
|
||||
!IF ("$(EFI_BINARY_BUILD)" == "YES")
|
||||
if not exist $(EFI_PLATFORM_BIN)\Tools mkdir $(EFI_PLATFORM_BIN)\Tools
|
||||
if exist $(TARGET_EXE) copy $(TARGET_EXE) $(EFI_PLATFORM_BIN)\tools\$(TARGET_NAME).exe /Y
|
||||
@@ -100,5 +108,6 @@ $(TARGET_EXE) : $(OBJECTS) $(LIBS)
|
||||
clean:
|
||||
@if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
||||
@if exist $(EDK_TOOLS_OUTPUT)\DscFile.* del $(EDK_TOOLS_OUTPUT)\DscFile.* > NUL
|
||||
@if exist $(EDK_TOOLS_OUTPUT)\MultiThread.* del $(EDK_TOOLS_OUTPUT)\MultiThread.* > NUL
|
||||
@if exist $(EDK_TOOLS_OUTPUT)\Exceptions* del $(EDK_TOOLS_OUTPUT)\Exceptions.* > NUL
|
||||
@if exist $(EDK_TOOLS_OUTPUT)\FwVolume.* del $(EDK_TOOLS_OUTPUT)\FwVolume.* > NUL
|
||||
|
905
EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/MultiThread.c
Normal file
905
EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/MultiThread.c
Normal file
@@ -0,0 +1,905 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2008 - 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
MultiThread.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module is used to add multi-thread build support to ProcessDsc utility
|
||||
to improve the build performance.
|
||||
|
||||
--*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <direct.h>
|
||||
#include "Common.h"
|
||||
#include "MultiThread.h"
|
||||
|
||||
BUILD_ITEM *
|
||||
AddBuildItem (
|
||||
BUILD_ITEM **BuildList,
|
||||
INT8 *BaseName,
|
||||
INT8 *Processor,
|
||||
INT8 *Makefile
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add a build item to a specified build list
|
||||
|
||||
Arguments:
|
||||
|
||||
BuildList - build list where the new build item will be added
|
||||
BaseName - base name of the new module
|
||||
Processor - processor type of the new module
|
||||
Makefile - makefile name of the new module
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the newly added build item
|
||||
|
||||
--*/
|
||||
{
|
||||
BUILD_ITEM *NewBuildItem;
|
||||
|
||||
//
|
||||
// Create a new build item
|
||||
//
|
||||
NewBuildItem = malloc (sizeof (BUILD_ITEM));
|
||||
if (NewBuildItem == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset (NewBuildItem, 0, sizeof (BUILD_ITEM));
|
||||
NewBuildItem->BaseName = _strdup (BaseName);
|
||||
NewBuildItem->Processor = _strdup (Processor);
|
||||
NewBuildItem->Makefile = _strdup (Makefile);
|
||||
|
||||
//
|
||||
// Add the build item to the head of the build list
|
||||
//
|
||||
NewBuildItem->Next = *BuildList;
|
||||
*BuildList = NewBuildItem;
|
||||
|
||||
return NewBuildItem;
|
||||
}
|
||||
|
||||
SOURCE_FILE_ITEM *
|
||||
AddSourceFile (
|
||||
BUILD_ITEM *BuildItem,
|
||||
INT8 *FileName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add a source file for a build item
|
||||
|
||||
Arguments:
|
||||
|
||||
BuildItem - build item to add the source file
|
||||
FileName - source file name to be added
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the newly added source file item
|
||||
|
||||
--*/
|
||||
{
|
||||
SOURCE_FILE_ITEM *NewSourceFile;
|
||||
|
||||
//
|
||||
// Create a new source file item
|
||||
//
|
||||
NewSourceFile = malloc (sizeof (SOURCE_FILE_ITEM));
|
||||
if (NewSourceFile == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset (NewSourceFile, 0, sizeof (SOURCE_FILE_ITEM));
|
||||
NewSourceFile->FileName = _strdup (FileName);
|
||||
|
||||
//
|
||||
// Add the source file item to the head of the source file list
|
||||
//
|
||||
NewSourceFile->Next = BuildItem->SourceFileList;
|
||||
BuildItem->SourceFileList = NewSourceFile;
|
||||
|
||||
return NewSourceFile;
|
||||
}
|
||||
|
||||
DEPENDENCY_ITEM *
|
||||
AddDependency (
|
||||
BUILD_ITEM *BuildList,
|
||||
BUILD_ITEM *BuildItem,
|
||||
INT8 *BaseName,
|
||||
INT8 AdjustIndex
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add a build dependency for a build item in the specified build list
|
||||
|
||||
Arguments:
|
||||
|
||||
BuildList - build list where to search the dependency
|
||||
BuildItem - build item to add the dependency
|
||||
BaseName - dependency module base name
|
||||
AdjustIndex - Adjust BuildItem->Index when non-zero
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the newly added build dependency
|
||||
|
||||
--*/
|
||||
{
|
||||
BUILD_ITEM *TempBuildItem;
|
||||
DEPENDENCY_ITEM *NewDependency;
|
||||
|
||||
//
|
||||
// Search the dependency in the build list
|
||||
//
|
||||
TempBuildItem = BuildList;
|
||||
while (TempBuildItem != NULL) {
|
||||
if ((_stricmp (TempBuildItem->BaseName, BaseName) == 0) &&
|
||||
(_stricmp (TempBuildItem->Processor, BuildItem->Processor) == 0) &&
|
||||
(TempBuildItem != BuildItem)) {
|
||||
break;
|
||||
}
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
}
|
||||
if (TempBuildItem == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// This index is used to isolate two modules with same base name and processor.
|
||||
// (ProcessDsc allows duplicate base name libraries.)
|
||||
//
|
||||
if (AdjustIndex) {
|
||||
BuildItem->Index = TempBuildItem->Index + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a new build dependency item
|
||||
//
|
||||
NewDependency = malloc (sizeof (DEPENDENCY_ITEM));
|
||||
if (NewDependency == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset (NewDependency, 0, sizeof (DEPENDENCY_ITEM));
|
||||
NewDependency->Dependency = TempBuildItem;
|
||||
|
||||
//
|
||||
// Add the build dependency item to the head of the dependency list
|
||||
//
|
||||
NewDependency->Next = BuildItem->DependencyList;
|
||||
BuildItem->DependencyList = NewDependency;
|
||||
|
||||
return NewDependency;
|
||||
}
|
||||
|
||||
void
|
||||
FreeBuildList (
|
||||
BUILD_ITEM *BuildList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Free a build list
|
||||
|
||||
Arguments:
|
||||
|
||||
BuildList - build list to be freed
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
BUILD_ITEM *TempBuildItem;
|
||||
BUILD_ITEM *FreeBuildItem;
|
||||
SOURCE_FILE_ITEM *TempSourceFile;
|
||||
SOURCE_FILE_ITEM *FreeSourceFile;
|
||||
DEPENDENCY_ITEM *TempDependency;
|
||||
DEPENDENCY_ITEM *FreeDependency;
|
||||
|
||||
TempBuildItem = BuildList;
|
||||
while (TempBuildItem != NULL) {
|
||||
free (TempBuildItem->BaseName);
|
||||
free (TempBuildItem->Processor);
|
||||
free (TempBuildItem->Makefile);
|
||||
|
||||
//
|
||||
// Free source file list
|
||||
//
|
||||
TempSourceFile = TempBuildItem->SourceFileList;
|
||||
while (TempSourceFile != NULL) {
|
||||
FreeSourceFile = TempSourceFile;
|
||||
TempSourceFile = TempSourceFile->Next;
|
||||
free (FreeSourceFile);
|
||||
}
|
||||
|
||||
//
|
||||
// Free dependency list
|
||||
//
|
||||
TempDependency = TempBuildItem->DependencyList;
|
||||
while (TempDependency != NULL) {
|
||||
FreeDependency = TempDependency;
|
||||
TempDependency = TempDependency->Next;
|
||||
free (FreeDependency);
|
||||
}
|
||||
|
||||
FreeBuildItem = TempBuildItem;
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
free (FreeBuildItem);
|
||||
}
|
||||
}
|
||||
|
||||
COMPONENTS_ITEM *
|
||||
AddComponentsItem (
|
||||
COMPONENTS_ITEM **ComponentsList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add a new components item to a specified components list
|
||||
|
||||
Arguments:
|
||||
|
||||
ComponentsList - components list where the new components item will be added
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the newly added components item
|
||||
|
||||
--*/
|
||||
{
|
||||
COMPONENTS_ITEM *NewComponents;
|
||||
COMPONENTS_ITEM *TempComponents;
|
||||
|
||||
//
|
||||
// Create a new components item
|
||||
//
|
||||
NewComponents = malloc (sizeof (COMPONENTS_ITEM));
|
||||
if (NewComponents == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset (NewComponents, 0, sizeof (COMPONENTS_ITEM));
|
||||
|
||||
//
|
||||
// Add the components item to the tail of the components list
|
||||
//
|
||||
TempComponents = *ComponentsList;
|
||||
if (TempComponents == NULL) {
|
||||
*ComponentsList = NewComponents;
|
||||
} else {
|
||||
while (TempComponents->Next != NULL) {
|
||||
TempComponents = TempComponents->Next;
|
||||
}
|
||||
TempComponents->Next = NewComponents;
|
||||
}
|
||||
|
||||
return NewComponents;
|
||||
}
|
||||
|
||||
void
|
||||
FreeComponentsList (
|
||||
COMPONENTS_ITEM *ComponentsList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Free a components list
|
||||
|
||||
Arguments:
|
||||
|
||||
ComponentsList - components list to be freed
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
COMPONENTS_ITEM *TempComponents;
|
||||
COMPONENTS_ITEM *FreeComponents;
|
||||
|
||||
TempComponents = ComponentsList;
|
||||
while (TempComponents != NULL) {
|
||||
FreeBuildList (TempComponents->BuildList);
|
||||
FreeComponents = TempComponents;
|
||||
TempComponents = TempComponents->Next;
|
||||
free (FreeComponents);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Module globals for multi-thread build
|
||||
//
|
||||
static INT8 mError; // non-zero means error occurred
|
||||
static INT8 mDone; // non-zero means no more build items available for build
|
||||
static UINT32 mThreadNumber; // thread number
|
||||
static INT8 *mBuildDir; // build directory
|
||||
static INT8 mLogDir[MAX_PATH]; // build item log dir
|
||||
static CRITICAL_SECTION mCriticalSection; // critical section object
|
||||
static HANDLE mSemaphoreHandle; // semaphore for "ready for build" items in mWaitingList
|
||||
static HANDLE mEventHandle; // event signaled when one build item is finished
|
||||
static BUILD_ITEM *mPendingList; // build list for build items which are not ready for build
|
||||
static BUILD_ITEM *mWaitingList; // build list for build items which are ready for build
|
||||
static BUILD_ITEM *mBuildingList; // build list for build items which are buiding
|
||||
static BUILD_ITEM *mDoneList; // build list for build items which already finish the build
|
||||
|
||||
//
|
||||
// Restore the BuildList (not care about the sequence of the build items)
|
||||
//
|
||||
static void
|
||||
RestoreBuildList (
|
||||
BUILD_ITEM **BuildList
|
||||
)
|
||||
{
|
||||
BUILD_ITEM *TempBuildItem;
|
||||
|
||||
if (mPendingList != NULL) {
|
||||
//
|
||||
// Add the mPendingList to the header of *BuildList
|
||||
//
|
||||
TempBuildItem = mPendingList;
|
||||
while (TempBuildItem->Next != NULL) {
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
}
|
||||
TempBuildItem->Next = *BuildList;
|
||||
*BuildList = mPendingList;
|
||||
}
|
||||
|
||||
if (mWaitingList != NULL) {
|
||||
//
|
||||
// Add the mWaitingList to the header of *BuildList
|
||||
//
|
||||
TempBuildItem = mWaitingList;
|
||||
while (TempBuildItem->Next != NULL) {
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
}
|
||||
TempBuildItem->Next = *BuildList;
|
||||
*BuildList = mWaitingList;
|
||||
}
|
||||
|
||||
if (mBuildingList != NULL) {
|
||||
//
|
||||
// Add the mBuildingList to the header of *BuildList
|
||||
//
|
||||
TempBuildItem = mBuildingList;
|
||||
while (TempBuildItem->Next != NULL) {
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
}
|
||||
TempBuildItem->Next = *BuildList;
|
||||
*BuildList = mBuildingList;
|
||||
}
|
||||
|
||||
if (mDoneList != NULL) {
|
||||
//
|
||||
// Add the mDoneList to the header of *BuildList
|
||||
//
|
||||
TempBuildItem = mDoneList;
|
||||
while (TempBuildItem->Next != NULL) {
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
}
|
||||
TempBuildItem->Next = *BuildList;
|
||||
*BuildList = mDoneList;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return non-zero when no source file build conflict
|
||||
//
|
||||
static INT8
|
||||
CheckSourceFile (
|
||||
SOURCE_FILE_ITEM *SourceFileList
|
||||
)
|
||||
{
|
||||
BUILD_ITEM *TempBuildItem;
|
||||
SOURCE_FILE_ITEM *TempSourceFile;
|
||||
|
||||
while (SourceFileList != NULL) {
|
||||
TempBuildItem = mBuildingList;
|
||||
while (TempBuildItem != NULL) {
|
||||
TempSourceFile = TempBuildItem->SourceFileList;
|
||||
while (TempSourceFile != NULL) {
|
||||
if (_stricmp (SourceFileList->FileName, TempSourceFile->FileName) == 0) {
|
||||
return 0;
|
||||
}
|
||||
TempSourceFile = TempSourceFile->Next;
|
||||
}
|
||||
TempBuildItem = TempBuildItem->Next;
|
||||
}
|
||||
SourceFileList = SourceFileList->Next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Return non-zero when all the dependency build items has been built
|
||||
//
|
||||
static INT8
|
||||
CheckDependency (
|
||||
DEPENDENCY_ITEM *DependencyList
|
||||
)
|
||||
{
|
||||
while (DependencyList != NULL) {
|
||||
if (!(DependencyList->Dependency->CompleteFlag)) {
|
||||
return 0;
|
||||
}
|
||||
DependencyList = DependencyList->Next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Run the build task. The system() function call will cause stdout conflict
|
||||
// in multi-thread envroment, so implement this through CreateProcess().
|
||||
//
|
||||
static INT8
|
||||
RunBuildTask (
|
||||
INT8 *WorkingDir,
|
||||
INT8 *LogFile,
|
||||
INT8 *BuildCmd
|
||||
)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
SECURITY_ATTRIBUTES SecAttr;
|
||||
PROCESS_INFORMATION ProcInfo;
|
||||
STARTUPINFO StartInfo;
|
||||
BOOL FuncRetn;
|
||||
DWORD ExitCode;
|
||||
|
||||
//
|
||||
// Init SecAttr
|
||||
//
|
||||
SecAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
|
||||
SecAttr.bInheritHandle = TRUE;
|
||||
SecAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
//
|
||||
// Create the log file
|
||||
//
|
||||
FileHandle = CreateFile (
|
||||
LogFile, // file to create
|
||||
GENERIC_WRITE, // open for writing
|
||||
0, // do not share
|
||||
&SecAttr, // can be inherited by child processes
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_NORMAL, // normal file
|
||||
NULL // no attr. template
|
||||
);
|
||||
|
||||
if (FileHandle == INVALID_HANDLE_VALUE) {
|
||||
EnterCriticalSection (&mCriticalSection);
|
||||
Error (NULL, 0, 0, NULL, "could not open file %s", LogFile);
|
||||
LeaveCriticalSection (&mCriticalSection);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Init ProcInfo and StartInfo
|
||||
//
|
||||
ZeroMemory (&ProcInfo, sizeof (PROCESS_INFORMATION));
|
||||
ZeroMemory (&StartInfo, sizeof (STARTUPINFO));
|
||||
StartInfo.cb = sizeof (STARTUPINFO);
|
||||
StartInfo.hStdError = FileHandle;
|
||||
StartInfo.hStdOutput = FileHandle;
|
||||
StartInfo.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
StartInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||
|
||||
//
|
||||
// Create the child process
|
||||
//
|
||||
FuncRetn = CreateProcess (
|
||||
NULL, // no application name
|
||||
BuildCmd, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
NULL, // use parent's environment
|
||||
WorkingDir, // set current directory
|
||||
&StartInfo, // STARTUPINFO pointer
|
||||
&ProcInfo // receives PROCESS_INFORMATION
|
||||
);
|
||||
|
||||
if (FuncRetn == FALSE) {
|
||||
EnterCriticalSection (&mCriticalSection);
|
||||
Error (NULL, 0, 0, NULL, "could not create child process");
|
||||
LeaveCriticalSection (&mCriticalSection);
|
||||
CloseHandle (FileHandle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Wait until child process exits
|
||||
//
|
||||
WaitForSingleObject (ProcInfo.hProcess, INFINITE);
|
||||
GetExitCodeProcess (ProcInfo.hProcess, &ExitCode);
|
||||
CloseHandle (ProcInfo.hProcess);
|
||||
CloseHandle (ProcInfo.hThread);
|
||||
CloseHandle (FileHandle);
|
||||
|
||||
if (ExitCode != 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Thread function
|
||||
//
|
||||
static DWORD WINAPI
|
||||
ThreadProc (
|
||||
LPVOID lpParam
|
||||
)
|
||||
{
|
||||
UINT32 ThreadId;
|
||||
BUILD_ITEM *PreviousBuildItem;
|
||||
BUILD_ITEM *CurrentBuildItem;
|
||||
BUILD_ITEM *NextBuildItem;
|
||||
INT8 WorkingDir[MAX_PATH];
|
||||
INT8 LogFile[MAX_PATH];
|
||||
INT8 BuildCmd[MAX_PATH];
|
||||
|
||||
ThreadId = (UINT32)lpParam;
|
||||
//
|
||||
// Loop until error occurred or no more build items available for build
|
||||
//
|
||||
for (;;) {
|
||||
WaitForSingleObject (mSemaphoreHandle, INFINITE);
|
||||
if (mError || mDone) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// When code runs here, there must have one build item available for this
|
||||
// thread. Loop until error occurred or get one build item for build.
|
||||
//
|
||||
for (;;) {
|
||||
EnterCriticalSection (&mCriticalSection);
|
||||
PreviousBuildItem = NULL;
|
||||
CurrentBuildItem = mWaitingList;
|
||||
while (CurrentBuildItem != NULL) {
|
||||
NextBuildItem = CurrentBuildItem->Next;
|
||||
//
|
||||
// CheckSourceFile() is to avoid concurrently build the same source file
|
||||
// which may cause the muti-thread build failure
|
||||
//
|
||||
if (CheckSourceFile (CurrentBuildItem->SourceFileList)) {
|
||||
//
|
||||
// Move the current build item from mWaitingList
|
||||
//
|
||||
if (PreviousBuildItem != NULL) {
|
||||
PreviousBuildItem->Next = NextBuildItem;
|
||||
} else {
|
||||
mWaitingList = NextBuildItem;
|
||||
}
|
||||
//
|
||||
// Add the current build item to the head of mBuildingList
|
||||
//
|
||||
CurrentBuildItem->Next = mBuildingList;
|
||||
mBuildingList = CurrentBuildItem;
|
||||
//
|
||||
// If no more build items is pending or waiting for build,
|
||||
// wake up every child thread for exit.
|
||||
//
|
||||
if ((mPendingList == NULL) && (mWaitingList == NULL)) {
|
||||
mDone = 1;
|
||||
//
|
||||
// Make sure to wake up every child thread for exit
|
||||
//
|
||||
ReleaseSemaphore (mSemaphoreHandle, mThreadNumber, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
PreviousBuildItem = CurrentBuildItem;
|
||||
CurrentBuildItem = NextBuildItem;
|
||||
}
|
||||
if (CurrentBuildItem != NULL) {
|
||||
//
|
||||
// Display build item info
|
||||
//
|
||||
printf ("\t[Thread_%d] nmake -nologo -f %s all\n", ThreadId, CurrentBuildItem->Makefile);
|
||||
//
|
||||
// Prepare build task
|
||||
//
|
||||
sprintf (WorkingDir, "%s\\%s", mBuildDir, CurrentBuildItem->Processor);
|
||||
sprintf (LogFile, "%s\\%s_%s_%d.txt", mLogDir, CurrentBuildItem->BaseName,
|
||||
CurrentBuildItem->Processor, CurrentBuildItem->Index);
|
||||
sprintf (BuildCmd, "nmake -nologo -f %s all", CurrentBuildItem->Makefile);
|
||||
LeaveCriticalSection (&mCriticalSection);
|
||||
break;
|
||||
} else {
|
||||
LeaveCriticalSection (&mCriticalSection);
|
||||
//
|
||||
// All the build items in mWaitingList have source file conflict with
|
||||
// mBuildingList. This rarely hapeens. Need wait for the build items in
|
||||
// mBuildingList to be finished by other child threads.
|
||||
//
|
||||
Sleep (1000);
|
||||
if (mError) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Start to build the CurrentBuildItem
|
||||
//
|
||||
if (RunBuildTask (WorkingDir, LogFile, BuildCmd)) {
|
||||
//
|
||||
// Build failure
|
||||
//
|
||||
mError = 1;
|
||||
//
|
||||
// Make sure to wake up every child thread for exit
|
||||
//
|
||||
ReleaseSemaphore (mSemaphoreHandle, mThreadNumber, NULL);
|
||||
SetEvent(mEventHandle);
|
||||
|
||||
return mError;
|
||||
} else {
|
||||
//
|
||||
// Build success
|
||||
//
|
||||
CurrentBuildItem->CompleteFlag = 1;
|
||||
|
||||
EnterCriticalSection (&mCriticalSection);
|
||||
//
|
||||
// Move this build item from mBuildingList
|
||||
//
|
||||
if (mBuildingList == CurrentBuildItem) {
|
||||
mBuildingList = mBuildingList->Next;
|
||||
} else {
|
||||
NextBuildItem = mBuildingList;
|
||||
while (NextBuildItem->Next != CurrentBuildItem) {
|
||||
NextBuildItem = NextBuildItem->Next;
|
||||
}
|
||||
NextBuildItem->Next = CurrentBuildItem->Next;
|
||||
}
|
||||
//
|
||||
// Add this build item to mDoneList
|
||||
//
|
||||
CurrentBuildItem->Next = mDoneList;
|
||||
mDoneList = CurrentBuildItem;
|
||||
LeaveCriticalSection (&mCriticalSection);
|
||||
|
||||
SetEvent(mEventHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INT8
|
||||
StartMultiThreadBuild (
|
||||
BUILD_ITEM **BuildList,
|
||||
UINT32 ThreadNumber,
|
||||
INT8 *BuildDir
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Start multi-thread build for a specified build list
|
||||
|
||||
Arguments:
|
||||
|
||||
BuildList - build list for multi-thread build
|
||||
ThreadNumber - thread number for multi-thread build
|
||||
BuildDir - build dir
|
||||
|
||||
Returns:
|
||||
|
||||
0 - Successfully finished the multi-thread build
|
||||
other value - Build failure
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT32 Count;
|
||||
BUILD_ITEM *PreviousBuildItem;
|
||||
BUILD_ITEM *CurrentBuildItem;
|
||||
BUILD_ITEM *NextBuildItem;
|
||||
HANDLE *ThreadHandle;
|
||||
INT8 Cmd[MAX_PATH];
|
||||
|
||||
mError = 0;
|
||||
mDone = 0;
|
||||
mThreadNumber = ThreadNumber;
|
||||
mBuildDir = BuildDir;
|
||||
mPendingList = *BuildList;
|
||||
*BuildList = NULL;
|
||||
mWaitingList = NULL;
|
||||
mBuildingList = NULL;
|
||||
mDoneList = NULL;
|
||||
|
||||
//
|
||||
// Do nothing when mPendingList is empty
|
||||
//
|
||||
if (mPendingList == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Get build item count of mPendingList
|
||||
//
|
||||
Count = 0;
|
||||
CurrentBuildItem = mPendingList;
|
||||
while (CurrentBuildItem != NULL) {
|
||||
Count++;
|
||||
CurrentBuildItem = CurrentBuildItem->Next;
|
||||
}
|
||||
|
||||
//
|
||||
// The semaphore is also used to wake up child threads for exit,
|
||||
// so need to make sure "maximum count" >= "thread number".
|
||||
//
|
||||
if (Count < ThreadNumber) {
|
||||
Count = ThreadNumber;
|
||||
}
|
||||
|
||||
//
|
||||
// Init mSemaphoreHandle
|
||||
//
|
||||
mSemaphoreHandle = CreateSemaphore (
|
||||
NULL, // default security attributes
|
||||
0, // initial count
|
||||
Count, // maximum count
|
||||
NULL // unnamed semaphore
|
||||
);
|
||||
if (mSemaphoreHandle == NULL) {
|
||||
Error (NULL, 0, 0, NULL, "failed to create semaphore");
|
||||
RestoreBuildList (BuildList);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Init mEventHandle
|
||||
//
|
||||
mEventHandle = CreateEvent(
|
||||
NULL, // default security attributes
|
||||
FALSE, // auto-reset event
|
||||
TRUE, // initial state is signaled
|
||||
NULL // object not named
|
||||
);
|
||||
if (mEventHandle == NULL) {
|
||||
Error (NULL, 0, 0, NULL, "failed to create event");
|
||||
CloseHandle (mSemaphoreHandle);
|
||||
RestoreBuildList (BuildList);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Init mCriticalSection
|
||||
//
|
||||
InitializeCriticalSection (&mCriticalSection);
|
||||
|
||||
//
|
||||
// Create build item log dir
|
||||
//
|
||||
sprintf (mLogDir, "%s\\Log", mBuildDir);
|
||||
_mkdir (mLogDir);
|
||||
|
||||
//
|
||||
// Create child threads for muti-thread build
|
||||
//
|
||||
ThreadHandle = malloc (ThreadNumber * sizeof (HANDLE));
|
||||
if (ThreadHandle == NULL) {
|
||||
Error (NULL, 0, 0, NULL, "failed to allocate memory");
|
||||
CloseHandle (mSemaphoreHandle);
|
||||
CloseHandle (mEventHandle);
|
||||
RestoreBuildList (BuildList);
|
||||
return 1;
|
||||
}
|
||||
for (Index = 0; Index < ThreadNumber; Index++) {
|
||||
ThreadHandle[Index] = CreateThread (
|
||||
NULL, // default security attributes
|
||||
0, // use default stack size
|
||||
ThreadProc, // thread function
|
||||
(LPVOID)Index, // argument to thread function: use Index as thread id
|
||||
0, // use default creation flags
|
||||
NULL // thread identifier not needed
|
||||
);
|
||||
if (ThreadHandle[Index] == NULL) {
|
||||
Error (NULL, 0, 0, NULL, "failed to create Thread_%d", Index);
|
||||
mError = 1;
|
||||
ThreadNumber = Index;
|
||||
//
|
||||
// Make sure to wake up every child thread for exit
|
||||
//
|
||||
ReleaseSemaphore (mSemaphoreHandle, ThreadNumber, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loop until error occurred or no more build items pending for build
|
||||
//
|
||||
for (;;) {
|
||||
WaitForSingleObject (mEventHandle, INFINITE);
|
||||
if (mError) {
|
||||
break;
|
||||
}
|
||||
Count = 0;
|
||||
|
||||
EnterCriticalSection (&mCriticalSection);
|
||||
PreviousBuildItem = NULL;
|
||||
CurrentBuildItem = mPendingList;
|
||||
while (CurrentBuildItem != NULL) {
|
||||
NextBuildItem = CurrentBuildItem->Next;
|
||||
if (CheckDependency (CurrentBuildItem->DependencyList)) {
|
||||
//
|
||||
// Move the current build item from mPendingList
|
||||
//
|
||||
if (PreviousBuildItem != NULL) {
|
||||
PreviousBuildItem->Next = NextBuildItem;
|
||||
} else {
|
||||
mPendingList = NextBuildItem;
|
||||
}
|
||||
//
|
||||
// Add the current build item to the head of mWaitingList
|
||||
//
|
||||
CurrentBuildItem->Next = mWaitingList;
|
||||
mWaitingList = CurrentBuildItem;
|
||||
Count++;
|
||||
} else {
|
||||
PreviousBuildItem = CurrentBuildItem;
|
||||
}
|
||||
CurrentBuildItem = NextBuildItem;
|
||||
}
|
||||
LeaveCriticalSection (&mCriticalSection);
|
||||
|
||||
ReleaseSemaphore (mSemaphoreHandle, Count, NULL);
|
||||
if (mPendingList == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Wait until all threads have terminated
|
||||
//
|
||||
WaitForMultipleObjects (ThreadNumber, ThreadHandle, TRUE, INFINITE);
|
||||
|
||||
if (mError && (mBuildingList != NULL)) {
|
||||
//
|
||||
// Dump build failure log of the first build item which doesn't finish the build
|
||||
//
|
||||
printf ("\tnmake -nologo -f %s all\n", mBuildingList->Makefile);
|
||||
sprintf (Cmd, "type %s\\%s_%s_%d.txt 2>NUL", mLogDir, mBuildingList->BaseName,
|
||||
mBuildingList->Processor, mBuildingList->Index);
|
||||
_flushall ();
|
||||
if (system (Cmd)) {
|
||||
Error (NULL, 0, 0, NULL, "failed to run \"%s\"", Cmd);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteCriticalSection (&mCriticalSection);
|
||||
for (Index = 0; Index < ThreadNumber; Index++) {
|
||||
CloseHandle (ThreadHandle[Index]);
|
||||
}
|
||||
free (ThreadHandle);
|
||||
CloseHandle (mSemaphoreHandle);
|
||||
CloseHandle (mEventHandle);
|
||||
RestoreBuildList (BuildList);
|
||||
|
||||
return mError;
|
||||
}
|
116
EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/MultiThread.h
Normal file
116
EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/MultiThread.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2008 - 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
MultiThread.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Defines and function prototypes for the ProcessDsc utility.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _MULTI_THREAD_H_
|
||||
#define _MULTI_THREAD_H_
|
||||
|
||||
typedef struct _COMPONENTS_ITEM COMPONENTS_ITEM;
|
||||
typedef struct _BUILD_ITEM BUILD_ITEM;
|
||||
typedef struct _SOURCE_FILE_ITEM SOURCE_FILE_ITEM;
|
||||
typedef struct _DEPENDENCY_ITEM DEPENDENCY_ITEM;
|
||||
|
||||
//
|
||||
// Use this structure to keep track of module build items
|
||||
//
|
||||
typedef struct _BUILD_ITEM {
|
||||
BUILD_ITEM *Next;
|
||||
INT8 *BaseName;
|
||||
INT8 *Processor;
|
||||
INT8 *Makefile;
|
||||
UINT32 Index;
|
||||
UINT32 CompleteFlag;
|
||||
SOURCE_FILE_ITEM *SourceFileList;
|
||||
DEPENDENCY_ITEM *DependencyList;
|
||||
} BUILD_ITEM;
|
||||
|
||||
//
|
||||
// Use this structure to keep track of module source files
|
||||
//
|
||||
typedef struct _SOURCE_FILE_ITEM {
|
||||
SOURCE_FILE_ITEM *Next;
|
||||
INT8 *FileName;
|
||||
} SOURCE_FILE_ITEM;
|
||||
|
||||
//
|
||||
// Use this structure to keep track of module build dependencies
|
||||
//
|
||||
typedef struct _DEPENDENCY_ITEM {
|
||||
DEPENDENCY_ITEM *Next;
|
||||
BUILD_ITEM *Dependency;
|
||||
} DEPENDENCY_ITEM;
|
||||
|
||||
//
|
||||
// Use this structure to keep track of [components] and [components.n] sections
|
||||
//
|
||||
typedef struct _COMPONENTS_ITEM {
|
||||
COMPONENTS_ITEM *Next;
|
||||
BUILD_ITEM *BuildList;
|
||||
} COMPONENTS_ITEM;
|
||||
|
||||
//
|
||||
// Function prototypes
|
||||
//
|
||||
BUILD_ITEM *
|
||||
AddBuildItem (
|
||||
BUILD_ITEM **BuildList,
|
||||
INT8 *BaseName,
|
||||
INT8 *Processor,
|
||||
INT8 *Makefile
|
||||
);
|
||||
|
||||
|
||||
SOURCE_FILE_ITEM *
|
||||
AddSourceFile (
|
||||
BUILD_ITEM *BuildItem,
|
||||
INT8 *FileName
|
||||
);
|
||||
|
||||
DEPENDENCY_ITEM *
|
||||
AddDependency (
|
||||
BUILD_ITEM *BuildList,
|
||||
BUILD_ITEM *BuildItem,
|
||||
INT8 *BaseName,
|
||||
INT8 AdjustIndex
|
||||
);
|
||||
|
||||
void
|
||||
FreeBuildList (
|
||||
BUILD_ITEM *BuildList
|
||||
);
|
||||
|
||||
COMPONENTS_ITEM *
|
||||
AddComponentsItem (
|
||||
COMPONENTS_ITEM **ComponentsList
|
||||
);
|
||||
|
||||
void
|
||||
FreeComponentsList (
|
||||
COMPONENTS_ITEM *ComponentsList
|
||||
);
|
||||
|
||||
INT8
|
||||
StartMultiThreadBuild (
|
||||
BUILD_ITEM **BuildList,
|
||||
UINT32 ThreadNumber,
|
||||
INT8 *BuildDir
|
||||
);
|
||||
|
||||
#endif // ifndef _MULTI_THREAD_H_
|
@@ -1,6 +1,6 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 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
|
||||
@@ -27,25 +27,18 @@ Abstract:
|
||||
#include <direct.h> // for _mkdir()
|
||||
#include <errno.h>
|
||||
#include <stdlib.h> // for getenv()
|
||||
#include <shlwapi.h> // for PathCanonicalize()
|
||||
#include "DSCFile.h"
|
||||
#include "MultiThread.h"
|
||||
#include "FWVolume.h"
|
||||
#include "Exceptions.h"
|
||||
#include "Common.h"
|
||||
|
||||
#include "EfiUtilityMsgs.h"
|
||||
#include "TianoBind.h"
|
||||
//
|
||||
// Disable warning for while(1) code
|
||||
//
|
||||
#pragma warning(disable : 4127)
|
||||
//
|
||||
// Disable warning for unreferenced function parameters
|
||||
//
|
||||
#pragma warning(disable : 4100)
|
||||
|
||||
extern int errno;
|
||||
|
||||
#define PROGRAM_NAME "ProcessDsc"
|
||||
#define UTILITY_NAME "ProcessDsc"
|
||||
#define UTILITY_VERSION "v1.0"
|
||||
|
||||
//
|
||||
// Common symbol name definitions. For example, the user can reference
|
||||
@@ -220,25 +213,39 @@ typedef struct _SYMBOL {
|
||||
} SYMBOL;
|
||||
|
||||
//
|
||||
// Define new SYMBOL list to record all module name used in the platform.dsc file.
|
||||
// Module globals for multi-thread build
|
||||
//
|
||||
SYMBOL *gModuleList = NULL;
|
||||
static BUILD_ITEM **mCurrentBuildList; // build list currently handling
|
||||
static BUILD_ITEM *mCurrentBuildItem; // build item currently handling
|
||||
|
||||
//
|
||||
// Define masks for the build targets
|
||||
//
|
||||
#define BUILD_TARGET_COMPONENTS 0x01
|
||||
#define BUILD_TARGET_LIBRARIES 0x02
|
||||
#define BUILD_TARGET_FVS 0x04
|
||||
#define BUILD_TARGET_ALL 0xff
|
||||
|
||||
|
||||
//
|
||||
// This structure is used to save globals
|
||||
//
|
||||
struct {
|
||||
INT8 *DscFilename;
|
||||
SYMBOL *Symbol;
|
||||
INT8 MakefileName[MAX_PATH]; // output makefile name
|
||||
INT8 XRefFileName[MAX_PATH];
|
||||
INT8 GuidDatabaseFileName[MAX_PATH];
|
||||
INT8 ModuleMakefileName[MAX_PATH];
|
||||
FILE *MakefileFptr;
|
||||
FILE *ModuleMakefileFptr;
|
||||
SYMBOL *ModuleList;
|
||||
SYMBOL *OutdirList;
|
||||
UINT32 Verbose;
|
||||
INT8 *DscFilename;
|
||||
SYMBOL *Symbol;
|
||||
INT8 MakefileName[MAX_PATH]; // output makefile name
|
||||
INT8 XRefFileName[MAX_PATH];
|
||||
INT8 GuidDatabaseFileName[MAX_PATH];
|
||||
INT8 ModuleMakefileName[MAX_PATH];
|
||||
FILE *MakefileFptr;
|
||||
FILE *ModuleMakefileFptr;
|
||||
SYMBOL *ModuleList;
|
||||
SYMBOL *OutdirList;
|
||||
UINT32 Verbose;
|
||||
UINT32 ThreadNumber;
|
||||
UINT32 BuildTarget;
|
||||
BUILD_ITEM *LibraryList;
|
||||
COMPONENTS_ITEM *ComponentsList;
|
||||
} gGlobals;
|
||||
|
||||
//
|
||||
@@ -584,16 +591,18 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
int i;
|
||||
DSC_FILE DSCFile;
|
||||
SECTION *Sect;
|
||||
INT8 Line[MAX_LINE_LEN];
|
||||
INT8 ExpLine[MAX_LINE_LEN];
|
||||
INT8 *EMsg;
|
||||
FILE *FpModule;
|
||||
SYMBOL *TempSymbol;
|
||||
int i;
|
||||
DSC_FILE DSCFile;
|
||||
SECTION *Sect;
|
||||
INT8 Line[MAX_LINE_LEN];
|
||||
INT8 ExpLine[MAX_LINE_LEN];
|
||||
INT8 *BuildDir;
|
||||
INT8 *EMsg;
|
||||
FILE *FpModule;
|
||||
SYMBOL *TempSymbol;
|
||||
COMPONENTS_ITEM *TempComponents;
|
||||
|
||||
SetUtilityName (PROGRAM_NAME);
|
||||
SetUtilityName (UTILITY_NAME);
|
||||
|
||||
InitExceptions ();
|
||||
|
||||
@@ -710,6 +719,7 @@ Returns:
|
||||
//
|
||||
Sect = DSCFileFindSection (&DSCFile, LIBRARIES_SECTION_NAME);
|
||||
if (Sect != NULL) {
|
||||
mCurrentBuildList = &gGlobals.LibraryList;
|
||||
ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_LIBRARIES, 0);
|
||||
}
|
||||
|
||||
@@ -721,6 +731,7 @@ Returns:
|
||||
//
|
||||
Sect = DSCFileFindSection (&DSCFile, LIBRARIES_PLATFORM_SECTION_NAME);
|
||||
if (Sect != NULL) {
|
||||
mCurrentBuildList = &gGlobals.LibraryList;
|
||||
ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_PLATFORM_LIBRARIES, 0);
|
||||
}
|
||||
|
||||
@@ -735,6 +746,8 @@ Returns:
|
||||
Sect = DSCFileFindSection (&DSCFile, COMPONENTS_SECTION_NAME);
|
||||
if (Sect != NULL) {
|
||||
fprintf (gGlobals.MakefileFptr, "components_0 : \n");
|
||||
TempComponents = AddComponentsItem (&gGlobals.ComponentsList);
|
||||
mCurrentBuildList = &TempComponents->BuildList;
|
||||
ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_COMPONENTS, 0);
|
||||
fprintf (gGlobals.MakefileFptr, "\n");
|
||||
}
|
||||
@@ -754,6 +767,8 @@ Returns:
|
||||
Sect = DSCFileFindSection (&DSCFile, Line);
|
||||
if (Sect != NULL) {
|
||||
fprintf (gGlobals.MakefileFptr, "components_%d : \n", i);
|
||||
TempComponents = AddComponentsItem (&gGlobals.ComponentsList);
|
||||
mCurrentBuildList = &TempComponents->BuildList;
|
||||
ProcessSectionComponents (&DSCFile, DSC_SECTION_TYPE_COMPONENTS, i);
|
||||
fprintf (gGlobals.MakefileFptr, "\n");
|
||||
} else {
|
||||
@@ -807,12 +822,52 @@ ProcessingError:
|
||||
fclose (gGlobals.ModuleMakefileFptr);
|
||||
gGlobals.ModuleMakefileFptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Start multi-thread build if ThreadNumber is specified and no error status
|
||||
//
|
||||
if ((gGlobals.ThreadNumber != 0) && (GetUtilityStatus () < STATUS_ERROR)) {
|
||||
BuildDir = GetSymbolValue (BUILD_DIR);
|
||||
if (gGlobals.BuildTarget & BUILD_TARGET_LIBRARIES) {
|
||||
if (StartMultiThreadBuild (&gGlobals.LibraryList, gGlobals.ThreadNumber, BuildDir) != 0) {
|
||||
Error (NULL, 0, 0, NULL, "Multi-thread build libraries failure");
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
TempComponents = gGlobals.ComponentsList;
|
||||
while (TempComponents != NULL) {
|
||||
if (gGlobals.BuildTarget & BUILD_TARGET_COMPONENTS) {
|
||||
if (StartMultiThreadBuild (&TempComponents->BuildList, gGlobals.ThreadNumber, BuildDir) != 0) {
|
||||
Error (NULL, 0, 0, NULL, "Multi-thread build components %d failure", i);
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
if (gGlobals.BuildTarget & BUILD_TARGET_FVS) {
|
||||
sprintf (ExpLine, "nmake -nologo -f %s fvs_%d", gGlobals.MakefileName, i);
|
||||
_flushall ();
|
||||
if (system (ExpLine)) {
|
||||
Error (NULL, 0, 0, NULL, "Build FVs for components %d failure", i);
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
TempComponents = TempComponents->Next;
|
||||
}
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
//
|
||||
// Clean up
|
||||
//
|
||||
FreeBuildList (gGlobals.LibraryList);
|
||||
gGlobals.LibraryList = NULL;
|
||||
FreeComponentsList (gGlobals.ComponentsList);
|
||||
gGlobals.ComponentsList = NULL;
|
||||
FreeSymbols (gGlobals.ModuleList);
|
||||
gGlobals.ModuleList = NULL;
|
||||
FreeSymbols (gGlobals.OutdirList);
|
||||
gGlobals.OutdirList = NULL;
|
||||
FreeSymbols (gGlobals.Symbol);
|
||||
gGlobals.Symbol = NULL;
|
||||
CFVDestructor ();
|
||||
@@ -1311,6 +1366,16 @@ Returns:
|
||||
CreatePackageFile (DSCFile);
|
||||
}
|
||||
|
||||
//
|
||||
// Add a new build item to mCurrentBuildList
|
||||
//
|
||||
mCurrentBuildItem = AddBuildItem (mCurrentBuildList, GetSymbolValue (BASE_NAME), Processor, FileName);
|
||||
//
|
||||
// ProcessDsc allows duplicate base name libraries. Make sure the duplicate
|
||||
// base name libraries will be built in the same order as listed in DSC file.
|
||||
//
|
||||
AddDependency (*mCurrentBuildList, mCurrentBuildItem, mCurrentBuildItem->BaseName, 1);
|
||||
|
||||
//
|
||||
// Add Module name to the global module list
|
||||
//
|
||||
@@ -1336,6 +1401,7 @@ Returns:
|
||||
// files in this component. This macro can then be used elsewhere to
|
||||
// process all the files making up the component. Required for scanning
|
||||
// files for string localization.
|
||||
// Also add source files to mCurrentBuildItem.
|
||||
//
|
||||
ProcessSourceFiles (DSCFile, &ComponentFile, MakeFptr, SOURCE_MODE_SOURCE_FILES);
|
||||
//
|
||||
@@ -1370,7 +1436,8 @@ Returns:
|
||||
// Process all the libraries to define "LIBS = x.lib y.lib..."
|
||||
// Be generous and append ".lib" if they forgot.
|
||||
// Make a macro definition: LIBS = $(LIBS) xlib.lib ylib.lib...
|
||||
// Also add libs dependency for single module build: basenamebuild :: xlibbuild ylibbuild ...
|
||||
// Add libs dependency for single module build: basenamebuild :: xlibbuild ylibbuild ...
|
||||
// Also add libs dependency to mCurrentBuildItem.
|
||||
//
|
||||
ProcessLibs (&ComponentFile, MakeFptr);
|
||||
|
||||
@@ -1829,8 +1896,14 @@ Returns:
|
||||
OverridePath = GetSymbolValue (SOURCE_OVERRIDE_PATH);
|
||||
if (OverridePath != NULL) {
|
||||
ReplaceSlash (OverridePath);
|
||||
fprintf (MakeFptr, "!IF EXIST(%s)\n", OverridePath);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s\n", OverridePath);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s\\%s \n", OverridePath, Processor);
|
||||
fprintf (MakeFptr, "!IF EXIST(%s\\%s)\n", OverridePath, Processor);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s\\%s\n", OverridePath, Processor);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
fprintf (MakeFptr, "!ELSE\n");
|
||||
fprintf (MakeFptr, "!MESSAGE Warning: include dir %s does not exist\n", OverridePath);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
}
|
||||
//
|
||||
// Try for an [includes.$(PROCESSOR).$(PLATFORM)]
|
||||
@@ -1909,43 +1982,45 @@ ProcessIncludesSectionSingle (
|
||||
//
|
||||
if (Cptr[1] == 0) {
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\n");
|
||||
fprintf (
|
||||
MakeFptr,
|
||||
"INC = $(INC) -I $(SOURCE_DIR)\\%s \n",
|
||||
Processor
|
||||
);
|
||||
fprintf (MakeFptr, "!IF EXIST($(SOURCE_DIR)\\%s)\n", Processor);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\\%s\n", Processor);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
} else {
|
||||
//
|
||||
// Handle case of ".\path\path\path" or "..\path\path\path"
|
||||
//
|
||||
fprintf (
|
||||
MakeFptr,
|
||||
"INC = $(INC) -I $(SOURCE_DIR)\\%s \n",
|
||||
Cptr
|
||||
);
|
||||
fprintf (
|
||||
MakeFptr,
|
||||
"INC = $(INC) -I $(SOURCE_DIR)\\%s\\%s \n",
|
||||
Cptr,
|
||||
Processor
|
||||
);
|
||||
fprintf (MakeFptr, "!IF EXIST($(SOURCE_DIR)\\%s)\n", Cptr);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\\%s\n", Cptr);
|
||||
fprintf (MakeFptr, "!IF EXIST($(SOURCE_DIR)\\%s\\%s)\n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(SOURCE_DIR)\\%s\\%s\n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
fprintf (MakeFptr, "!ELSE\n");
|
||||
fprintf (MakeFptr, "!MESSAGE Warning: include dir $(SOURCE_DIR)\\%s does not exist\n", Cptr);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
}
|
||||
} else if ((Cptr[1] != ':') && isalpha (*Cptr)) {
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(EFI_SOURCE)\\%s \n", Cptr);
|
||||
fprintf (
|
||||
MakeFptr,
|
||||
"INC = $(INC) -I $(EFI_SOURCE)\\%s\\%s \n",
|
||||
Cptr,
|
||||
Processor
|
||||
);
|
||||
fprintf (MakeFptr, "!IF EXIST($(EFI_SOURCE)\\%s)\n", Cptr);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(EFI_SOURCE)\\%s\n", Cptr);
|
||||
fprintf (MakeFptr, "!IF EXIST($(EFI_SOURCE)\\%s\\%s)\n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I $(EFI_SOURCE)\\%s\\%s\n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
fprintf (MakeFptr, "!ELSE\n");
|
||||
fprintf (MakeFptr, "!MESSAGE Warning: include dir $(EFI_SOURCE)\\%s does not exist\n", Cptr);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
} else {
|
||||
//
|
||||
// The line is something like: $(EFI_SOURCE)\dxe\include. Add it to
|
||||
// the existing $(INC) definition. Add user includes before any
|
||||
// other existing paths.
|
||||
//
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s \n", Cptr);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s\\%s \n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "!IF EXIST(%s)\n", Cptr);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s\n", Cptr);
|
||||
fprintf (MakeFptr, "!IF EXIST(%s\\%s)\n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "INC = $(INC) -I %s\\%s\n", Cptr, Processor);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
fprintf (MakeFptr, "!ELSE\n");
|
||||
fprintf (MakeFptr, "!MESSAGE Warning: include dir %s does not exist\n", Cptr);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2260,16 +2335,35 @@ ProcessSourceFilesSection (
|
||||
// SOURCE_FILES = $(SOURCE_FILES) c:\Path\ThisFile.c
|
||||
//
|
||||
fprintf (MakeFptr, "SOURCE_FILES = $(SOURCE_FILES) %s\n", TempFileName);
|
||||
//
|
||||
// Save the source absolute path
|
||||
//
|
||||
if (PathCanonicalize (FilePath, TempFileName)) {
|
||||
AddSourceFile (mCurrentBuildItem, FilePath);
|
||||
}
|
||||
} else if (IsAbsolutePath (FileName)) {
|
||||
//
|
||||
// For Absolute path, don't print $(SOURCE_FILE) directory.
|
||||
//
|
||||
fprintf (MakeFptr, "SOURCE_FILES = $(SOURCE_FILES) %s\n", FileName);
|
||||
//
|
||||
// Save the source absolute path
|
||||
//
|
||||
if (PathCanonicalize (FilePath, FileName)) {
|
||||
AddSourceFile (mCurrentBuildItem, FilePath);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// SOURCE_FILES = $(SOURCE_FILES) $(SOURCE_DIR)\ThisFile.c
|
||||
//
|
||||
fprintf (MakeFptr, "SOURCE_FILES = $(SOURCE_FILES) $(SOURCE_DIR)\\%s\n", FileName);
|
||||
//
|
||||
// Save the source absolute path
|
||||
//
|
||||
sprintf (Str, "%s\\%s", GetSymbolValue (SOURCE_DIR), FileName);
|
||||
if (PathCanonicalize (FilePath, Str)) {
|
||||
AddSourceFile (mCurrentBuildItem, FilePath);
|
||||
}
|
||||
}
|
||||
} else if (Mode & SOURCE_MODE_BUILD_COMMANDS) {
|
||||
//
|
||||
@@ -2612,6 +2706,10 @@ ProcessLibsSingle (
|
||||
Cptr[strlen (Cptr) - 4] = 0;
|
||||
fprintf (gGlobals.ModuleMakefileFptr, " %sbuild", Cptr);
|
||||
}
|
||||
//
|
||||
// Add libs dependency for mCurrentBuildItem
|
||||
//
|
||||
AddDependency (*mCurrentBuildList, mCurrentBuildItem, Cptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2767,8 +2865,9 @@ ProcessIncludeFilesSingle (
|
||||
if (Cptr >= TempFileName) {
|
||||
*Cptr = 0;
|
||||
}
|
||||
|
||||
fprintf (MakeFptr, "!IF EXIST(%s)\n", TempFileName);
|
||||
fprintf (MakeFptr, "INC = -I %s $(INC)\n", TempFileName);
|
||||
fprintf (MakeFptr, "!ENDIF\n");
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -4173,6 +4272,63 @@ Returns:
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Enable multi-thread build and specify the thread number
|
||||
//
|
||||
case 'n':
|
||||
case 'N':
|
||||
//
|
||||
// Skip to next arg
|
||||
//
|
||||
Argc--;
|
||||
Argv++;
|
||||
if (Argc == 0) {
|
||||
Argv--;
|
||||
Error (NULL, 0, 0, Argv[0], "missing input thread number with option");
|
||||
Usage ();
|
||||
return STATUS_ERROR;
|
||||
} else {
|
||||
gGlobals.ThreadNumber = atoi (Argv[0]);
|
||||
if (gGlobals.ThreadNumber == 0) {
|
||||
Argv--;
|
||||
Error (NULL, 0, 0, Argv[0], "input thread number should not be %s", Argv[1]);
|
||||
return STATUS_ERROR;
|
||||
} else if (gGlobals.ThreadNumber > MAXIMUM_WAIT_OBJECTS) {
|
||||
Argv--;
|
||||
Error (NULL, 0, 0, Argv[0], "input thread number should not greater than %d", MAXIMUM_WAIT_OBJECTS);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Specify the multi-thread build target
|
||||
//
|
||||
case 't':
|
||||
case 'T':
|
||||
//
|
||||
// Skip to next arg
|
||||
//
|
||||
Argc--;
|
||||
Argv++;
|
||||
if (Argc == 0) {
|
||||
Argv--;
|
||||
Error (NULL, 0, 0, Argv[0], "missing input build target with option");
|
||||
Usage ();
|
||||
return STATUS_ERROR;
|
||||
} else if (_stricmp (Argv[0], "all") == 0) {
|
||||
gGlobals.BuildTarget |= BUILD_TARGET_ALL;
|
||||
} else if (_stricmp (Argv[0], "libraries") == 0) {
|
||||
gGlobals.BuildTarget |= BUILD_TARGET_LIBRARIES;
|
||||
} else if (_stricmp (Argv[0], "components") == 0) {
|
||||
gGlobals.BuildTarget |= BUILD_TARGET_COMPONENTS;
|
||||
} else {
|
||||
Argv--;
|
||||
Error (NULL, 0, 0, Argv[0], "input build target not supported");
|
||||
Usage ();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
gGlobals.Verbose = 1;
|
||||
@@ -4228,7 +4384,14 @@ Returns:
|
||||
if (FreeCwd) {
|
||||
free (Cptr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Default build target is all
|
||||
//
|
||||
if (gGlobals.BuildTarget == 0) {
|
||||
gGlobals.BuildTarget = BUILD_TARGET_ALL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4426,18 +4589,29 @@ Usage (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
int i;
|
||||
static const INT8 *Help[] = {
|
||||
"Usage: ProcessDsc {options} [Dsc Filename]",
|
||||
" Options:",
|
||||
" -d var=value to define symbol 'var' to 'value'",
|
||||
" -v for verbose mode",
|
||||
" -g filename to preparse GUID listing file",
|
||||
" -x filename to create a cross-reference file",
|
||||
int Index;
|
||||
const char *Str[] = {
|
||||
UTILITY_NAME" "UTILITY_VERSION" - Intel Process DSC File Utility",
|
||||
" Copyright (C), 2004 - 2008 Intel Corporation",
|
||||
|
||||
#if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
|
||||
" Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
|
||||
#endif
|
||||
"",
|
||||
"Usage:",
|
||||
" "UTILITY_NAME" [OPTION]... DSCFILE",
|
||||
"Options:",
|
||||
" -d var=value to define symbol 'var' to 'value'",
|
||||
" -v for verbose mode",
|
||||
" -g filename to preparse GUID listing file",
|
||||
" -x filename to create a cross-reference file",
|
||||
" -n threadnumber to build with multi-thread",
|
||||
" -t target to build the specified target:",
|
||||
" all, libraries or components",
|
||||
NULL
|
||||
};
|
||||
for (i = 0; Help[i] != NULL; i++) {
|
||||
fprintf (stdout, "%s\n", Help[i]);
|
||||
for (Index = 0; Str[Index] != NULL; Index++) {
|
||||
fprintf (stdout, "%s\n", Str[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4562,7 +4736,7 @@ SmartOpen (
|
||||
if (SmartFile->FileContent != NULL) {
|
||||
memset (SmartFile->FileContent, 0, FileSize + 1);
|
||||
//
|
||||
// Usually FileLength < FileSize, because in text mode, carriage return-linefeed
|
||||
// Usually FileLength < FileSize, because in text mode, carriage return<EFBFBD>Clinefeed
|
||||
// combinations are translated into single linefeeds on input
|
||||
//
|
||||
SmartFile->FileLength = fread (SmartFile->FileContent, sizeof(char), FileSize, Fptr);
|
||||
|
Reference in New Issue
Block a user