From 383666f74f7a6bcd099ac494dc0e2ac2621ad712 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 21 Nov 2018 11:56:29 +0100 Subject: [PATCH] Handle reference files when expanding commandline This commit allows to specify referenced file in your board.properties with the notation $filename. gcc accepts files containing arguments as @filename, but it normally applies only to defines or similar flags. With the new notation, these files can contain include paths, which must be specified absolutely and change between every installation. At runtime, the file content is being read and written ion a writable location with the actual resolved paths. --- builder_utils/utils.go | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/builder_utils/utils.go b/builder_utils/utils.go index 9b4cb536..6ae7c8e5 100644 --- a/builder_utils/utils.go +++ b/builder_utils/utils.go @@ -31,9 +31,11 @@ package builder_utils import ( "io" + "io/ioutil" "os" "os/exec" "path/filepath" + "regexp" "sort" "strconv" "strings" @@ -476,6 +478,42 @@ func ExecRecipe(ctx *types.Context, buildProperties properties.Map, recipe strin return utils.ExecCommand(ctx, command, stdout, stderr) } +func replaceFilesWithUnexpandedProps(str string, buildProperties properties.Map) string { + + // Regexp to match file path + re := regexp.MustCompile("\\$(.+?)(/|\\\\)(.+?) ") + fileString := re.FindString(str) + if fileString == "" { + return str + } + path := strings.TrimSpace(strings.Trim(fileString, "$")) + filename := filepath.Base(path) + + content, err := ioutil.ReadFile(path) + if err != nil { + return str + } + + path = filepath.Join(buildProperties[constants.BUILD_PROPERTIES_BUILD_PATH], constants.FOLDER_PREPROC, filename) + // if new path does not exist, read original file and create the resolved one + if _, err := os.Stat(path); os.IsNotExist(err) { + // expand properties in data file + data := buildProperties.ExpandPropsInString(string(content)) + // does the folder already exist? if not, create it + os.MkdirAll(filepath.Dir(path), 0777) + // write file to buildProperties[constants.BUILD_PROPERTIES_BUILD_PATH]/preproc/filename + ioutil.WriteFile(path, []byte(data), 0666) + } + + // replace filename with new one (add a space because we needed it to validate the regexp and then it got stripped) + str = strings.Replace(str, fileString, "@"+path+" ", 1) + + // repeat recursively until all occurrences are resolved + str = replaceFilesWithUnexpandedProps(str, buildProperties) + + return str +} + const COMMANDLINE_LIMIT = 30000 func PrepareCommandForRecipe(ctx *types.Context, buildProperties properties.Map, recipe string, removeUnsetProperties bool) (*exec.Cmd, error) { @@ -487,6 +525,13 @@ func PrepareCommandForRecipe(ctx *types.Context, buildProperties properties.Map, var err error commandLine := buildProperties.ExpandPropsInString(pattern) + + // handle reference files; gcc accepts files replacing commandline arguments if specified as @filename + // such files can't contain paths, since they must be absolute + // so, if pattern contains $filename, replace it with @new_filename, where the file content has been expanded + // and the path of new_filename is inside the build folder + commandLine = replaceFilesWithUnexpandedProps(commandLine, buildProperties) + if removeUnsetProperties { commandLine = properties.DeleteUnexpandedPropsFromString(commandLine) }