diff --git a/arduino/libraries/libraries.go b/arduino/libraries/libraries.go index 7bf6f3e0f3d..8d83e9b93cc 100644 --- a/arduino/libraries/libraries.go +++ b/arduino/libraries/libraries.go @@ -19,6 +19,7 @@ import ( "fmt" "github.com/arduino/arduino-cli/arduino/cores" + rpc "github.com/arduino/arduino-cli/rpc/commands" paths "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" semver "go.bug.st/relaxed-semver" @@ -85,6 +86,49 @@ func (library *Library) String() string { return library.Name + "@" + library.Version.String() } +// ToRPCLibrary converts this library into an rpc.Library +func (library *Library) ToRPCLibrary() *rpc.Library { + pathOrEmpty := func(p *paths.Path) string { + if p == nil { + return "" + } + return p.String() + } + platformOrEmpty := func(p *cores.PlatformRelease) string { + if p == nil { + return "" + } + return p.String() + } + return &rpc.Library{ + Name: library.Name, + Author: library.Author, + Maintainer: library.Maintainer, + Sentence: library.Sentence, + Paragraph: library.Paragraph, + Website: library.Website, + Category: library.Category, + Architectures: library.Architectures, + Types: library.Types, + InstallDir: pathOrEmpty(library.InstallDir), + SourceDir: pathOrEmpty(library.SourceDir), + UtilityDir: pathOrEmpty(library.UtilityDir), + Location: library.Location.ToRPCLibraryLocation(), + ContainerPlatform: platformOrEmpty(library.ContainerPlatform), + Layout: library.Layout.ToRPCLibraryLayout(), + RealName: library.RealName, + DotALinkage: library.DotALinkage, + Precompiled: library.Precompiled, + LdFlags: library.LDflags, + IsLegacy: library.IsLegacy, + Version: library.Version.String(), + License: library.License, + Examples: library.Examples.AsStrings(), + ProvidesIncludes: library.DeclaredHeaders(), + CompatibleWith: library.CompatibleWith, + } +} + // SupportsAnyArchitectureIn returns true if any of the following is true: // - the library supports at least one of the given architectures // - the library is architecture independent diff --git a/arduino/libraries/librariesindex/index.go b/arduino/libraries/librariesindex/index.go index 3c42358f5cc..b21506a197e 100644 --- a/arduino/libraries/librariesindex/index.go +++ b/arduino/libraries/librariesindex/index.go @@ -20,6 +20,7 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries" "github.com/arduino/arduino-cli/arduino/resources" + rpc "github.com/arduino/arduino-cli/rpc/commands" semver "go.bug.st/relaxed-semver" ) @@ -58,6 +59,21 @@ type Release struct { Library *Library `json:"-"` } +// ToRPCLibraryRelease transform this Release into a rpc.LibraryRelease +func (r *Release) ToRPCLibraryRelease() *rpc.LibraryRelease { + return &rpc.LibraryRelease{ + Author: r.Author, + Version: r.Version.String(), + Maintainer: r.Maintainer, + Sentence: r.Sentence, + Paragraph: r.Paragraph, + Website: r.Website, + Category: r.Category, + Architectures: r.Architectures, + Types: r.Types, + } +} + // GetName returns the name of this library. func (r *Release) GetName() string { return r.Library.Name diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 23e65758e7b..afa73c55c09 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -16,10 +16,12 @@ package compile import ( + "bytes" "context" "os" "github.com/arduino/arduino-cli/cli/feedback" + "github.com/arduino/arduino-cli/cli/output" "github.com/arduino/arduino-cli/configuration" "github.com/arduino/arduino-cli/cli/errorcodes" @@ -124,7 +126,7 @@ func run(cmd *cobra.Command, args []string) { // the config file and the env vars. exportBinaries = configuration.Settings.GetBool("sketch.always_export_binaries") - _, err = compile.Compile(context.Background(), &rpc.CompileReq{ + compileReq := &rpc.CompileReq{ Instance: inst, Fqbn: fqbn, SketchPath: sketchPath.String(), @@ -142,15 +144,19 @@ func run(cmd *cobra.Command, args []string) { OptimizeForDebug: optimizeForDebug, Clean: clean, ExportBinaries: exportBinaries, - }, os.Stdout, os.Stderr, configuration.Settings.GetString("logging.level") == "debug") - - if err != nil { - feedback.Errorf("Error during build: %v", err) - os.Exit(errorcodes.ErrGeneric) + } + compileOut := new(bytes.Buffer) + compileErr := new(bytes.Buffer) + verboseCompile := configuration.Settings.GetString("logging.level") == "debug" + var compileRes *rpc.CompileResp + if output.OutputFormat == "json" { + compileRes, err = compile.Compile(context.Background(), compileReq, compileOut, compileErr, verboseCompile) + } else { + compileRes, err = compile.Compile(context.Background(), compileReq, os.Stdout, os.Stderr, verboseCompile) } - if uploadAfterCompile { - _, err := upload.Upload(context.Background(), &rpc.UploadReq{ + if err == nil && uploadAfterCompile { + uploadReq := &rpc.UploadReq{ Instance: inst, Fqbn: fqbn, SketchPath: sketchPath.String(), @@ -159,13 +165,32 @@ func run(cmd *cobra.Command, args []string) { Verify: verify, ImportDir: buildPath, Programmer: programmer, - }, os.Stdout, os.Stderr) - + } + var err error + if output.OutputFormat == "json" { + // TODO: do not print upload output in json mode + uploadOut := new(bytes.Buffer) + uploadErr := new(bytes.Buffer) + _, err = upload.Upload(context.Background(), uploadReq, uploadOut, uploadErr) + } else { + _, err = upload.Upload(context.Background(), uploadReq, os.Stdout, os.Stderr) + } if err != nil { feedback.Errorf("Error during Upload: %v", err) os.Exit(errorcodes.ErrGeneric) } } + + feedback.PrintResult(&compileResult{ + CompileOut: compileOut.String(), + CompileErr: compileErr.String(), + BuilderResult: compileRes, + Success: err == nil, + }) + if err != nil && output.OutputFormat != "json" { + feedback.Errorf("Error during build: %v", err) + os.Exit(errorcodes.ErrGeneric) + } } // initSketchPath returns the current working directory @@ -182,3 +207,19 @@ func initSketchPath(sketchPath *paths.Path) *paths.Path { logrus.Infof("Reading sketch from dir: %s", wd) return wd } + +type compileResult struct { + CompileOut string `json:"compiler_out"` + CompileErr string `json:"compiler_err"` + BuilderResult *rpc.CompileResp `json:"builder_result"` + Success bool `json:"success"` +} + +func (r *compileResult) Data() interface{} { + return r +} + +func (r *compileResult) String() string { + // The output is already printed via os.Stdout/os.Stdin + return "" +} diff --git a/cli/lib/list.go b/cli/lib/list.go index 0f6c32cd83f..6225ad8b16c 100644 --- a/cli/lib/list.go +++ b/cli/lib/list.go @@ -140,19 +140,22 @@ func (ir installedResult) String() string { location = lib.GetContainerPlatform() } + available := "" + sentence := "" if libMeta.GetRelease() != nil { - available := libMeta.GetRelease().GetVersion() - if available == "" { - available = "-" - } - sentence := lib.Sentence - if sentence == "" { - sentence = "-" - } else if len(sentence) > 40 { - sentence = sentence[:37] + "..." - } - t.AddRow(name, lib.Version, available, location, sentence) + available = libMeta.GetRelease().GetVersion() + sentence = lib.Sentence + } + + if available == "" { + available = "-" + } + if sentence == "" { + sentence = "-" + } else if len(sentence) > 40 { + sentence = sentence[:37] + "..." } + t.AddRow(name, lib.Version, available, location, sentence) } return t.Render() diff --git a/commands/compile/compile.go b/commands/compile/compile.go index 11b2f8148e2..360db3638c6 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -189,6 +189,21 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W builderCtx.SetLogger(i18n.LoggerToCustomStreams{Stdout: outStream, Stderr: errStream}) builderCtx.Clean = req.GetClean() + // Use defer() to create an rpc.CompileResp with all the information available at the + // moment of return. + defer func() { + if r != nil { + importedLibs := []*rpc.Library{} + for _, lib := range builderCtx.ImportedLibraries { + importedLibs = append(importedLibs, lib.ToRPCLibrary()) + } + + r.BuildPath = builderCtx.BuildPath.String() + r.UsedLibraries = importedLibs + r.ExecutableSectionsSize = builderCtx.ExecutableSectionsSize.ToRPCExecutableSectionSizeArray() + } + }() + // if --preprocess or --show-properties were passed, we can stop here if req.GetShowProperties() { return &rpc.CompileResp{}, builder.RunParseHardwareAndDumpBuildProperties(builderCtx) @@ -198,7 +213,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W // if it's a regular build, go on... if err := builder.RunBuilder(builderCtx); err != nil { - return nil, err + return &rpc.CompileResp{}, err } // If the export directory is set we assume you want to export the binaries diff --git a/commands/lib/list.go b/commands/lib/list.go index 07a21de3889..de23709bf14 100644 --- a/commands/lib/list.go +++ b/commands/lib/list.go @@ -99,13 +99,12 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListReq) (*rpc.LibraryList if nameFilter != "" && strings.ToLower(lib.Library.Name) != nameFilter { continue } - libtmp, err := GetOutputLibrary(lib.Library) - if err != nil { - return nil, err + var release *rpc.LibraryRelease + if lib.Available != nil { + release = lib.Available.ToRPCLibraryRelease() } - release := GetOutputRelease(lib.Available) instaledLib = append(instaledLib, &rpc.InstalledLibrary{ - Library: libtmp, + Library: lib.Library.ToRPCLibrary(), Release: release, }) } @@ -136,69 +135,3 @@ func listLibraries(lm *librariesmanager.LibrariesManager, updatable bool, all bo } return res } - -// GetOutputLibrary FIXMEDOC -func GetOutputLibrary(lib *libraries.Library) (*rpc.Library, error) { - insdir := "" - if lib.InstallDir != nil { - insdir = lib.InstallDir.String() - } - srcdir := "" - if lib.SourceDir != nil { - srcdir = lib.SourceDir.String() - } - utldir := "" - if lib.UtilityDir != nil { - utldir = lib.UtilityDir.String() - } - cntplat := "" - if lib.ContainerPlatform != nil { - cntplat = lib.ContainerPlatform.String() - } - - return &rpc.Library{ - Name: lib.Name, - Author: lib.Author, - Maintainer: lib.Maintainer, - Sentence: lib.Sentence, - Paragraph: lib.Paragraph, - Website: lib.Website, - Category: lib.Category, - Architectures: lib.Architectures, - Types: lib.Types, - InstallDir: insdir, - SourceDir: srcdir, - UtilityDir: utldir, - Location: lib.Location.ToRPCLibraryLocation(), - ContainerPlatform: cntplat, - Layout: lib.Layout.ToRPCLibraryLayout(), - RealName: lib.RealName, - DotALinkage: lib.DotALinkage, - Precompiled: lib.Precompiled, - LdFlags: lib.LDflags, - IsLegacy: lib.IsLegacy, - Version: lib.Version.String(), - License: lib.License, - Examples: lib.Examples.AsStrings(), - ProvidesIncludes: lib.DeclaredHeaders(), - CompatibleWith: lib.CompatibleWith, - }, nil -} - -// GetOutputRelease FIXMEDOC -func GetOutputRelease(lib *librariesindex.Release) *rpc.LibraryRelease { // - if lib != nil { - return &rpc.LibraryRelease{ - Author: lib.Author, - Version: lib.Version.String(), - Maintainer: lib.Maintainer, - Sentence: lib.Sentence, - Paragraph: lib.Paragraph, - Website: lib.Website, - Category: lib.Category, - Architectures: lib.Architectures, - Types: lib.Types, - } - } - return &rpc.LibraryRelease{} -} diff --git a/legacy/builder/phases/sizer.go b/legacy/builder/phases/sizer.go index 57a3d265e9a..a650ce68292 100644 --- a/legacy/builder/phases/sizer.go +++ b/legacy/builder/phases/sizer.go @@ -88,6 +88,21 @@ func checkSize(ctx *types.Context, buildProperties *properties.Map) error { } } + ctx.ExecutableSectionsSize = []types.ExecutableSectionSize{ + { + Name: "text", + Size: textSize, + MaxSize: maxTextSize, + }, + } + if maxDataSize > 0 { + ctx.ExecutableSectionsSize = append(ctx.ExecutableSectionsSize, types.ExecutableSectionSize{ + Name: "data", + Size: dataSize, + MaxSize: maxDataSize, + }) + } + if textSize > maxTextSize { logger.Println(constants.LOG_LEVEL_ERROR, constants.MSG_SIZER_TEXT_TOO_BIG) return errors.New("text section exceeds available space in board") diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index cd5510e1897..50ca24dce93 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -25,6 +25,7 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/arduino/libraries/librariesresolver" "github.com/arduino/arduino-cli/legacy/builder/i18n" + rpc "github.com/arduino/arduino-cli/rpc/commands" paths "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" ) @@ -159,6 +160,32 @@ type Context struct { // Out and Err stream to redirect all Exec commands ExecStdout io.Writer ExecStderr io.Writer + + // Sizer results + ExecutableSectionsSize ExecutablesFileSections +} + +// ExecutableSectionSize represents a section of the executable output file +type ExecutableSectionSize struct { + Name string + Size int + MaxSize int +} + +// ExecutablesFileSections is an array of ExecutablesFileSection +type ExecutablesFileSections []ExecutableSectionSize + +// ToRPCExecutableSectionSizeArray transforms this array into a []*rpc.ExecutableSectionSize +func (s ExecutablesFileSections) ToRPCExecutableSectionSizeArray() []*rpc.ExecutableSectionSize { + res := []*rpc.ExecutableSectionSize{} + for _, section := range s { + res = append(res, &rpc.ExecutableSectionSize{ + Name: section.Name, + Size: int64(section.Size), + MaxSize: int64(section.MaxSize), + }) + } + return res } func (ctx *Context) ExtractBuildOptions() *properties.Map { diff --git a/rpc/commands/compile.pb.go b/rpc/commands/compile.pb.go index 98907ff28cb..269a37dcd6d 100644 --- a/rpc/commands/compile.pb.go +++ b/rpc/commands/compile.pb.go @@ -228,8 +228,11 @@ type CompileResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OutStream []byte `protobuf:"bytes,1,opt,name=out_stream,json=outStream,proto3" json:"out_stream,omitempty"` // The output of the compilation process. - ErrStream []byte `protobuf:"bytes,2,opt,name=err_stream,json=errStream,proto3" json:"err_stream,omitempty"` // The error output of the compilation process. + OutStream []byte `protobuf:"bytes,1,opt,name=out_stream,json=outStream,proto3" json:"out_stream,omitempty"` // The output of the compilation process. + ErrStream []byte `protobuf:"bytes,2,opt,name=err_stream,json=errStream,proto3" json:"err_stream,omitempty"` // The error output of the compilation process. + BuildPath string `protobuf:"bytes,3,opt,name=build_path,json=buildPath,proto3" json:"build_path,omitempty"` // The compiler build path + UsedLibraries []*Library `protobuf:"bytes,4,rep,name=used_libraries,json=usedLibraries,proto3" json:"used_libraries,omitempty"` // The libraries used in the build + ExecutableSectionsSize []*ExecutableSectionSize `protobuf:"bytes,5,rep,name=executable_sections_size,json=executableSectionsSize,proto3" json:"executable_sections_size,omitempty"` // The size of the executable split by sections } func (x *CompileResp) Reset() { @@ -278,6 +281,90 @@ func (x *CompileResp) GetErrStream() []byte { return nil } +func (x *CompileResp) GetBuildPath() string { + if x != nil { + return x.BuildPath + } + return "" +} + +func (x *CompileResp) GetUsedLibraries() []*Library { + if x != nil { + return x.UsedLibraries + } + return nil +} + +func (x *CompileResp) GetExecutableSectionsSize() []*ExecutableSectionSize { + if x != nil { + return x.ExecutableSectionsSize + } + return nil +} + +type ExecutableSectionSize struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + MaxSize int64 `protobuf:"varint,3,opt,name=maxSize,proto3" json:"maxSize,omitempty"` +} + +func (x *ExecutableSectionSize) Reset() { + *x = ExecutableSectionSize{} + if protoimpl.UnsafeEnabled { + mi := &file_commands_compile_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutableSectionSize) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutableSectionSize) ProtoMessage() {} + +func (x *ExecutableSectionSize) ProtoReflect() protoreflect.Message { + mi := &file_commands_compile_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutableSectionSize.ProtoReflect.Descriptor instead. +func (*ExecutableSectionSize) Descriptor() ([]byte, []int) { + return file_commands_compile_proto_rawDescGZIP(), []int{2} +} + +func (x *ExecutableSectionSize) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ExecutableSectionSize) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ExecutableSectionSize) GetMaxSize() int64 { + if x != nil { + return x.MaxSize + } + return 0 +} + var File_commands_compile_proto protoreflect.FileDescriptor var file_commands_compile_proto_rawDesc = []byte{ @@ -285,53 +372,73 @@ var file_commands_compile_proto_rawDesc = []byte{ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd7, 0x04, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, - 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x63, 0x2e, 0x61, - 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6b, - 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x68, - 0x6f, 0x77, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, - 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, - 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, - 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x69, 0x65, - 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x71, 0x75, 0x69, 0x65, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x76, 0x69, 0x64, 0x50, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x76, 0x69, 0x64, 0x50, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x69, - 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x70, 0x74, 0x69, - 0x6d, 0x69, 0x7a, 0x65, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x18, 0x10, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x46, 0x6f, 0x72, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, - 0x69, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x44, 0x69, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x13, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x70, - 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x14, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x69, - 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, - 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, - 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x2f, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd7, 0x04, 0x0a, + 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x08, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, + 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1e, + 0x0a, 0x0a, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, + 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, + 0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x0f, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x69, 0x65, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x71, 0x75, 0x69, + 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x69, 0x64, 0x50, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x76, 0x69, 0x64, 0x50, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x6f, + 0x62, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x12, 0x1c, + 0x0a, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, + 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, + 0x46, 0x6f, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x65, 0x61, 0x6e, + 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x27, 0x0a, + 0x0f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x69, + 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x22, 0x9d, 0x02, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, + 0x61, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, + 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x0d, 0x75, + 0x73, 0x65, 0x64, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x68, 0x0a, 0x18, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x16, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x59, 0x0a, 0x15, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, + 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, + 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, + 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -346,19 +453,23 @@ func file_commands_compile_proto_rawDescGZIP() []byte { return file_commands_compile_proto_rawDescData } -var file_commands_compile_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_commands_compile_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_commands_compile_proto_goTypes = []interface{}{ - (*CompileReq)(nil), // 0: cc.arduino.cli.commands.CompileReq - (*CompileResp)(nil), // 1: cc.arduino.cli.commands.CompileResp - (*Instance)(nil), // 2: cc.arduino.cli.commands.Instance + (*CompileReq)(nil), // 0: cc.arduino.cli.commands.CompileReq + (*CompileResp)(nil), // 1: cc.arduino.cli.commands.CompileResp + (*ExecutableSectionSize)(nil), // 2: cc.arduino.cli.commands.ExecutableSectionSize + (*Instance)(nil), // 3: cc.arduino.cli.commands.Instance + (*Library)(nil), // 4: cc.arduino.cli.commands.Library } var file_commands_compile_proto_depIdxs = []int32{ - 2, // 0: cc.arduino.cli.commands.CompileReq.instance:type_name -> cc.arduino.cli.commands.Instance - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 3, // 0: cc.arduino.cli.commands.CompileReq.instance:type_name -> cc.arduino.cli.commands.Instance + 4, // 1: cc.arduino.cli.commands.CompileResp.used_libraries:type_name -> cc.arduino.cli.commands.Library + 2, // 2: cc.arduino.cli.commands.CompileResp.executable_sections_size:type_name -> cc.arduino.cli.commands.ExecutableSectionSize + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_commands_compile_proto_init() } @@ -367,6 +478,7 @@ func file_commands_compile_proto_init() { return } file_commands_common_proto_init() + file_commands_lib_proto_init() if !protoimpl.UnsafeEnabled { file_commands_compile_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CompileReq); i { @@ -392,6 +504,18 @@ func file_commands_compile_proto_init() { return nil } } + file_commands_compile_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutableSectionSize); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -399,7 +523,7 @@ func file_commands_compile_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_commands_compile_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/commands/compile.proto b/rpc/commands/compile.proto index fcba5a0fb41..ef7ccccfcc1 100644 --- a/rpc/commands/compile.proto +++ b/rpc/commands/compile.proto @@ -20,6 +20,7 @@ package cc.arduino.cli.commands; option go_package = "github.com/arduino/arduino-cli/rpc/commands"; import "commands/common.proto"; +import "commands/lib.proto"; message CompileReq { Instance instance = 1; // Arduino Core Service instance from the `Init` response. @@ -45,4 +46,13 @@ message CompileReq { message CompileResp { bytes out_stream = 1; // The output of the compilation process. bytes err_stream = 2; // The error output of the compilation process. + string build_path = 3; // The compiler build path + repeated Library used_libraries = 4; // The libraries used in the build + repeated ExecutableSectionSize executable_sections_size = 5; // The size of the executable split by sections } + +message ExecutableSectionSize { + string name = 1; + int64 size = 2; + int64 maxSize = 3; +} \ No newline at end of file diff --git a/test/test_compile.py b/test/test_compile.py index 30ffd1ef452..b04c8e82f10 100644 --- a/test/test_compile.py +++ b/test/test_compile.py @@ -17,6 +17,7 @@ import tempfile import hashlib from pathlib import Path +import simplejson as json import pytest @@ -55,6 +56,14 @@ def test_compile_with_simple_sketch(run_command, data_dir, working_dir): result = run_command(f"compile -b {fqbn} {sketch_path}") assert result.ok + # Build sketch for arduino:avr:uno with json output + result = run_command(f"compile -b {fqbn} {sketch_path} --format json") + assert result.ok + # check is a valid json and contains requested data + compile_output = json.loads(result.stdout) + assert compile_output["compiler_out"] != "" + assert compile_output["compiler_err"] == "" + # Verifies expected binaries have been built sketch_path_md5 = hashlib.md5(bytes(sketch_path)).hexdigest().upper() build_dir = Path(tempfile.gettempdir(), f"arduino-sketch-{sketch_path_md5}")