From 6f953ff33e5c203f63cd1f914414438cf006e8c6 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 25 Sep 2017 15:15:09 +0200 Subject: [PATCH] Use relative paths if commandline is too long --- src/arduino.cc/builder/builder_utils/utils.go | 10 +++++++- src/arduino.cc/builder/ctags_runner.go | 2 +- src/arduino.cc/builder/utils/utils.go | 25 ++++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/arduino.cc/builder/builder_utils/utils.go b/src/arduino.cc/builder/builder_utils/utils.go index 97b6e355..fab0e209 100644 --- a/src/arduino.cc/builder/builder_utils/utils.go +++ b/src/arduino.cc/builder/builder_utils/utils.go @@ -375,6 +375,8 @@ func ExecRecipe(properties properties.Map, recipe string, removeUnsetProperties return bytes, i18n.WrapError(err) } +const COMMANDLINE_LIMIT = 32000 + func PrepareCommandForRecipe(buildProperties properties.Map, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (*exec.Cmd, error) { pattern := buildProperties[recipe] if pattern == constants.EMPTY_STRING { @@ -390,7 +392,13 @@ func PrepareCommandForRecipe(buildProperties properties.Map, recipe string, remo } } - command, err := utils.PrepareCommand(commandLine, logger) + relativePath := "" + + if len(commandLine) > COMMANDLINE_LIMIT { + relativePath = buildProperties[constants.BUILD_PROPERTIES_BUILD_PATH] + } + + command, err := utils.PrepareCommand(commandLine, logger, relativePath) if err != nil { return nil, i18n.WrapError(err) } diff --git a/src/arduino.cc/builder/ctags_runner.go b/src/arduino.cc/builder/ctags_runner.go index 2ab75638..89b1d3e8 100644 --- a/src/arduino.cc/builder/ctags_runner.go +++ b/src/arduino.cc/builder/ctags_runner.go @@ -56,7 +56,7 @@ func (s *CTagsRunner) Run(ctx *types.Context) error { } commandLine := properties.ExpandPropsInString(pattern) - command, err := utils.PrepareCommand(commandLine, logger) + command, err := utils.PrepareCommand(commandLine, logger, "") if err != nil { return i18n.WrapError(err) } diff --git a/src/arduino.cc/builder/utils/utils.go b/src/arduino.cc/builder/utils/utils.go index 0aa2e811..d9bea4ec 100644 --- a/src/arduino.cc/builder/utils/utils.go +++ b/src/arduino.cc/builder/utils/utils.go @@ -229,7 +229,7 @@ func TrimSpace(value string) string { type argFilterFunc func(int, string, []string) bool -func PrepareCommandFilteredArgs(pattern string, filter argFilterFunc, logger i18n.Logger) (*exec.Cmd, error) { +func PrepareCommandFilteredArgs(pattern string, filter argFilterFunc, logger i18n.Logger, relativePath string) (*exec.Cmd, error) { parts, err := ParseCommandLine(pattern, logger) if err != nil { return nil, i18n.WrapError(err) @@ -239,19 +239,36 @@ func PrepareCommandFilteredArgs(pattern string, filter argFilterFunc, logger i18 var args []string for idx, part := range parts { if filter(idx, part, parts) { + // if relativePath is specified, the overall commandline is too long for the platform + // try reducing the length by making the filenames relative + // and changing working directory to build.path + if relativePath != "" { + if _, err := os.Stat(part); !os.IsNotExist(err) { + tmp, err := filepath.Rel(relativePath, part) + if err == nil { + part = tmp + } + } + } args = append(args, part) } } - return exec.Command(command, args...), nil + cmd := exec.Command(command, args...) + + if relativePath != "" { + cmd.Dir = relativePath + } + + return cmd, nil } func filterEmptyArg(_ int, arg string, _ []string) bool { return arg != constants.EMPTY_STRING } -func PrepareCommand(pattern string, logger i18n.Logger) (*exec.Cmd, error) { - return PrepareCommandFilteredArgs(pattern, filterEmptyArg, logger) +func PrepareCommand(pattern string, logger i18n.Logger, relativePath string) (*exec.Cmd, error) { + return PrepareCommandFilteredArgs(pattern, filterEmptyArg, logger, relativePath) } func MapHas(aMap map[string]interface{}, key string) bool {