BaseTools: Update Build tool to support multiple workspaces

WORKSPACE is still kept.
New PACKAGES_PATH is introduced to specify the additional WORKSPACEs.
In PACKAGES_PATH, ';' is separator in Windows, ':' is separator in Linux.

Build directory is in WORKSPACE. Package, BaseTools and Conf directory
will be found from WORKSPACE and PACKAGES_PATH.

In implementation, BaseTools adds MultipleWorkspace class for
the file path conversion from WORKSPACE and PACKAGES_PATH.

Verify two tree layouts.
Root\edk2\MdePkg
Root\edk2\MdeMdeModulePkg
Root\edk2\...
1. set WORKSPACE=Root\edk2
2. set WORKSPACE=Root, and set PACKAGES_PATH=Root\edk2

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Li YangX <yangx.li@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18579 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Li YangX 2015-10-08 09:27:14 +00:00 committed by lgao4
parent 6fa04d934b
commit 05cc51ad58
15 changed files with 232 additions and 35 deletions

View File

@ -40,7 +40,7 @@ from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
import Common.VpdInfoFile as VpdInfoFile import Common.VpdInfoFile as VpdInfoFile
from GenPcdDb import CreatePcdDatabaseCode from GenPcdDb import CreatePcdDatabaseCode
from Workspace.MetaFileCommentParser import UsageList from Workspace.MetaFileCommentParser import UsageList
from Common.MultipleWorkspace import MultipleWorkspace as mws
import InfSectionParser import InfSectionParser
## Regular expression for splitting Dependency Expression string into tokens ## Regular expression for splitting Dependency Expression string into tokens
@ -953,7 +953,7 @@ class PlatformAutoGen(AutoGen):
self._GuidValue = {} self._GuidValue = {}
FdfModuleList = [] FdfModuleList = []
for InfName in self._AsBuildInfList: for InfName in self._AsBuildInfList:
InfName = os.path.join(self.WorkspaceDir, InfName) InfName = mws.join(self.WorkspaceDir, InfName)
FdfModuleList.append(os.path.normpath(InfName)) FdfModuleList.append(os.path.normpath(InfName))
for F in self.Platform.Modules.keys(): for F in self.Platform.Modules.keys():
M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile) M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)
@ -1288,7 +1288,7 @@ class PlatformAutoGen(AutoGen):
def _GetFdfFile(self): def _GetFdfFile(self):
if self._FdfFile == None: if self._FdfFile == None:
if self.Workspace.FdfFile != "": if self.Workspace.FdfFile != "":
self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile) self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)
else: else:
self._FdfFile = '' self._FdfFile = ''
return self._FdfFile return self._FdfFile
@ -2115,8 +2115,11 @@ class PlatformAutoGen(AutoGen):
BuildOptions[Tool][Attr] = "" BuildOptions[Tool][Attr] = ""
# check if override is indicated # check if override is indicated
if Value.startswith('='): if Value.startswith('='):
BuildOptions[Tool][Attr] = Value[1:] ToolPath = Value[1:]
ToolPath = mws.handleWsMacro(ToolPath)
BuildOptions[Tool][Attr] = ToolPath
else: else:
Value = mws.handleWsMacro(Value)
BuildOptions[Tool][Attr] += " " + Value BuildOptions[Tool][Attr] += " " + Value
if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None: if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:
# #
@ -2193,8 +2196,7 @@ class ModuleAutoGen(AutoGen):
return False return False
self.SourceDir = self.MetaFile.SubDir self.SourceDir = self.MetaFile.SubDir
if self.SourceDir.upper().find(self.WorkspaceDir.upper()) == 0: self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)
self.SourceDir = self.SourceDir[len(self.WorkspaceDir) + 1:]
self.SourceOverrideDir = None self.SourceOverrideDir = None
# use overrided path defined in DSC file # use overrided path defined in DSC file
@ -3042,7 +3044,7 @@ class ModuleAutoGen(AutoGen):
self._IncludePathList.append(self.DebugDir) self._IncludePathList.append(self.DebugDir)
for Package in self.Module.Packages: for Package in self.Module.Packages:
PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir) PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
if PackageDir not in self._IncludePathList: if PackageDir not in self._IncludePathList:
self._IncludePathList.append(PackageDir) self._IncludePathList.append(PackageDir)
for Inc in Package.Includes: for Inc in Package.Includes:

