@@ -17,7 +17,6 @@ package compile
1717
1818import (
1919 "context"
20- "errors"
2120 "fmt"
2221 "io"
2322 "path/filepath"
@@ -37,6 +36,7 @@ import (
3736 "github.com/arduino/arduino-cli/telemetry"
3837 paths "github.com/arduino/go-paths-helper"
3938 properties "github.com/arduino/go-properties-orderedmap"
39+ "github.com/pkg/errors"
4040 "github.com/segmentio/stats/v4"
4141 "github.com/sirupsen/logrus"
4242 "github.com/spf13/viper"
@@ -55,11 +55,16 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
5555 "verbose" : strconv .FormatBool (req .Verbose ),
5656 "quiet" : strconv .FormatBool (req .Quiet ),
5757 "vidPid" : req .VidPid ,
58- "exportFile" : telemetry .Sanitize (req .ExportFile ),
58+ "exportFile" : telemetry .Sanitize (req .ExportFile ), // deprecated
59+ "exportDir" : telemetry .Sanitize (req .GetExportDir ()),
5960 "jobs" : strconv .FormatInt (int64 (req .Jobs ), 10 ),
6061 "libraries" : strings .Join (req .Libraries , "," ),
6162 }
6263
64+ if req .GetExportFile () != "" {
65+ outStream .Write ([]byte (fmt .Sprintln ("Compile.ExportFile has been deprecated. The ExportFile parameter will be ignored, use ExportDir instead." )))
66+ }
67+
6368 // Use defer func() to evaluate tags map when function returns
6469 // and set success flag inspecting the error named return parameter
6570 defer func () {
@@ -197,54 +202,38 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
197202 }
198203
199204 if ! req .GetDryRun () {
200- // FIXME: Make a function to obtain these info...
201- outputPath := paths .New (
202- builderCtx .BuildProperties .ExpandPropsInString ("{build.path}/{recipe.output.tmp_file}" )) // "/build/path/sketch.ino.bin"
203- ext := outputPath .Ext () // ".hex" | ".bin"
204- base := outputPath .Base () // "sketch.ino.hex"
205- base = base [:len (base )- len (ext )] // "sketch.ino"
206-
207- // FIXME: Make a function to produce a better name...
208- // Make the filename without the FQBN configs part
209- fqbnSuffix := strings .Replace (fqbn .StringWithoutConfig (), ":" , "." , - 1 )
210-
211205 var exportPath * paths.Path
212- var exportFile string
213- if req .GetExportFile () == "" {
214- exportPath = sketch .FullPath
215- exportFile = sketch .Name + "." + fqbnSuffix // "sketch.arduino.avr.uno"
206+ if exportDir := req .GetExportDir (); exportDir != "" {
207+ exportPath = paths .New (exportDir )
216208 } else {
217- exportPath = paths .New (req .GetExportFile ()).Parent ()
218- exportFile = paths .New (req .GetExportFile ()).Base ()
219- if strings .HasSuffix (exportFile , ext ) {
220- exportFile = exportFile [:len (exportFile )- len (ext )]
221- }
209+ exportPath = sketch .FullPath
210+ // Add FQBN (without configs part) to export path
211+ fqbnSuffix := strings .Replace (fqbn .StringWithoutConfig (), ":" , "." , - 1 )
212+ exportPath = exportPath .Join ("build" ).Join (fqbnSuffix )
213+ }
214+ logrus .WithField ("path" , exportPath ).Trace ("Saving sketch to export path." )
215+ if err := exportPath .MkdirAll (); err != nil {
216+ return nil , errors .Wrap (err , "creating output dir" )
222217 }
223218
224- // Copy "sketch.ino.*.hex" / "sketch.ino.*.bin " artifacts to sketch directory
225- srcDir , err := outputPath . Parent (). ReadDir ( ) // read "/build/path/* "
226- if err != nil {
227- return nil , fmt . Errorf ( "reading build directory: %s" , err )
219+ // Copy all "sketch.ino.*" artifacts to the export directory
220+ baseName , ok := builderCtx . BuildProperties . GetOk ( "build.project_name" ) // == "sketch.ino "
221+ if ! ok {
222+ return nil , errors . New ( "missing ' build.project_name' build property" )
228223 }
229- srcDir .FilterPrefix (base + "." )
230- srcDir .FilterSuffix (ext )
231- for _ , srcOutput := range srcDir {
232- srcFilename := srcOutput .Base () // "sketch.ino.*.bin"
233- srcFilename = srcFilename [len (base ):] // ".*.bin"
234- dstOutput := exportPath .Join (exportFile + srcFilename )
235- logrus .WithField ("from" , srcOutput ).WithField ("to" , dstOutput ).Debug ("copying sketch build output" )
236- if err = srcOutput .CopyTo (dstOutput ); err != nil {
237- return nil , fmt .Errorf ("copying output file: %s" , err )
238- }
224+ buildFiles , err := builderCtx .BuildPath .ReadDir ()
225+ if err != nil {
226+ return nil , errors .Errorf ("reading build directory: %s" , err )
239227 }
240-
241- // Copy .elf file to sketch directory
242- srcElf := outputPath .Parent ().Join (base + ".elf" )
243- if srcElf .Exist () {
244- dstElf := exportPath .Join (exportFile + ".elf" )
245- logrus .WithField ("from" , srcElf ).WithField ("to" , dstElf ).Debug ("copying sketch build output" )
246- if err = srcElf .CopyTo (dstElf ); err != nil {
247- return nil , fmt .Errorf ("copying elf file: %s" , err )
228+ buildFiles .FilterPrefix (baseName )
229+ for _ , buildFile := range buildFiles {
230+ exportedFile := exportPath .Join (buildFile .Base ())
231+ logrus .
232+ WithField ("src" , buildFile ).
233+ WithField ("dest" , exportedFile ).
234+ Trace ("Copying artifact." )
235+ if err = buildFile .CopyTo (exportedFile ); err != nil {
236+ return nil , errors .Wrapf (err , "copying output file %s" , buildFile )
248237 }
249238 }
250239 }
0 commit comments