16
16
package phases
17
17
18
18
import (
19
+ "bytes"
20
+ "io"
19
21
"strings"
20
22
21
23
"github.com/arduino/arduino-cli/arduino/builder"
22
24
"github.com/arduino/arduino-cli/arduino/builder/utils"
23
25
f "github.com/arduino/arduino-cli/internal/algorithms"
24
- "github.com/arduino/arduino-cli/legacy/builder/constants"
25
- "github.com/arduino/arduino-cli/legacy/builder/types"
26
26
"github.com/arduino/go-paths-helper"
27
27
"github.com/arduino/go-properties-orderedmap"
28
28
"github.com/pkg/errors"
29
29
)
30
30
31
- type Linker struct {}
32
-
33
- func (s * Linker ) Run (ctx * types.Context ) error {
34
- if ctx .OnlyUpdateCompilationDatabase {
35
- if ctx .Verbose {
36
- ctx .Info (tr ("Skip linking of final executable." ))
31
+ func Linker (
32
+ onlyUpdateCompilationDatabase , verbose bool ,
33
+ sketchObjectFiles , librariesObjectFiles , coreObjectsFiles paths.PathList ,
34
+ coreArchiveFilePath , buildPath * paths.Path ,
35
+ buildProperties * properties.Map ,
36
+ stdoutWriter , stderrWriter io.Writer ,
37
+ warningsLevel string ,
38
+ ) ([]byte , error ) {
39
+ verboseInfo := & bytes.Buffer {}
40
+ if onlyUpdateCompilationDatabase {
41
+ if verbose {
42
+ verboseInfo .WriteString (tr ("Skip linking of final executable." ))
37
43
}
38
- return nil
44
+ return verboseInfo . Bytes (), nil
39
45
}
40
46
41
- objectFilesSketch := ctx . SketchObjectFiles
42
- objectFilesLibraries := ctx . LibrariesObjectFiles
43
- objectFilesCore := ctx . CoreObjectsFiles
47
+ objectFilesSketch := sketchObjectFiles
48
+ objectFilesLibraries := librariesObjectFiles
49
+ objectFilesCore := coreObjectsFiles
44
50
45
51
objectFiles := paths .NewPathList ()
46
52
objectFiles .AddAll (objectFilesSketch )
47
53
objectFiles .AddAll (objectFilesLibraries )
48
54
objectFiles .AddAll (objectFilesCore )
49
55
50
- coreArchiveFilePath := ctx .CoreArchiveFilePath
51
- buildPath := ctx .BuildPath
52
56
coreDotARelPath , err := buildPath .RelTo (coreArchiveFilePath )
53
57
if err != nil {
54
- return errors .WithStack (err )
58
+ return nil , errors .WithStack (err )
55
59
}
56
60
57
- buildProperties := ctx .BuildProperties
58
-
59
- err = link (ctx , objectFiles , coreDotARelPath , coreArchiveFilePath , buildProperties )
61
+ verboseInfoOut , err := link (
62
+ objectFiles , coreDotARelPath , coreArchiveFilePath , buildProperties ,
63
+ verbose , stdoutWriter , stderrWriter , warningsLevel ,
64
+ )
65
+ verboseInfo .Write (verboseInfoOut )
60
66
if err != nil {
61
- return errors .WithStack (err )
67
+ return verboseInfo . Bytes (), errors .WithStack (err )
62
68
}
63
69
64
- return nil
70
+ return verboseInfo . Bytes (), nil
65
71
}
66
72
67
- func link (ctx * types.Context , objectFiles paths.PathList , coreDotARelPath * paths.Path , coreArchiveFilePath * paths.Path , buildProperties * properties.Map ) error {
73
+ func link (
74
+ objectFiles paths.PathList , coreDotARelPath * paths.Path , coreArchiveFilePath * paths.Path , buildProperties * properties.Map ,
75
+ verbose bool ,
76
+ stdoutWriter , stderrWriter io.Writer ,
77
+ warningsLevel string ,
78
+ ) ([]byte , error ) {
79
+ verboseBuffer := & bytes.Buffer {}
80
+ wrapWithDoubleQuotes := func (value string ) string { return "\" " + value + "\" " }
68
81
objectFileList := strings .Join (f .Map (objectFiles .AsStrings (), wrapWithDoubleQuotes ), " " )
69
82
70
83
// If command line length is too big (> 30000 chars), try to collect the object files into archives
@@ -95,14 +108,14 @@ func link(ctx *types.Context, objectFiles paths.PathList, coreDotARelPath *paths
95
108
96
109
command , err := utils .PrepareCommandForRecipe (properties , builder .RecipeARPattern , false )
97
110
if err != nil {
98
- return errors .WithStack (err )
111
+ return nil , errors .WithStack (err )
99
112
}
100
113
101
- if verboseInfo , _ , _ , err := utils .ExecCommand (ctx . Verbose , ctx . Stdout , ctx . Stderr , command , utils .ShowIfVerbose /* stdout */ , utils .Show /* stderr */ ); err != nil {
102
- if ctx . Verbose {
103
- ctx . Info (string (verboseInfo ))
114
+ if verboseInfo , _ , _ , err := utils .ExecCommand (verbose , stdoutWriter , stderrWriter , command , utils .ShowIfVerbose /* stdout */ , utils .Show /* stderr */ ); err != nil {
115
+ if verbose {
116
+ verboseBuffer . WriteString (string (verboseInfo ))
104
117
}
105
- return errors .WithStack (err )
118
+ return verboseBuffer . Bytes (), errors .WithStack (err )
106
119
}
107
120
}
108
121
@@ -111,24 +124,20 @@ func link(ctx *types.Context, objectFiles paths.PathList, coreDotARelPath *paths
111
124
}
112
125
113
126
properties := buildProperties .Clone ()
114
- properties .Set (constants . BUILD_PROPERTIES_COMPILER_C_ELF_FLAGS , properties .Get (constants . BUILD_PROPERTIES_COMPILER_C_ELF_FLAGS ))
115
- properties .Set (builder .BuildPropertiesCompilerWarningFlags , properties .Get (builder .BuildPropertiesCompilerWarningFlags + "." + ctx . WarningsLevel ))
127
+ properties .Set ("compiler.c.elf.flags" , properties .Get ("compiler.c.elf.flags" ))
128
+ properties .Set (builder .BuildPropertiesCompilerWarningFlags , properties .Get (builder .BuildPropertiesCompilerWarningFlags + "." + warningsLevel ))
116
129
properties .Set (builder .BuildPropertiesArchiveFile , coreDotARelPath .String ())
117
130
properties .Set (builder .BuildPropertiesArchiveFilePath , coreArchiveFilePath .String ())
118
131
properties .Set ("object_files" , objectFileList )
119
132
120
- command , err := utils .PrepareCommandForRecipe (properties , constants . RECIPE_C_COMBINE_PATTERN , false )
133
+ command , err := utils .PrepareCommandForRecipe (properties , "recipe.c.combine.pattern" , false )
121
134
if err != nil {
122
- return err
135
+ return verboseBuffer . Bytes (), err
123
136
}
124
137
125
- verboseInfo , _ , _ , err := utils .ExecCommand (ctx . Verbose , ctx . Stdout , ctx . Stderr , command , utils .ShowIfVerbose /* stdout */ , utils .Show /* stderr */ )
126
- if ctx . Verbose {
127
- ctx . Info (string (verboseInfo ))
138
+ verboseInfo , _ , _ , err := utils .ExecCommand (verbose , stdoutWriter , stderrWriter , command , utils .ShowIfVerbose /* stdout */ , utils .Show /* stderr */ )
139
+ if verbose {
140
+ verboseBuffer . WriteString (string (verboseInfo ))
128
141
}
129
- return err
130
- }
131
-
132
- func wrapWithDoubleQuotes (value string ) string {
133
- return "\" " + value + "\" "
142
+ return verboseBuffer .Bytes (), err
134
143
}
0 commit comments