func (s *IncludesFinderWithGCC) Run(context map[string]interface{}) error {
	buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES)
	sketch := context[constants.CTX_SKETCH].(*types.Sketch)
	sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string)
	verbose := context[constants.CTX_VERBOSE].(bool)
	logger := context[constants.CTX_LOGGER].(i18n.Logger)

	includesParams := ""
	if utils.MapHas(context, constants.CTX_INCLUDE_FOLDERS) {
		includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
		includes = utils.Map(includes, utils.WrapWithHyphenI)
		includesParams = strings.Join(includes, " ")
	}

	properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties)
	properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")
	properties[constants.BUILD_PROPERTIES_INCLUDES] = includesParams
	builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)

	output, err := builder_utils.ExecRecipe(properties, constants.RECIPE_PREPROC_INCLUDES, true, verbose, false, logger)
	if err != nil {
		return utils.WrapError(err)
	}

	context[constants.CTX_GCC_MINUS_M_OUTPUT] = string(output)

	return nil
}
func (s *IncludesFinderWithGCC) Run(context map[string]interface{}) error {
	buildProperties := make(props.PropertiesMap)
	if p, ok := context[constants.CTX_BUILD_PROPERTIES]; ok {
		buildProperties = p.(props.PropertiesMap).Clone()
	}
	verbose := context[constants.CTX_VERBOSE].(bool)
	logger := context[constants.CTX_LOGGER].(i18n.Logger)

	includesParams := constants.EMPTY_STRING
	if utils.MapHas(context, constants.CTX_INCLUDE_FOLDERS) {
		includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
		includes = utils.Map(includes, utils.WrapWithHyphenI)
		includesParams = strings.Join(includes, " ")
	}

	properties := buildProperties.Clone()
	properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = s.SourceFile
	properties[constants.BUILD_PROPERTIES_INCLUDES] = includesParams
	builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)

	output, err := builder_utils.ExecRecipe(properties, constants.RECIPE_PREPROC_INCLUDES, true, verbose, false, logger)
	if err != nil {
		return utils.WrapError(err)
	}

	context[constants.CTX_GCC_MINUS_M_OUTPUT] = string(output)

	return nil
}
func compileCore(buildPath string, buildProperties map[string]string, verbose bool, warningsLevel string, logger i18n.Logger) (string, error) {
	coreFolder := buildProperties[constants.BUILD_PROPERTIES_BUILD_CORE_PATH]
	variantFolder := buildProperties[constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH]

	var includes []string
	includes = append(includes, coreFolder)
	if variantFolder != constants.EMPTY_STRING {
		includes = append(includes, variantFolder)
	}
	includes = utils.Map(includes, utils.WrapWithHyphenI)

	var err error

	var variantObjectFiles []string
	if variantFolder != constants.EMPTY_STRING {
		variantObjectFiles, err = builder_utils.CompileFiles(variantObjectFiles, variantFolder, true, buildPath, buildProperties, includes, verbose, warningsLevel, logger)
		if err != nil {
			return "", utils.WrapError(err)
		}
	}

	coreObjectFiles, err := builder_utils.CompileFiles([]string{}, coreFolder, true, buildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return "", utils.WrapError(err)
	}

	objectFiles := append(coreObjectFiles, variantObjectFiles...)

	archiveFile, err := builder_utils.ArchiveCompiledFiles(buildPath, "core.a", objectFiles, buildProperties, verbose, logger)
	if err != nil {
		return "", utils.WrapError(err)
	}

	return archiveFile, nil
}
func (s *SketchBuilder) Run(ctx *types.Context) error {
	sketchBuildPath := ctx.SketchBuildPath
	buildProperties := ctx.BuildProperties
	includes := ctx.IncludeFolders
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	verbose := ctx.Verbose
	warningsLevel := ctx.WarningsLevel
	logger := ctx.GetLogger()

	err := utils.EnsureFolderExists(sketchBuildPath)
	if err != nil {
		return i18n.WrapError(err)
	}

	var objectFiles []string
	objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return i18n.WrapError(err)
	}

	// The "src/" subdirectory of a sketch is compiled recursively
	sketchSrcPath := filepath.Join(sketchBuildPath, constants.SKETCH_FOLDER_SRC)
	if info, err := os.Stat(sketchSrcPath); err == nil && info.IsDir() {
		objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchSrcPath, true, sketchSrcPath, buildProperties, includes, verbose, warningsLevel, logger)
		if err != nil {
			return i18n.WrapError(err)
		}
	}

	ctx.SketchObjectFiles = objectFiles

	return nil
}
func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFilePath string, targetFilePath string) (props.PropertiesMap, string, error) {
	if targetFilePath != utils.NULLFile() {
		preprocPath := context[constants.CTX_PREPROC_PATH].(string)
		err := utils.EnsureFolderExists(preprocPath)
		if err != nil {
			return nil, "", utils.WrapError(err)
		}
		targetFilePath = filepath.Join(preprocPath, targetFilePath)
	}

	properties := make(props.PropertiesMap)
	if p, ok := context[constants.CTX_BUILD_PROPERTIES]; ok {
		properties = p.(props.PropertiesMap).Clone()
	}

	properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFilePath
	properties[constants.BUILD_PROPERTIES_PREPROCESSED_FILE_PATH] = targetFilePath

	includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE)
	builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)

	return properties, targetFilePath, nil
}
Example #6
0
func TestMapTrimSpace(t *testing.T) {
	value := "hello, world , how are,you? "
	parts := utils.Map(strings.Split(value, ","), utils.TrimSpace)

	require.Equal(t, 4, len(parts))
	require.Equal(t, "hello", parts[0])
	require.Equal(t, "world", parts[1])
	require.Equal(t, "how are", parts[2])
	require.Equal(t, "you?", parts[3])
}
func addAdditionalPropertiesToTargetBoard(board *types.Board, options string) {
	optionsParts := strings.Split(options, ",")
	optionsParts = utils.Map(optionsParts, utils.TrimSpace)

	for _, optionPart := range optionsParts {
		parts := strings.Split(optionPart, "=")
		parts = utils.Map(parts, utils.TrimSpace)

		key := parts[0]
		value := parts[1]
		if key != constants.EMPTY_STRING && value != constants.EMPTY_STRING {
			menu := board.Properties.SubTree(constants.BOARD_PROPERTIES_MENU)
			if len(menu) == 0 {
				return
			}
			propertiesOfKey := menu.SubTree(key)
			if len(propertiesOfKey) == 0 {
				return
			}
			propertiesOfKeyValue := propertiesOfKey.SubTree(value)
			board.Properties.Merge(propertiesOfKeyValue)
		}
	}
}
Example #8
0
func compileCore(buildPath string, buildProperties map[string]string, verbose bool, warningsLevel string, logger i18n.Logger) ([]string, error) {
	var objectFiles []string
	coreFolder := buildProperties[constants.BUILD_PROPERTIES_BUILD_CORE_PATH]
	variantFolder := buildProperties[constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH]

	var includes []string
	includes = append(includes, coreFolder)
	if variantFolder != constants.EMPTY_STRING {
		includes = append(includes, variantFolder)
	}
	includes = utils.Map(includes, utils.WrapWithHyphenI)

	var err error

	if variantFolder != constants.EMPTY_STRING {
		objectFiles, err = builder_utils.CompileFiles(objectFiles, variantFolder, true, buildPath, buildProperties, includes, verbose, warningsLevel, logger)
		if err != nil {
			return nil, utils.WrapError(err)
		}
	}

	coreObjectFiles, err := builder_utils.CompileFiles([]string{}, coreFolder, true, buildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return nil, utils.WrapError(err)
	}

	coreArchiveFilePath := filepath.Join(buildPath, "core.a")
	if _, err := os.Stat(coreArchiveFilePath); err == nil {
		err = os.Remove(coreArchiveFilePath)
		if err != nil {
			return nil, utils.WrapError(err)
		}
	}

	for _, coreObjectFile := range coreObjectFiles {
		properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties)
		properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE)
		properties[constants.BUILD_PROPERTIES_ARCHIVE_FILE] = filepath.Base(coreArchiveFilePath)
		properties[constants.BUILD_PROPERTIES_OBJECT_FILE] = coreObjectFile

		_, err := builder_utils.ExecRecipe(properties, "recipe.ar.pattern", false, verbose, verbose, logger)
		if err != nil {
			return nil, utils.WrapError(err)
		}
	}

	return objectFiles, nil
}
Example #9
0
func link(objectFiles []string, coreDotARelPath string, coreArchiveFilePath string, buildProperties properties.Map, verbose bool, warningsLevel string, logger i18n.Logger) error {
	optRelax := addRelaxTrickIfATMEGA2560(buildProperties)

	objectFiles = utils.Map(objectFiles, wrapWithDoubleQuotes)
	objectFileList := strings.Join(objectFiles, constants.SPACE)

	properties := buildProperties.Clone()
	properties[constants.BUILD_PROPERTIES_COMPILER_C_ELF_FLAGS] = properties[constants.BUILD_PROPERTIES_COMPILER_C_ELF_FLAGS] + optRelax
	properties[constants.BUILD_PROPERTIES_COMPILER_WARNING_FLAGS] = properties[constants.BUILD_PROPERTIES_COMPILER_WARNING_FLAGS+"."+warningsLevel]
	properties[constants.BUILD_PROPERTIES_ARCHIVE_FILE] = coreDotARelPath
	properties[constants.BUILD_PROPERTIES_ARCHIVE_FILE_PATH] = coreArchiveFilePath
	properties[constants.BUILD_PROPERTIES_OBJECT_FILES] = objectFileList

	_, err := builder_utils.ExecRecipe(properties, constants.RECIPE_C_COMBINE_PATTERN, false, verbose, verbose, logger)
	return err
}
Example #10
0
func link(objectFiles []string, buildProperties map[string]string, verbose bool, warningsLevel string, logger i18n.Logger) error {
	optRelax := constants.EMPTY_STRING
	if buildProperties[constants.BUILD_PROPERTIES_BUILD_MCU] == "atmega2560" {
		optRelax = ",--relax"
	}

	objectFiles = utils.Map(objectFiles, wrapWithDoubleQuotes)
	objectFileList := strings.Join(objectFiles, constants.SPACE)

	properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties)
	properties["compiler.c.elf.flags"] = properties["compiler.c.elf.flags"] + optRelax
	properties["compiler.warning_flags"] = properties["compiler.warning_flags."+warningsLevel]
	properties[constants.BUILD_PROPERTIES_ARCHIVE_FILE] = "core.a"
	properties[constants.BUILD_PROPERTIES_OBJECT_FILES] = objectFileList

	_, err := builder_utils.ExecRecipe(properties, "recipe.c.combine.pattern", false, verbose, verbose, logger)
	return err
}
func prepareGCCPreprocRecipeProperties(ctx *types.Context, sourceFilePath string, targetFilePath string, includes []string) (properties.Map, string, error) {
	if targetFilePath != utils.NULLFile() {
		preprocPath := ctx.PreprocPath
		err := utils.EnsureFolderExists(preprocPath)
		if err != nil {
			return nil, "", i18n.WrapError(err)
		}
		targetFilePath = filepath.Join(preprocPath, targetFilePath)
	}

	properties := ctx.BuildProperties.Clone()
	properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFilePath
	properties[constants.BUILD_PROPERTIES_PREPROCESSED_FILE_PATH] = targetFilePath

	includes = utils.Map(includes, utils.WrapWithHyphenI)
	properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE)
	builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)

	return properties, targetFilePath, nil
}
func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFilePath string, targetFileName string) (map[string]string, string, error) {
	preprocPath := context[constants.CTX_PREPROC_PATH].(string)
	err := utils.EnsureFolderExists(preprocPath)
	if err != nil {
		return nil, "", utils.WrapError(err)
	}
	targetFilePath := filepath.Join(preprocPath, targetFileName)

	buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES)
	properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties)

	properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFilePath
	properties[constants.BUILD_PROPERTIES_PREPROCESSED_FILE_PATH] = targetFilePath

	includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE)
	builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)

	return properties, targetFilePath, nil
}
func (s *LibrariesBuilder) Run(ctx *types.Context) error {
	librariesBuildPath := ctx.LibrariesBuildPath
	buildProperties := ctx.BuildProperties
	includes := ctx.IncludeFolders
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	libraries := ctx.ImportedLibraries
	verbose := ctx.Verbose
	warningsLevel := ctx.WarningsLevel
	logger := ctx.GetLogger()

	err := utils.EnsureFolderExists(librariesBuildPath)
	if err != nil {
		return i18n.WrapError(err)
	}

	objectFiles, err := compileLibraries(libraries, librariesBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return i18n.WrapError(err)
	}

	ctx.LibrariesObjectFiles = objectFiles

	return nil
}
Example #14
0
func (s *SketchBuilder) Run(context map[string]interface{}) error {
	sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string)
	buildProperties := context[constants.CTX_BUILD_PROPERTIES].(map[string]string)
	includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	verbose := context[constants.CTX_VERBOSE].(bool)
	warningsLevel := context[constants.CTX_WARNINGS_LEVEL].(string)
	logger := context[constants.CTX_LOGGER].(i18n.Logger)

	err := os.MkdirAll(sketchBuildPath, os.FileMode(0755))
	if err != nil {
		return utils.WrapError(err)
	}

	var objectFiles []string
	objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return utils.WrapError(err)
	}

	context[constants.CTX_OBJECT_FILES_SKETCH] = objectFiles

	return nil
}
func (s *LibrariesBuilder) Run(context map[string]interface{}) error {
	librariesBuildPath := context[constants.CTX_LIBRARIES_BUILD_PATH].(string)
	buildProperties := context[constants.CTX_BUILD_PROPERTIES].(map[string]string)
	includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	libraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
	verbose := context[constants.CTX_VERBOSE].(bool)
	warningsLevel := context[constants.CTX_WARNINGS_LEVEL].(string)
	logger := context[constants.CTX_LOGGER].(i18n.Logger)

	err := utils.EnsureFolderExists(librariesBuildPath)
	if err != nil {
		return utils.WrapError(err)
	}

	objectFiles, err := compileLibraries(libraries, librariesBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return utils.WrapError(err)
	}

	context[constants.CTX_OBJECT_FILES_LIBRARIES] = objectFiles

	return nil
}
func (s *SketchBuilder) Run(ctx *types.Context) error {
	sketchBuildPath := ctx.SketchBuildPath
	buildProperties := ctx.BuildProperties
	includes := ctx.IncludeFolders
	includes = utils.Map(includes, utils.WrapWithHyphenI)
	verbose := ctx.Verbose
	warningsLevel := ctx.WarningsLevel
	logger := ctx.GetLogger()

	err := utils.EnsureFolderExists(sketchBuildPath)
	if err != nil {
		return i18n.WrapError(err)
	}

	var objectFiles []string
	objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, true, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
	if err != nil {
		return i18n.WrapError(err)
	}

	ctx.SketchObjectFiles = objectFiles

	return nil
}
Example #17
0
func ObjFileIsUpToDate(sourceFile, objectFile, dependencyFile string) (bool, error) {
	sourceFile = filepath.Clean(sourceFile)
	objectFile = filepath.Clean(objectFile)
	dependencyFile = filepath.Clean(dependencyFile)

	sourceFileStat, err := os.Stat(sourceFile)
	if err != nil {
		return false, i18n.WrapError(err)
	}

	objectFileStat, err := os.Stat(objectFile)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		} else {
			return false, i18n.WrapError(err)
		}
	}

	dependencyFileStat, err := os.Stat(dependencyFile)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		} else {
			return false, i18n.WrapError(err)
		}
	}

	if sourceFileStat.ModTime().After(objectFileStat.ModTime()) {
		return false, nil
	}
	if sourceFileStat.ModTime().After(dependencyFileStat.ModTime()) {
		return false, nil
	}

	rows, err := utils.ReadFileToRows(dependencyFile)
	if err != nil {
		return false, i18n.WrapError(err)
	}

	rows = utils.Map(rows, removeEndingBackSlash)
	rows = utils.Map(rows, strings.TrimSpace)
	rows = utils.Map(rows, unescapeDep)
	rows = utils.Filter(rows, nonEmptyString)

	if len(rows) == 0 {
		return true, nil
	}

	firstRow := rows[0]
	if !strings.HasSuffix(firstRow, ":") {
		return false, nil
	}
	objFileInDepFile := firstRow[:len(firstRow)-1]
	if objFileInDepFile != objectFile {
		return false, nil
	}

	rows = rows[1:]
	for _, row := range rows {
		depStat, err := os.Stat(row)
		if err != nil && !os.IsNotExist(err) {
			// There is probably a parsing error of the dep file
			// Ignore the error and trigger a full rebuild anyway
			return false, nil
		}
		if os.IsNotExist(err) {
			return false, nil
		}
		if depStat.ModTime().After(objectFileStat.ModTime()) {
			return false, nil
		}
	}

	return true, nil
}