- ## Find dependencies for one source file\r
- #\r
- # By searching recursively "#include" directive in file, find out all the\r
- # files needed by given source file. The dependecies will be only searched\r
- # in given search path list.\r
- #\r
- # @param File The source file\r
- # @param ForceInculeList The list of files which will be included forcely\r
- # @param SearchPathList The list of search path\r
- #\r
- # @retval list The list of files the given source file depends on\r
- #\r
- def GetDependencyList(self, File, ForceList, SearchPathList):\r
- EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)\r
- FileStack = [File] + ForceList\r
- DependencySet = set()\r
-\r
- if self._AutoGenObject.Arch not in gDependencyDatabase:\r
- gDependencyDatabase[self._AutoGenObject.Arch] = {}\r
- DepDb = gDependencyDatabase[self._AutoGenObject.Arch]\r
-\r
- while len(FileStack) > 0:\r
- F = FileStack.pop()\r
-\r
- FullPathDependList = []\r
- if F in self.FileCache:\r
- for CacheFile in self.FileCache[F]:\r
- FullPathDependList.append(CacheFile)\r
- if CacheFile not in DependencySet:\r
- FileStack.append(CacheFile)\r
- DependencySet.update(FullPathDependList)\r
- continue\r
-\r
- CurrentFileDependencyList = []\r
- if F in DepDb:\r
- CurrentFileDependencyList = DepDb[F]\r
- else:\r
- try:\r
- Fd = open(F.Path, 'r')\r
- except BaseException, X:\r
- EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path + "\n\t" + str(X))\r
-\r
- FileContent = Fd.read()\r
- Fd.close()\r
- if len(FileContent) == 0:\r
- continue\r
-\r
- if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
- FileContent = unicode(FileContent, "utf-16")\r
- IncludedFileList = gIncludePattern.findall(FileContent)\r
-\r
- for Inc in IncludedFileList:\r
- Inc = Inc.strip()\r
- # if there's macro used to reference header file, expand it\r
- HeaderList = gMacroPattern.findall(Inc)\r
- if len(HeaderList) == 1 and len(HeaderList[0]) == 2:\r
- HeaderType = HeaderList[0][0]\r
- HeaderKey = HeaderList[0][1]\r
- if HeaderType in gIncludeMacroConversion:\r
- Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}\r
- else:\r
- # not known macro used in #include, always build the file by\r
- # returning a empty dependency\r
- self.FileCache[File] = []\r
- return []\r
- Inc = os.path.normpath(Inc)\r
- CurrentFileDependencyList.append(Inc)\r
- DepDb[F] = CurrentFileDependencyList\r
-\r
- CurrentFilePath = F.Dir\r
- PathList = [CurrentFilePath] + SearchPathList\r
- for Inc in CurrentFileDependencyList:\r
- for SearchPath in PathList:\r
- FilePath = os.path.join(SearchPath, Inc)\r
- if FilePath in gIsFileMap:\r
- if not gIsFileMap[FilePath]:\r
- continue\r
- # If isfile is called too many times, the performance is slow down.\r
- elif not os.path.isfile(FilePath):\r
- gIsFileMap[FilePath] = False\r
- continue\r
- else:\r
- gIsFileMap[FilePath] = True\r
- FilePath = PathClass(FilePath)\r
- FullPathDependList.append(FilePath)\r
- if FilePath not in DependencySet:\r
- FileStack.append(FilePath)\r
- break\r
- else:\r
- EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\\r
- "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))\r
-\r
- self.FileCache[F] = FullPathDependList\r
- DependencySet.update(FullPathDependList)\r
-\r
- DependencySet.update(ForceList)\r
- if File in DependencySet:\r
- DependencySet.remove(File)\r
- DependencyList = list(DependencySet) # remove duplicate ones\r
-\r
- return DependencyList\r
-\r
- _TemplateDict = property(_CreateTemplateDict)\r