func (s *IncludesToIncludeFolders) Run(ctx *types.Context) error { includes := ctx.Includes headerToLibraries := ctx.HeaderToLibraries platform := ctx.TargetPlatform actualPlatform := ctx.ActualPlatform libraryResolutionResults := ctx.LibrariesResolutionResults importedLibraries := ctx.ImportedLibraries newlyImportedLibraries, err := resolveLibraries(includes, headerToLibraries, importedLibraries, []*types.Platform{actualPlatform, platform}, libraryResolutionResults) if err != nil { return i18n.WrapError(err) } foldersWithSources := ctx.FoldersWithSourceFiles for _, newlyImportedLibrary := range newlyImportedLibraries { if !sliceContainsLibrary(importedLibraries, newlyImportedLibrary) { importedLibraries = append(importedLibraries, newlyImportedLibrary) sourceFolders := types.LibraryToSourceFolder(newlyImportedLibrary) for _, sourceFolder := range sourceFolders { foldersWithSources.Push(sourceFolder) } } } ctx.ImportedLibraries = importedLibraries ctx.IncludeFolders = resolveIncludeFolders(newlyImportedLibraries, ctx.BuildProperties, ctx.Verbose) return nil }
func findIncludesUntilDone(ctx *types.Context, cache *includeCache, sourceFile types.SourceFile) error { sourcePath := sourceFile.SourcePath(ctx) targetFilePath := utils.NULLFile() // TODO: This should perhaps also compare against the // include.cache file timestamp. Now, it only checks if the file // changed after the object file was generated, but if it // changed between generating the cache and the object file, // this could show the file as unchanged when it really is // changed. Changing files during a build isn't really // supported, but any problems from it should at least be // resolved when doing another build, which is not currently the // case. // TODO: This reads the dependency file, but the actual building // does it again. Should the result be somehow cached? Perhaps // remove the object file if it is found to be stale? unchanged, err := builder_utils.ObjFileIsUpToDate(sourcePath, sourceFile.ObjectPath(ctx), sourceFile.DepfilePath(ctx)) if err != nil { return i18n.WrapError(err) } first := true for { var include string cache.ExpectFile(sourcePath) includes := ctx.IncludeFolders if library, ok := sourceFile.Origin.(*types.Library); ok && library.UtilityFolder != "" { includes = append(includes, library.UtilityFolder) } if unchanged && cache.valid { include = cache.Next().Include if first && ctx.Verbose { ctx.GetLogger().Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_CACHED_INCLUDES, sourcePath) } } else { commands := []types.Command{ &GCCPreprocRunnerForDiscoveringIncludes{SourceFilePath: sourcePath, TargetFilePath: targetFilePath, Includes: includes}, &IncludesFinderWithRegExp{Source: &ctx.SourceGccMinusE}, } for _, command := range commands { err := runCommand(ctx, command) if err != nil { return i18n.WrapError(err) } } include = ctx.IncludeJustFound } if include == "" { // No missing includes found, we're done cache.ExpectEntry(sourcePath, "", "") return nil } library := ResolveLibrary(ctx, include) if library == nil { // Library could not be resolved, show error err := runCommand(ctx, &GCCPreprocRunner{SourceFilePath: sourcePath, TargetFileName: constants.FILE_CTAGS_TARGET_FOR_GCC_MINUS_E, Includes: includes}) return i18n.WrapError(err) } // Add this library to the list of libraries, the // include path and queue its source files for further // include scanning ctx.ImportedLibraries = append(ctx.ImportedLibraries, library) appendIncludeFolder(ctx, cache, sourcePath, include, library.SrcFolder) sourceFolders := types.LibraryToSourceFolder(library) for _, sourceFolder := range sourceFolders { queueSourceFilesFromFolder(ctx, ctx.CollectedSourceFiles, library, sourceFolder.Folder, sourceFolder.Recurse) } first = false } }