View File

@ -19,7 +19,7 @@ import string
import re import re
import os.path as path import os.path as path
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common.BuildToolError import * from Common.BuildToolError import *
from Common.Misc import * from Common.Misc import *
from Common.String import * from Common.String import *
@ -559,7 +559,7 @@ cleanlib:
found = False found = False
while not found and os.sep in package_rel_dir: while not found and os.sep in package_rel_dir:
index = package_rel_dir.index(os.sep) index = package_rel_dir.index(os.sep)
current_dir = os.path.join(current_dir, package_rel_dir[:index]) current_dir = mws.join(current_dir, package_rel_dir[:index])
for fl in os.listdir(current_dir): for fl in os.listdir(current_dir):
if fl.endswith('.dec'): if fl.endswith('.dec'):
found = True found = True

View File

@ -17,6 +17,7 @@
import Common.LongFilePathOs as os, sys, time import Common.LongFilePathOs as os, sys, time
from DataType import * from DataType import *
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
## EdkIIWorkspace ## EdkIIWorkspace
# #
@ -112,7 +113,7 @@ class EdkIIWorkspace:
# @retval string The full path filename # @retval string The full path filename
# #
def WorkspaceFile(self, FileName): def WorkspaceFile(self, FileName):
return os.path.realpath(os.path.join(self.WorkspaceDir,FileName)) return os.path.realpath(mws.join(self.WorkspaceDir,FileName))
## Convert to a real path filename ## Convert to a real path filename
# #

View File

@ -20,6 +20,7 @@ import Common.LongFilePathOs as os
import CommonDataClass.FdfClass import CommonDataClass.FdfClass
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
##define T_CHAR_SPACE ' ' ##define T_CHAR_SPACE ' '
##define T_CHAR_NULL '\0' ##define T_CHAR_NULL '\0'
@ -485,7 +486,8 @@ class FdfParser(object):
IncFileName = self.__Token IncFileName = self.__Token
if not os.path.isabs(IncFileName): if not os.path.isabs(IncFileName):
if IncFileName.startswith('$(WORKSPACE)'): if IncFileName.startswith('$(WORKSPACE)'):
Str = IncFileName.replace('$(WORKSPACE)', os.environ.get('WORKSPACE')) Str = mws.handleWsMacro(IncFileName)
Str = Str.replace('$(WORKSPACE)', os.environ.get('WORKSPACE'))
if os.path.exists(Str): if os.path.exists(Str):
if not os.path.isabs(Str): if not os.path.isabs(Str):
Str = os.path.abspath(Str) Str = os.path.abspath(Str)
@ -494,7 +496,7 @@ class FdfParser(object):
# file is in the same dir with FDF file # file is in the same dir with FDF file
FullFdf = self.FileName FullFdf = self.FileName
if not os.path.isabs(self.FileName): if not os.path.isabs(self.FileName):
FullFdf = os.path.join(os.environ.get('WORKSPACE'), self.FileName) FullFdf = mws.join(os.environ.get('WORKSPACE'), self.FileName)
IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName) IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName)

View File

@ -49,3 +49,5 @@ dirname = os.path.dirname
islink = os.path.islink islink = os.path.islink
isabs = os.path.isabs isabs = os.path.isabs
realpath = os.path.realpath realpath = os.path.realpath
relpath = os.path.relpath
pardir = os.path.pardir

View File

