Skip to content

Commit 88468f2

Browse files
author
Roberto Sora
authored
Add support for compile with debug optimizations (#593)
* add debug symbols option in CLI and gRPC insterface * Calculate precompiled core path usign also build optimization flags * Align failing lecacy tests with new hashing behaviour
1 parent fc13047 commit 88468f2

13 files changed

+101
-65
lines changed

cli/compile/compile.go

+17-14
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var (
4848
verify bool // Upload, verify uploaded binary after the upload.
4949
exportFile string // The compiled binary is written to this file
5050
libraries []string // List of custom libraries paths separated by commas. Or can be used multiple times for multiple libraries paths.
51+
optimizeForDebug bool // Optimize compile output for debug, not for release
5152
)
5253

5354
// NewCommand created a new `compile` command
@@ -80,6 +81,7 @@ func NewCommand() *cobra.Command {
8081
command.Flags().StringVar(&vidPid, "vid-pid", "", "When specified, VID/PID specific build properties are used, if boards supports them.")
8182
command.Flags().StringSliceVar(&libraries, "libraries", []string{},
8283
"List of custom libraries paths separated by commas. Or can be used multiple times for multiple libraries paths.")
84+
command.Flags().BoolVar(&optimizeForDebug, "optimize-for-debug", false, "Optional, optimize compile output for debug, not for release.")
8385

8486
return command
8587
}
@@ -99,20 +101,21 @@ func run(cmd *cobra.Command, args []string) {
99101
sketchPath := initSketchPath(path)
100102

101103
_, err = compile.Compile(context.Background(), &rpc.CompileReq{
102-
Instance: inst,
103-
Fqbn: fqbn,
104-
SketchPath: sketchPath.String(),
105-
ShowProperties: showProperties,
106-
Preprocess: preprocess,
107-
BuildCachePath: buildCachePath,
108-
BuildPath: buildPath,
109-
BuildProperties: buildProperties,
110-
Warnings: warnings,
111-
Verbose: verbose,
112-
Quiet: quiet,
113-
VidPid: vidPid,
114-
ExportFile: exportFile,
115-
Libraries: libraries,
104+
Instance: inst,
105+
Fqbn: fqbn,
106+
SketchPath: sketchPath.String(),
107+
ShowProperties: showProperties,
108+
Preprocess: preprocess,
109+
BuildCachePath: buildCachePath,
110+
BuildPath: buildPath,
111+
BuildProperties: buildProperties,
112+
Warnings: warnings,
113+
Verbose: verbose,
114+
Quiet: quiet,
115+
VidPid: vidPid,
116+
ExportFile: exportFile,
117+
Libraries: libraries,
118+
OptimizeForDebug: optimizeForDebug,
116119
}, os.Stdout, os.Stderr, viper.GetString("logging.level") == "debug")
117120

118121
if err != nil {

commands/compile/compile.go

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
103103

104104
builderCtx.Verbose = req.GetVerbose()
105105

106+
// Optimize for debug
107+
builderCtx.OptimizeForDebug = req.GetOptimizeForDebug()
108+
106109
builderCtx.CoreBuildCachePath = paths.TempDir().Join("arduino-core-cache")
107110

108111
builderCtx.Jobs = int(req.GetJobs())

legacy/builder/builder_utils/utils.go

-17
Original file line numberDiff line numberDiff line change
@@ -519,20 +519,3 @@ func PrepareCommandForRecipe(ctx *types.Context, buildProperties *properties.Map
519519

520520
return command, nil
521521
}
522-
523-
// GetCachedCoreArchiveFileName returns the filename to be used to store
524-
// the global cached core.a.
525-
func GetCachedCoreArchiveFileName(fqbn string, coreFolder *paths.Path) string {
526-
fqbnToUnderscore := strings.Replace(fqbn, ":", "_", -1)
527-
fqbnToUnderscore = strings.Replace(fqbnToUnderscore, "=", "_", -1)
528-
if absCoreFolder, err := coreFolder.Abs(); err == nil {
529-
coreFolder = absCoreFolder
530-
} // silently continue if absolute path can't be detected
531-
hash := utils.MD5Sum([]byte(coreFolder.String()))
532-
realName := "core_" + fqbnToUnderscore + "_" + hash + ".a"
533-
if len(realName) > 100 {
534-
// avoid really long names, simply hash the final part
535-
realName = "core_" + utils.MD5Sum([]byte(fqbnToUnderscore+"_"+hash)) + ".a"
536-
}
537-
return realName
538-
}

legacy/builder/create_build_options_map.go

-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package builder
1717

1818
import (
1919
"encoding/json"
20-
2120
"github.com/arduino/arduino-cli/legacy/builder/i18n"
2221
"github.com/arduino/arduino-cli/legacy/builder/types"
2322
)
@@ -30,7 +29,6 @@ func (s *CreateBuildOptionsMap) Run(ctx *types.Context) error {
3029
if err != nil {
3130
return i18n.WrapError(err)
3231
}
33-
3432
ctx.BuildOptionsJson = string(bytes)
3533

3634
return nil

legacy/builder/phases/core_builder.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package phases
1717

1818
import (
1919
"os"
20+
"strings"
2021

2122
"github.com/arduino/arduino-cli/legacy/builder/builder_utils"
2223
"github.com/arduino/arduino-cli/legacy/builder/constants"
@@ -90,7 +91,8 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path
9091

9192
var targetArchivedCore *paths.Path
9293
if buildCachePath != nil {
93-
archivedCoreName := builder_utils.GetCachedCoreArchiveFileName(buildProperties.Get(constants.BUILD_PROPERTIES_FQBN), realCoreFolder)
94+
archivedCoreName := GetCachedCoreArchiveFileName(buildProperties.Get(constants.BUILD_PROPERTIES_FQBN),
95+
buildProperties.Get("compiler.optimization_flags"), realCoreFolder)
9496
targetArchivedCore = buildCachePath.Join(archivedCoreName)
9597
canUseArchivedCore := !builder_utils.CoreOrReferencedCoreHasChanged(realCoreFolder, targetCoreFolder, targetArchivedCore)
9698

@@ -129,3 +131,20 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path
129131

130132
return archiveFile, variantObjectFiles, nil
131133
}
134+
135+
// GetCachedCoreArchiveFileName returns the filename to be used to store
136+
// the global cached core.a.
137+
func GetCachedCoreArchiveFileName(fqbn string, optimizationFlags string, coreFolder *paths.Path) string {
138+
fqbnToUnderscore := strings.Replace(fqbn, ":", "_", -1)
139+
fqbnToUnderscore = strings.Replace(fqbnToUnderscore, "=", "_", -1)
140+
if absCoreFolder, err := coreFolder.Abs(); err == nil {
141+
coreFolder = absCoreFolder
142+
} // silently continue if absolute path can't be detected
143+
hash := utils.MD5Sum([]byte(coreFolder.String() + optimizationFlags))
144+
realName := "core_" + fqbnToUnderscore + "_" + hash + ".a"
145+
if len(realName) > 100 {
146+
// avoid really long names, simply hash the final part
147+
realName = "core_" + utils.MD5Sum([]byte(fqbnToUnderscore+"_"+hash)) + ".a"
148+
}
149+
return realName
150+
}

legacy/builder/setup_build_properties.go

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ func (s *SetupBuildProperties) Run(ctx *types.Context) error {
6969
buildProperties.Set("ide_version", ctx.ArduinoAPIVersion)
7070
buildProperties.Set("runtime.os", utils.PrettyOSName())
7171

72+
if ctx.OptimizeForDebug {
73+
if buildProperties.ContainsKey("compiler.optimization_flags.debug") {
74+
buildProperties.Set("compiler.optimization_flags", buildProperties.Get("compiler.optimization_flags.debug"))
75+
}
76+
} else {
77+
if buildProperties.ContainsKey("compiler.optimization_flags.release") {
78+
buildProperties.Set("compiler.optimization_flags", buildProperties.Get("compiler.optimization_flags.release"))
79+
}
80+
}
81+
ctx.OptimizationFlags = buildProperties.Get("compiler.optimization_flags")
82+
7283
variant := buildProperties.Get("build.variant")
7384
if variant == "" {
7485
buildProperties.Set("build.variant.path", "")

legacy/builder/test/builder_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import (
2424
"github.com/arduino/go-paths-helper"
2525

2626
"github.com/arduino/arduino-cli/legacy/builder"
27-
"github.com/arduino/arduino-cli/legacy/builder/builder_utils"
2827
"github.com/arduino/arduino-cli/legacy/builder/constants"
28+
"github.com/arduino/arduino-cli/legacy/builder/phases"
2929
"github.com/arduino/arduino-cli/legacy/builder/types"
3030
"github.com/stretchr/testify/require"
3131
)
@@ -379,7 +379,7 @@ func TestBuilderCacheCoreAFile(t *testing.T) {
379379

380380
// Pick timestamp of cached core
381381
coreFolder := paths.New("downloaded_hardware", "arduino", "avr")
382-
coreFileName := builder_utils.GetCachedCoreArchiveFileName(ctx.FQBN.String(), coreFolder)
382+
coreFileName := phases.GetCachedCoreArchiveFileName(ctx.FQBN.String(), ctx.OptimizationFlags, coreFolder)
383383
cachedCoreFile := ctx.CoreBuildCachePath.Join(coreFileName)
384384
coreStatBefore, err := cachedCoreFile.Stat()
385385
require.NoError(t, err)

legacy/builder/test/create_build_options_map_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func TestCreateBuildOptionsMap(t *testing.T) {
3535
Verbose: true,
3636
BuildPath: paths.New("buildPath"),
3737
DebugLevel: 5,
38+
OptimizationFlags: "-Os",
3839
}
3940

4041
create := builder.CreateBuildOptionsMap{}
@@ -45,6 +46,7 @@ func TestCreateBuildOptionsMap(t *testing.T) {
4546
"additionalFiles": "",
4647
"builtInLibrariesFolders": "",
4748
"builtInToolsFolders": "tools",
49+
"compiler.optimization_flags": "-Os",
4850
"customBuildProperties": "",
4951
"fqbn": "my:nice:fqbn",
5052
"hardwareFolders": "hardware,hardware2",

legacy/builder/test/store_build_options_map_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func TestStoreBuildOptionsMap(t *testing.T) {
3737
CustomBuildProperties: []string{"custom=prop"},
3838
Verbose: true,
3939
DebugLevel: 5,
40+
OptimizationFlags: "-Os",
4041
}
4142

4243
buildPath := SetupBuildPath(t, ctx)
@@ -63,6 +64,7 @@ func TestStoreBuildOptionsMap(t *testing.T) {
6364
"additionalFiles": "",
6465
"builtInLibrariesFolders": "built-in libraries",
6566
"builtInToolsFolders": "tools",
67+
"compiler.optimization_flags": "-Os",
6668
"customBuildProperties": "custom=prop",
6769
"fqbn": "my:nice:fqbn",
6870
"hardwareFolders": "hardware",

legacy/builder/types/context.go

+6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ type Context struct {
9494
Verbose bool
9595
DebugPreprocessor bool
9696

97+
// Compile optimization settings
98+
OptimizeForDebug bool
99+
OptimizationFlags string
100+
97101
// Dry run, only create progress map
98102
Progress ProgressStruct
99103

@@ -140,6 +144,7 @@ func (ctx *Context) ExtractBuildOptions() *properties.Map {
140144
opts.Set("runtime.ide.version", ctx.ArduinoAPIVersion)
141145
opts.Set("customBuildProperties", strings.Join(ctx.CustomBuildProperties, ","))
142146
opts.Set("additionalFiles", strings.Join(additionalFilesRelative, ","))
147+
opts.Set("compiler.optimization_flags", ctx.OptimizationFlags)
143148
return opts
144149
}
145150

@@ -156,6 +161,7 @@ func (ctx *Context) InjectBuildOptions(opts *properties.Map) {
156161
ctx.FQBN = fqbn
157162
ctx.ArduinoAPIVersion = opts.Get("runtime.ide.version")
158163
ctx.CustomBuildProperties = strings.Split(opts.Get("customBuildProperties"), ",")
164+
ctx.OptimizationFlags = opts.Get("compiler.optimization_flags")
159165
}
160166

161167
func (ctx *Context) GetLogger() i18n.Logger {

rpc/commands/compile.pb.go

+36-27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rpc/commands/compile.proto

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ message CompileReq {
3737
string exportFile = 13; // The compiled binary is written to this file
3838
int32 jobs = 14; // The max number of concurrent compiler instances to run (as make -jx)
3939
repeated string libraries = 15; // List of custom libraries paths separated by commas. Or can be used multiple times for multiple libraries paths.
40+
bool optimizeForDebug = 16; // Optimize compile output for debug, not for release
4041
}
4142

4243
message CompileResp {

rpc/debug/debug.pb.go

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)