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 (s *ContainerFindIncludes) Run(context map[string]interface{}) error { err := runCommand(context, &IncludesToIncludeFolders{}) if err != nil { return utils.WrapError(err) } sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string) sketch := context[constants.CTX_SKETCH].(*types.Sketch) err = findIncludesUntilDone(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")) if err != nil { return utils.WrapError(err) } foldersWithSources := context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueSourceFolderQueue) foldersWithSources.Push(types.SourceFolder{Folder: context[constants.CTX_SKETCH_BUILD_PATH].(string), Recurse: true}) if utils.MapHas(context, constants.CTX_IMPORTED_LIBRARIES) { for _, library := range context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) { sourceFolders := types.LibraryToSourceFolder(library) for _, sourceFolder := range sourceFolders { foldersWithSources.Push(sourceFolder) } } } err = runCommand(context, &CollectAllSourceFilesFromFoldersWithSources{}) if err != nil { return utils.WrapError(err) } sourceFilePaths := context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue) for !sourceFilePaths.Empty() { err = findIncludesUntilDone(context, sourceFilePaths.Pop().(string)) if err != nil { return utils.WrapError(err) } err := runCommand(context, &CollectAllSourceFilesFromFoldersWithSources{}) if err != nil { return utils.WrapError(err) } } err = runCommand(context, &FailIfImportedLibraryIsWrong{}) if err != nil { return utils.WrapError(err) } return nil }
func (s *ContainerFindIncludes) Run(ctx *types.Context) error { err := runCommand(ctx, &IncludesToIncludeFolders{}) if err != nil { return i18n.WrapError(err) } sketchBuildPath := ctx.SketchBuildPath sketch := ctx.Sketch err = findIncludesUntilDone(ctx, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")) if err != nil { return i18n.WrapError(err) } foldersWithSources := ctx.FoldersWithSourceFiles foldersWithSources.Push(types.SourceFolder{Folder: ctx.SketchBuildPath, Recurse: true}) if len(ctx.ImportedLibraries) > 0 { for _, library := range ctx.ImportedLibraries { sourceFolders := types.LibraryToSourceFolder(library) for _, sourceFolder := range sourceFolders { foldersWithSources.Push(sourceFolder) } } } err = runCommand(ctx, &CollectAllSourceFilesFromFoldersWithSources{}) if err != nil { return i18n.WrapError(err) } sourceFilePaths := ctx.CollectedSourceFiles for !sourceFilePaths.Empty() { err = findIncludesUntilDone(ctx, sourceFilePaths.Pop().(string)) if err != nil { return i18n.WrapError(err) } err := runCommand(ctx, &CollectAllSourceFilesFromFoldersWithSources{}) if err != nil { return i18n.WrapError(err) } } err = runCommand(ctx, &FailIfImportedLibraryIsWrong{}) if err != nil { return i18n.WrapError(err) } return nil }
func (s *IncludesToIncludeFolders) Run(context map[string]interface{}) error { includes := []string{} if utils.MapHas(context, constants.CTX_INCLUDES) { includes = context[constants.CTX_INCLUDES].([]string) } headerToLibraries := make(map[string][]*types.Library) if utils.MapHas(context, constants.CTX_HEADER_TO_LIBRARIES) { headerToLibraries = context[constants.CTX_HEADER_TO_LIBRARIES].(map[string][]*types.Library) } platform := context[constants.CTX_TARGET_PLATFORM].(*types.Platform) actualPlatform := context[constants.CTX_ACTUAL_PLATFORM].(*types.Platform) libraryResolutionResults := context[constants.CTX_LIBRARY_RESOLUTION_RESULTS].(map[string]types.LibraryResolutionResult) importedLibraries := []*types.Library{} if utils.MapHas(context, constants.CTX_IMPORTED_LIBRARIES) { importedLibraries = context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library) } newlyImportedLibraries, err := resolveLibraries(includes, headerToLibraries, importedLibraries, []*types.Platform{actualPlatform, platform}, libraryResolutionResults) if err != nil { return utils.WrapError(err) } foldersWithSources := context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueSourceFolderQueue) for _, newlyImportedLibrary := range newlyImportedLibraries { if !sliceContainsLibrary(importedLibraries, newlyImportedLibrary) { importedLibraries = append(importedLibraries, newlyImportedLibrary) sourceFolders := types.LibraryToSourceFolder(newlyImportedLibrary) for _, sourceFolder := range sourceFolders { foldersWithSources.Push(sourceFolder) } } } context[constants.CTX_IMPORTED_LIBRARIES] = importedLibraries buildProperties := context[constants.CTX_BUILD_PROPERTIES].(props.PropertiesMap) verbose := context[constants.CTX_VERBOSE].(bool) includeFolders := resolveIncludeFolders(newlyImportedLibraries, buildProperties, verbose) context[constants.CTX_INCLUDE_FOLDERS] = includeFolders 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 } }