@ -35,6 +35,7 @@ from BuildToolError import *
from CommonDataClass.DataClass import * from CommonDataClass.DataClass import *
from Parsing import GetSplitValueList from Parsing import GetSplitValueList
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
## Regular expression used to find out place holders in string template ## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE) gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE)
@ -1728,6 +1729,7 @@ class PathClass(object):
# Remove any '.' and '..' in path # Remove any '.' and '..' in path
if self.Root: if self.Root:
self.Root = mws.getWs(self.Root, self.File)
self.Path = os.path.normpath(os.path.join(self.Root, self.File)) self.Path = os.path.normpath(os.path.join(self.Root, self.File))
self.Root = os.path.normpath(CommonPath([self.Root, self.Path])) self.Root = os.path.normpath(CommonPath([self.Root, self.Path]))
# eliminate the side-effect of 'C:' # eliminate the side-effect of 'C:'
@ -1838,7 +1840,10 @@ class PathClass(object):
RealFile = os.path.join(self.AlterRoot, self.File) RealFile = os.path.join(self.AlterRoot, self.File)
elif self.Root: elif self.Root:
RealFile = os.path.join(self.Root, self.File) RealFile = os.path.join(self.Root, self.File)
if len (mws.getPkgPath()) == 0:
return FILE_NOT_FOUND, os.path.join(self.AlterRoot, RealFile) return FILE_NOT_FOUND, os.path.join(self.AlterRoot, RealFile)
else:
return FILE_NOT_FOUND, "%s is not found in packages path:\n\t%s" % (self.File, '\n\t'.join(mws.getPkgPath()))
ErrorCode = 0 ErrorCode = 0
ErrorInfo = '' ErrorInfo = ''

View File

@ -0,0 +1,148 @@
## @file
# manage multiple workspace file.
#
# This file is required to make Python interpreter treat the directory
# as containing package.
#
# Copyright (c) 2015, 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 Common.LongFilePathOs as os
from Common.DataType import TAB_WORKSPACE
## MultipleWorkspace
#
# This class manage multiple workspace behavior
#
# @param class:
#
# @var WORKSPACE: defined the current WORKSPACE
# @var PACKAGES_PATH: defined the other WORKSAPCE, if current WORKSPACE is invalid, search valid WORKSPACE from PACKAGES_PATH
#
class MultipleWorkspace(object):
WORKSPACE = ''
PACKAGES_PATH = None
## convertPackagePath()
#
# Convert path to match workspace.
#
# @param cls The class pointer
# @param Ws The current WORKSPACE
# @param Path Path to be converted to match workspace.
#
@classmethod
def convertPackagePath(cls, Ws, Path):
if str(os.path.normcase (Path)).startswith(Ws):
return os.path.join(Ws, Path[len(Ws) + 1:])
return Path
## setWs()
#
# set WORKSPACE and PACKAGES_PATH environment
#
# @param cls The class pointer
# @param Ws initialize WORKSPACE variable
# @param PackagesPath initialize PackagesPath variable
#
@classmethod
def setWs(cls, Ws, PackagesPath=None):
cls.WORKSPACE = Ws
if PackagesPath:
cls.PACKAGES_PATH = [cls.convertPackagePath (Ws, os.path.normpath(Path.strip())) for Path in PackagesPath.split(os.pathsep)]
else:
cls.PACKAGES_PATH = []
## join()
#
# rewrite os.path.join function
#
# @param cls The class pointer
# @param Ws the current WORKSPACE
# @param *p path of the inf/dec/dsc/fdf/conf file
# @retval Path the absolute path of specified file
#
@classmethod
def join(cls, Ws, *p):
Path = os.path.join(Ws, *p)
if not os.path.exists(Path):
for Pkg in cls.PACKAGES_PATH:
Path = os.path.join(Pkg, *p)
if os.path.exists(Path):
return Path
Path = os.path.join(Ws, *p)
return Path
## relpath()
#
# rewrite os.path.relpath function
#
# @param cls The class pointer
# @param Path path of the inf/dec/dsc/fdf/conf file
# @param Ws the current WORKSPACE
# @retval Path the relative path of specified file
#
@classmethod
def relpath(cls, Path, Ws):
for Pkg in cls.PACKAGES_PATH:
if Path.lower().startswith(Pkg.lower()):
Path = os.path.relpath(Path, Pkg)
return Path
if Path.lower().startswith(Ws.lower()):
Path = os.path.relpath(Path, Ws)
return Path
## getWs()
#
# get valid workspace for the path
#
# @param cls The class pointer
# @param Ws the current WORKSPACE
# @param Path path of the inf/dec/dsc/fdf/conf file
# @retval Ws the valid workspace relative to the specified file path
#
@classmethod
def getWs(cls, Ws, Path):
absPath = os.path.join(Ws, Path)
if not os.path.exists(absPath):
for Pkg in cls.PACKAGES_PATH:
absPath = os.path.join(Pkg, Path)
if os.path.exists(absPath):
return Pkg
return Ws
## handleWsMacro()
#
# handle the $(WORKSPACE) tag, if current workspace is invalid path relative the tool, replace it.
#
# @param cls The class pointer
# @retval PathStr Path string include the $(WORKSPACE)
#
@classmethod
def handleWsMacro(cls, PathStr):
if TAB_WORKSPACE in PathStr:
Path = PathStr.replace(TAB_WORKSPACE, cls.WORKSPACE).strip()
if not os.path.exists(Path):
for Pkg in cls.PACKAGES_PATH:
Path = PathStr.replace(TAB_WORKSPACE, Pkg).strip()
if os.path.exists(Path):
return Path
return PathStr
## getPkgPath()
#
# get all package pathes.
#
# @param cls The class pointer
#
@classmethod
def getPkgPath(cls):
return cls.PACKAGES_PATH

