Skip to content

Commit 9f198b9

Browse files
committed
Use runner.Task in GCC preprocessor
It slightly simplifies code, but also provide the basis for the next commits.
1 parent 7e1bdcd commit 9f198b9

File tree

5 files changed

+74
-73
lines changed

5 files changed

+74
-73
lines changed

internal/arduino/builder/internal/detector/detector.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,19 @@ func (l *SketchLibrariesDetector) findIncludes(
284284
return nil
285285
}
286286

287+
func (l *SketchLibrariesDetector) gccPreprocessTask(sourceFile *sourceFile, buildProperties *properties.Map) *runner.Task {
288+
// Libraries may require the "utility" directory to be added to the include
289+
// search path, but only for the source code of the library, so we temporary
290+
// copy the current search path list and add the library' utility directory
291+
// if needed.
292+
includeFolders := l.includeFolders
293+
if extraInclude := sourceFile.ExtraIncludePath; extraInclude != nil {
294+
includeFolders = append(includeFolders, extraInclude)
295+
}
296+
297+
return preprocessor.GCC(sourceFile.SourcePath, paths.NullPath(), includeFolders, buildProperties)
298+
}
299+
287300
func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
288301
ctx context.Context,
289302
sourceFileQueue *uniqueSourceFileQueue,
@@ -315,15 +328,7 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
315328
for {
316329
l.cache.Expect(&detectorCacheEntry{Compile: sourceFile})
317330

318-
// Libraries may require the "utility" directory to be added to the include
319-
// search path, but only for the source code of the library, so we temporary
320-
// copy the current search path list and add the library' utility directory
321-
// if needed.
322-
includeFolders := l.includeFolders
323-
if extraInclude := sourceFile.ExtraIncludePath; extraInclude != nil {
324-
includeFolders = append(includeFolders, extraInclude)
325-
}
326-
331+
preprocTask := l.gccPreprocessTask(sourceFile, buildProperties)
327332
var preprocErr error
328333
var preprocResult *runner.Result
329334

@@ -335,7 +340,8 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
335340
}
336341
first = false
337342
} else {
338-
preprocResult, preprocErr = preprocessor.GCC(ctx, sourcePath, paths.NullPath(), includeFolders, buildProperties)
343+
preprocResult = preprocTask.Run(ctx)
344+
preprocErr = preprocResult.Error
339345
if l.logger.VerbosityLevel() == logger.VerbosityVerbose {
340346
l.logger.WriteStdout(preprocResult.Stdout)
341347
}
@@ -368,7 +374,8 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
368374

369375
// If preprocess result came from cache, run the preprocessor to obtain the actual error to show
370376
if preprocErr == nil || len(preprocResult.Stderr) == 0 {
371-
preprocResult, preprocErr = preprocessor.GCC(ctx, sourcePath, paths.NullPath(), includeFolders, buildProperties)
377+
preprocResult = preprocTask.Run(ctx)
378+
preprocErr = preprocResult.Error
372379
if l.logger.VerbosityLevel() == logger.VerbosityVerbose {
373380
l.logger.WriteStdout(preprocResult.Stdout)
374381
}

internal/arduino/builder/internal/preprocessor/arduino_preprocessor.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ func PreprocessSketchWithArduinoPreprocessor(
4545

4646
sourceFile := buildPath.Join("sketch", sk.MainFile.Base()+".cpp")
4747
targetFile := buildPath.Join("preproc", "sketch_merged.cpp")
48-
gccResult, err := GCC(ctx, sourceFile, targetFile, includeFolders, buildProperties)
48+
gccResult := GCC(sourceFile, targetFile, includeFolders, buildProperties).Run(ctx)
4949
verboseOut.Write(gccResult.Stdout)
5050
verboseOut.Write(gccResult.Stderr)
51-
if err != nil {
52-
return nil, err
51+
if gccResult.Error != nil {
52+
return nil, gccResult.Error
5353
}
5454

5555
arduinoPreprocessorProperties := properties.NewMap()

internal/arduino/builder/internal/preprocessor/ctags.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ func PreprocessSketchWithCtags(
5757

5858
// Run GCC preprocessor
5959
sourceFile := buildPath.Join("sketch", sketch.MainFile.Base()+".cpp")
60-
result, err := GCC(ctx, sourceFile, ctagsTarget, includes, buildProperties)
60+
result := GCC(sourceFile, ctagsTarget, includes, buildProperties).Run(ctx)
6161
stdout.Write(result.Stdout)
6262
stderr.Write(result.Stderr)
63-
if err != nil {
63+
if err := result.Error; err != nil {
6464
if !onlyUpdateCompilationDatabase {
6565
return &runner.Result{Args: result.Args, Stdout: stdout.Bytes(), Stderr: stderr.Bytes()}, err
6666
}

internal/arduino/builder/internal/preprocessor/gcc.go

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,10 @@
1616
package preprocessor
1717

1818
import (
19-
"bytes"
20-
"context"
21-
"errors"
22-
"fmt"
2319
"strings"
2420

2521
"github.com/arduino/arduino-cli/internal/arduino/builder/cpp"
2622
"github.com/arduino/arduino-cli/internal/arduino/builder/internal/runner"
27-
"github.com/arduino/arduino-cli/internal/i18n"
2823
"github.com/arduino/go-paths-helper"
2924
"github.com/arduino/go-properties-orderedmap"
3025
"go.bug.st/f"
@@ -33,10 +28,9 @@ import (
3328
// GCC performs a run of the gcc preprocess (macro/includes expansion). The function outputs the result
3429
// to targetFilePath. Returns the stdout/stderr of gcc if any.
3530
func GCC(
36-
ctx context.Context,
3731
sourceFilePath, targetFilePath *paths.Path,
3832
includes paths.PathList, buildProperties *properties.Map,
39-
) (*runner.Result, error) {
33+
) *runner.Task {
4034
gccBuildProperties := properties.NewMap()
4135
gccBuildProperties.Set("preproc.macros.flags", "-w -x c++ -E -CC")
4236
gccBuildProperties.Merge(buildProperties)
@@ -60,10 +54,6 @@ func GCC(
6054
}
6155

6256
pattern := gccBuildProperties.Get(gccPreprocRecipeProperty)
63-
if pattern == "" {
64-
return nil, errors.New(i18n.Tr("%s pattern is missing", gccPreprocRecipeProperty))
65-
}
66-
6757
commandLine := gccBuildProperties.ExpandPropsInString(pattern)
6858
commandLine = properties.DeleteUnexpandedPropsFromString(commandLine)
6959
args, _ := properties.SplitQuotedString(commandLine, `"'`, false)
@@ -72,46 +62,7 @@ func GCC(
7262
// to create a /dev/null.d dependency file, which won't work.
7363
args = f.Filter(args, f.NotEquals("-MMD"))
7464

75-
proc, err := paths.NewProcess(nil, args...)
76-
if err != nil {
77-
return nil, err
78-
}
79-
80-
stdout := bytes.NewBuffer(nil)
81-
stderr := bytes.NewBuffer(nil)
82-
83-
ctx, cancel := context.WithCancel(ctx)
84-
defer cancel()
85-
count := 0
86-
stderrLimited := writerFunc(func(p []byte) (int, error) {
87-
// Limit the size of the stderr buffer to 100KB
88-
n, err := stderr.Write(p)
89-
count += n
90-
if count > 100*1024 {
91-
fmt.Fprintln(stderr, i18n.Tr("Compiler error output has been truncated."))
92-
cancel()
93-
}
94-
return n, err
95-
})
96-
97-
proc.RedirectStdoutTo(stdout)
98-
proc.RedirectStderrTo(stderrLimited)
99-
100-
// Append gcc arguments to stdout before running the command
101-
fmt.Fprintln(stdout, strings.Join(args, " "))
102-
103-
if err := proc.Start(); err != nil {
104-
return &runner.Result{}, err
105-
}
106-
107-
// Wait for the process to finish
108-
err = proc.WaitWithinContext(ctx)
109-
110-
return &runner.Result{Args: proc.GetArgs(), Stdout: stdout.Bytes(), Stderr: stderr.Bytes()}, err
111-
}
112-
113-
type writerFunc func(p []byte) (n int, err error)
114-
115-
func (f writerFunc) Write(p []byte) (n int, err error) {
116-
return f(p)
65+
// Limit the stderr output to 100 KiB
66+
// https://github.com/arduino/arduino-cli/pull/2883
67+
return runner.NewTaskWithLimitedStderr(100*1024, args...)
11768
}

internal/arduino/builder/internal/runner/task.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,31 @@
1616
package runner
1717

1818
import (
19+
"bytes"
1920
"context"
2021
"fmt"
2122
"strings"
2223

24+
"github.com/arduino/arduino-cli/internal/i18n"
2325
"github.com/arduino/go-paths-helper"
2426
)
2527

2628
// Task is a command to be executed
2729
type Task struct {
28-
Args []string `json:"args"`
30+
Args []string `json:"args"`
31+
LimitStderr int `json:"-"`
2932
}
3033

3134
// NewTask creates a new Task
3235
func NewTask(args ...string) *Task {
3336
return &Task{Args: args}
3437
}
3538

39+
// NewTaskWithLimitedStderr creates a new Task with a hard-limit on the stderr output
40+
func NewTaskWithLimitedStderr(limit int, args ...string) *Task {
41+
return &Task{Args: args, LimitStderr: limit}
42+
}
43+
3644
func (t *Task) String() string {
3745
return strings.Join(t.Args, " ")
3846
}
@@ -51,10 +59,45 @@ func (t *Task) Run(ctx context.Context) *Result {
5159
if err != nil {
5260
return &Result{Args: t.Args, Error: err}
5361
}
54-
stdout, stderr, err := proc.RunAndCaptureOutput(ctx)
62+
63+
stdout := bytes.NewBuffer(nil)
64+
stderr := bytes.NewBuffer(nil)
65+
proc.RedirectStdoutTo(stdout)
66+
67+
if t.LimitStderr > 0 {
68+
innerCtx, cancel := context.WithCancel(ctx)
69+
defer cancel()
70+
71+
count := 0
72+
stderrLimited := writerFunc(func(p []byte) (int, error) {
73+
n, err := stderr.Write(p)
74+
count += n
75+
if count > t.LimitStderr {
76+
fmt.Fprintln(stderr, i18n.Tr("Compiler error output has been truncated."))
77+
cancel()
78+
}
79+
return n, err
80+
})
81+
82+
ctx = innerCtx
83+
proc.RedirectStderrTo(stderrLimited)
84+
} else {
85+
proc.RedirectStderrTo(stderr)
86+
}
5587

5688
// Append arguments to stdout
57-
stdout = append([]byte(fmt.Sprintln(t)), stdout...)
89+
fmt.Fprintln(stdout, t.String())
90+
91+
// Execute command and wait for the process to finish
92+
if err := proc.Start(); err != nil {
93+
return &Result{Error: err}
94+
}
95+
err = proc.WaitWithinContext(ctx)
96+
return &Result{Args: proc.GetArgs(), Stdout: stdout.Bytes(), Stderr: stderr.Bytes(), Error: err}
97+
}
98+
99+
type writerFunc func(p []byte) (n int, err error)
58100

59-
return &Result{Args: proc.GetArgs(), Stdout: stdout, Stderr: stderr, Error: err}
101+
func (f writerFunc) Write(p []byte) (n int, err error) {
102+
return f(p)
60103
}

0 commit comments

Comments
 (0)