View File

@ -24,6 +24,7 @@ import GlobalData
from BuildToolError import * from BuildToolError import *
from CommonDataClass.Exceptions import * from CommonDataClass.Exceptions import *
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
gHexVerPatt = re.compile('0x[a-f0-9]{4}[a-f0-9]{4}$', re.IGNORECASE) 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}$') gHumanReadableVerPatt = re.compile(r'([1-9][0-9]*|0)\.[0-9]{1,2}$')
@ -305,6 +306,11 @@ def NormPath(Path, Defines={}):
# To local path format # To local path format
# #
Path = os.path.normpath(Path) Path = os.path.normpath(Path)
if Path.startswith(GlobalData.gWorkspace) and not os.path.exists(Path):
Path = Path[len (GlobalData.gWorkspace):]
if Path[0] == os.path.sep:
Path = Path[1:]
Path = mws.join(GlobalData.gWorkspace, Path)
if IsRelativePath and Path[0] != '.': if IsRelativePath and Path[0] != '.':
Path = os.path.join('.', Path) Path = os.path.join('.', Path)
@ -702,7 +708,7 @@ def RaiseParserError(Line, Section, File, Format='', LineNo= -1):
# @retval string A full path # @retval string A full path
# #
def WorkspaceFile(WorkspaceDir, Filename): def WorkspaceFile(WorkspaceDir, Filename):
return os.path.join(NormPath(WorkspaceDir), NormPath(Filename)) return mws.join(NormPath(WorkspaceDir), NormPath(Filename))
## Split string ## Split string
# #

View File

@ -28,6 +28,7 @@ import Section
import RuleSimpleFile import RuleSimpleFile
import RuleComplexFile import RuleComplexFile
from CommonDataClass.FdfClass import FfsInfStatementClassObject from CommonDataClass.FdfClass import FfsInfStatementClassObject
from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common.String import * from Common.String import *
from Common.Misc import PathClass from Common.Misc import PathClass
from Common.Misc import GuidStructureByteArrayToGuidString from Common.Misc import GuidStructureByteArrayToGuidString
@ -365,7 +366,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
# #
self.__InfParse__(Dict) self.__InfParse__(Dict)
SrcFile = os.path.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName); SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);
DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
SrcFileDir = "." SrcFileDir = "."
@ -511,7 +512,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
# #
def __GetPlatformArchList__(self): def __GetPlatformArchList__(self):
InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)) InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
DscArchList = [] DscArchList = []
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
if PlatformDataBase != None: if PlatformDataBase != None:
@ -878,7 +879,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
if not HasGneratedFlag: if not HasGneratedFlag:
UniVfrOffsetFileSection = "" UniVfrOffsetFileSection = ""
ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName) ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch] InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
# #
# Search the source list in InfData to find if there are .vfr file exist. # Search the source list in InfData to find if there are .vfr file exist.

View File

@ -39,6 +39,7 @@ from Common.Misc import SaveFileOnChange
from Common.Misc import ClearDuplicatedInf from Common.Misc import ClearDuplicatedInf
from Common.Misc import GuidStructureStringToGuidString from Common.Misc import GuidStructureStringToGuidString
from Common.BuildVersion import gBUILD_VERSION from Common.BuildVersion import gBUILD_VERSION
from Common.MultipleWorkspace import MultipleWorkspace as mws
## Version and Copyright ## Version and Copyright
versionNumber = "1.0" + ' ' + gBUILD_VERSION versionNumber = "1.0" + ' ' + gBUILD_VERSION
@ -95,6 +96,10 @@ def main():
GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace) GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace)
os.chdir(GenFdsGlobalVariable.WorkSpaceDir) os.chdir(GenFdsGlobalVariable.WorkSpaceDir)
# set multiple workspace
PackagesPath = os.getenv("PACKAGES_PATH")
mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)
if (Options.filename): if (Options.filename):
FdfFilename = Options.filename FdfFilename = Options.filename
FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)
@ -102,7 +107,7 @@ def main():
if FdfFilename[0:2] == '..': if FdfFilename[0:2] == '..':
FdfFilename = os.path.realpath(FdfFilename) FdfFilename = os.path.realpath(FdfFilename)
if not os.path.isabs (FdfFilename): if not os.path.isabs (FdfFilename):
FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename) FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)
if not os.path.exists(FdfFilename): if not os.path.exists(FdfFilename):
EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename) EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)
@ -129,13 +134,13 @@ def main():
ActivePlatform = os.path.realpath(ActivePlatform) ActivePlatform = os.path.realpath(ActivePlatform)
if not os.path.isabs (ActivePlatform): if not os.path.isabs (ActivePlatform):
ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)
if not os.path.exists(ActivePlatform) : if not os.path.exists(ActivePlatform) :
EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
if os.path.normcase (ActivePlatform).find(Workspace) == 0: if os.path.normcase (ActivePlatform).find(Workspace) == 0:
ActivePlatform = ActivePlatform[len(Workspace):] ActivePlatform = mws.relpath(ActivePlatform, Workspace)
if len(ActivePlatform) > 0 : if len(ActivePlatform) > 0 :
if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/': if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/':
ActivePlatform = ActivePlatform[1:] ActivePlatform = ActivePlatform[1:]
@ -159,7 +164,7 @@ def main():
ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath) ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)
else: else:
# Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf') ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')
GenFdsGlobalVariable.ConfDir = ConfDirectoryPath GenFdsGlobalVariable.ConfDir = ConfDirectoryPath
BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt")) BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))
if os.path.isfile(BuildConfigurationFile) == True: if os.path.isfile(BuildConfigurationFile) == True:

View File

@ -31,6 +31,7 @@ from AutoGen.BuildEngine import BuildRule
import Common.DataType as DataType import Common.DataType as DataType
from Common.Misc import PathClass from Common.Misc import PathClass
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
## Global variables ## Global variables
# #
@ -322,12 +323,13 @@ class GenFdsGlobalVariable:
# @param String String that may contain macro # @param String String that may contain macro
# #
def ReplaceWorkspaceMacro(String): def ReplaceWorkspaceMacro(String):
String = mws.handleWsMacro(String)
Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
if os.path.exists(Str): if os.path.exists(Str):
if not os.path.isabs(Str): if not os.path.isabs(Str):
Str = os.path.abspath(Str) Str = os.path.abspath(Str)
else: else:
Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String) Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)
return os.path.normpath(Str) return os.path.normpath(Str)
## Check if the input files are newer than output files ## Check if the input files are newer than output files

View File

@ -24,6 +24,7 @@ from stat import *
from Common import EdkLogger from Common import EdkLogger
from Common.BuildToolError import * from Common.BuildToolError import *
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
## generate Region ## generate Region
# #
@ -205,7 +206,7 @@ class Region(RegionClassObject):
for RegionData in self.RegionDataList: for RegionData in self.RegionDataList:
RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
if RegionData[1] != ':' : if RegionData[1] != ':' :
RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
if not os.path.exists(RegionData): if not os.path.exists(RegionData):
EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
# #

View File

@ -21,6 +21,7 @@ import uuid
import Common.EdkLogger as EdkLogger import Common.EdkLogger as EdkLogger
import Common.GlobalData as GlobalData import Common.GlobalData as GlobalData
from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common.String import * from Common.String import *
from Common.DataType import * from Common.DataType import *
@ -166,7 +167,7 @@ class DscBuildData(PlatformBuildClassObject):
ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch) ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId] RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
if RecordList != []: if RecordList != []:
SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0])) SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
# Check if the source override path exists # Check if the source override path exists
if not os.path.isdir(SourceOverridePath): if not os.path.isdir(SourceOverridePath):
@ -2179,8 +2180,11 @@ class InfBuildData(ModuleBuildClassObject):
if self.AutoGenVersion < 0x00010005: if self.AutoGenVersion < 0x00010005:
Macros["EDK_SOURCE"] = GlobalData.gEcpSource Macros["EDK_SOURCE"] = GlobalData.gEcpSource
Macros['PROCESSOR'] = self._Arch Macros['PROCESSOR'] = self._Arch
SourceFile = NormPath(Record[0], Macros)
if SourceFile[0] == os.path.sep:
SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])
# old module source files (Edk) # old module source files (Edk)
File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath, File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,
'', False, self._Arch, ToolChainFamily, '', TagName, ToolCode) '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
# check the file validation # check the file validation
ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False) ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)
@ -2339,6 +2343,17 @@ class InfBuildData(ModuleBuildClassObject):
if File: if File:
self._Includes.append(File) self._Includes.append(File)
else: else:
File = NormPath(Record[0], Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
File = mws.join(GlobalData.gWorkspace, File)
File = RealPath(os.path.normpath(File))
if File:
self._Includes.append(File)
if not File and Record[0].find('EFI_SOURCE') > -1:
# tricky to regard WorkSpace as EFI_SOURCE
Macros['EFI_SOURCE'] = GlobalData.gWorkspace
File = NormPath(Record[0], Macros) File = NormPath(Record[0], Macros)
if File[0] == '.': if File[0] == '.':
File = os.path.join(self._ModuleDir, File) File = os.path.join(self._ModuleDir, File)
@ -2797,7 +2812,7 @@ class WorkspaceDatabase(object):
def __init__(self, DbPath, RenewDb=False): def __init__(self, DbPath, RenewDb=False):
self._DbClosedFlag = False self._DbClosedFlag = False
if not DbPath: if not DbPath:
DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath)) DbPath = os.path.normpath(mws.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))
# don't create necessary path for db in memory # don't create necessary path for db in memory
if DbPath != ':memory:': if DbPath != ':memory:':

View File

@ -41,6 +41,7 @@ from Common.DataType import TAB_BRG_PCD
from Common.DataType import TAB_BRG_LIBRARY from Common.DataType import TAB_BRG_LIBRARY
from Common.DataType import TAB_BACK_SLASH from Common.DataType import TAB_BACK_SLASH
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
## Pattern to extract contents in EDK DXS files ## Pattern to extract contents in EDK DXS files
gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL) gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)
@ -1255,7 +1256,7 @@ class FdRegionReport(object):
for Pa in Wa.AutoGenObjectList: for Pa in Wa.AutoGenObjectList:
for ModuleKey in Pa.Platform.Modules: for ModuleKey in Pa.Platform.Modules:
M = Pa.Platform.Modules[ModuleKey].M M = Pa.Platform.Modules[ModuleKey].M
InfPath = os.path.join(Wa.WorkspaceDir, M.MetaFile.File) InfPath = mws.join(Wa.WorkspaceDir, M.MetaFile.File)
self._GuidsDb[M.Guid.upper()] = "%s (%s)" % (M.Module.BaseName, InfPath) self._GuidsDb[M.Guid.upper()] = "%s (%s)" % (M.Module.BaseName, InfPath)
# #
@ -1277,7 +1278,7 @@ class FdRegionReport(object):
Guid = GuidStructureByteArrayToGuidString(GuidValue).upper() Guid = GuidStructureByteArrayToGuidString(GuidValue).upper()
for Section in Ffs.SectionList: for Section in Ffs.SectionList:
try: try:
ModuleSectFile = os.path.join(Wa.WorkspaceDir, Section.SectFileName) ModuleSectFile = mws.join(Wa.WorkspaceDir, Section.SectFileName)
self._GuidsDb[Guid] = ModuleSectFile self._GuidsDb[Guid] = ModuleSectFile
except AttributeError: except AttributeError:
pass pass

View File

@ -41,6 +41,7 @@ from Common.BuildVersion import gBUILD_VERSION
from AutoGen.AutoGen import * from AutoGen.AutoGen import *
from Common.BuildToolError import * from Common.BuildToolError import *
from Workspace.WorkspaceDatabase import * from Workspace.WorkspaceDatabase import *
from Common.MultipleWorkspace import MultipleWorkspace as mws
from BuildReport import BuildReport from BuildReport import BuildReport
from GenPatchPcdTable.GenPatchPcdTable import * from GenPatchPcdTable.GenPatchPcdTable import *
@ -105,11 +106,15 @@ def CheckEnvVariable():
ExtraData=WorkspaceDir) ExtraData=WorkspaceDir)
os.environ["WORKSPACE"] = WorkspaceDir os.environ["WORKSPACE"] = WorkspaceDir
# set multiple workspace
PackagesPath = os.getenv("PACKAGES_PATH")
mws.setWs(WorkspaceDir, PackagesPath)
# #
# Check EFI_SOURCE (Edk build convention). EDK_SOURCE will always point to ECP # Check EFI_SOURCE (Edk build convention). EDK_SOURCE will always point to ECP
# #
if "ECP_SOURCE" not in os.environ: if "ECP_SOURCE" not in os.environ:
os.environ["ECP_SOURCE"] = os.path.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg) os.environ["ECP_SOURCE"] = mws.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg)
if "EFI_SOURCE" not in os.environ: if "EFI_SOURCE" not in os.environ:
os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"] os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"]
if "EDK_SOURCE" not in os.environ: if "EDK_SOURCE" not in os.environ:
@ -198,7 +203,8 @@ def NormFile(FilePath, Workspace):
if os.path.isabs(FilePath): if os.path.isabs(FilePath):
FileFullPath = os.path.normpath(FilePath) FileFullPath = os.path.normpath(FilePath)
else: else:
FileFullPath = os.path.normpath(os.path.join(Workspace, FilePath)) FileFullPath = os.path.normpath(mws.join(Workspace, FilePath))
Workspace = mws.getWs(Workspace, FilePath)
# check if the file path exists or not # check if the file path exists or not
if not os.path.isfile(FileFullPath): if not os.path.isfile(FileFullPath):
@ -748,10 +754,10 @@ class Build():
if not os.path.isabs(ConfDirectoryPath): if not os.path.isabs(ConfDirectoryPath):
# Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
# This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
ConfDirectoryPath = os.path.join(self.WorkspaceDir, ConfDirectoryPath) ConfDirectoryPath = mws.join(self.WorkspaceDir, ConfDirectoryPath)
else: else:
# Get standard WORKSPACE/Conf use the absolute path to the WORKSPACE/Conf # Get standard WORKSPACE/Conf use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = os.path.join(self.WorkspaceDir, 'Conf') ConfDirectoryPath = mws.join(self.WorkspaceDir, 'Conf')
GlobalData.gConfDirectory = ConfDirectoryPath GlobalData.gConfDirectory = ConfDirectoryPath
GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath)) GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))
@ -796,7 +802,7 @@ class Build():
ToolDefinitionFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] ToolDefinitionFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
if ToolDefinitionFile == '': if ToolDefinitionFile == '':
ToolDefinitionFile = gToolsDefinition ToolDefinitionFile = gToolsDefinition
ToolDefinitionFile = os.path.normpath(os.path.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile)) ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
if os.path.isfile(ToolDefinitionFile) == True: if os.path.isfile(ToolDefinitionFile) == True:
StatusCode = self.ToolDef.LoadToolDefFile(ToolDefinitionFile) StatusCode = self.ToolDef.LoadToolDefFile(ToolDefinitionFile)
else: else: