Skip to content

[EXPERIMENTAL] RPC support + paraller compilation + arduino-preprocessor #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 69 commits into from
May 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
97e56c4
First experiments with arduino-preprocessor
cmaglie Apr 18, 2017
7ca217b
Added code-completion support
cmaglie May 6, 2017
f8e1038
Updated tools for arduino-preprocessor
cmaglie Jun 7, 2017
d3759d7
Export CMake project if the build is successfull
facchinm May 8, 2017
2fecce3
restrict cmake project generation to platforms declaring compiler.exp…
facchinm Jun 14, 2017
471ff97
update arduino-preprocessor to 0.1.1
cmaglie Jun 25, 2017
007cfcf
add OSX and LinuxARM builds
facchinm Aug 3, 2017
6c60c47
change windows target (final trigger)
facchinm Aug 3, 2017
3d06ecf
Parallel compiling: arduino-builder will leverage your multi core pc
copercini Aug 14, 2017
9521522
First experiments with RPC
facchinm Sep 15, 2017
f9e1acb
cleanup needed ctx sections between runs
facchinm Sep 15, 2017
7c70931
Implement autocomplete endpoint
facchinm Sep 15, 2017
cab702e
Initial implementation using grps with streaming capabilities
facchinm Sep 18, 2017
758c3ec
add working watcher implementation
facchinm Sep 19, 2017
ea2e91b
Use relative paths if commandline is too long
facchinm Sep 25, 2017
361953f
Don't try spawining more than one daemonized builder
facchinm Oct 5, 2017
e330052
update to arduino-preprocessor 0.1.3
facchinm Oct 5, 2017
253195c
remove debug print
facchinm Oct 5, 2017
db0055f
Don't try to absolutize the filepath if empty
facchinm Oct 6, 2017
52e78fc
[WIN] make filepath relative to overcome parsing difficulties
facchinm Oct 9, 2017
44e6d73
[WIN] USe cross-compiled arduino-preprocessor
facchinm Oct 9, 2017
b4be062
Mute log output during autocomplete via rpc
facchinm Oct 12, 2017
dcce66b
Add NormalizeUTF8 utility function
facchinm Oct 13, 2017
7de76a9
[WIN] Launch arduino-preprocessor from volume name path
facchinm Oct 13, 2017
0dae510
Mute ctx.SourceGccMinusE if empty
facchinm Oct 13, 2017
ae6b635
Normalize preprocessed output
facchinm Oct 16, 2017
d9f55b4
Remove watcher, add endpoint to explicitely drop cache
facchinm Oct 18, 2017
de716ee
Fix cmake generation for difficult targets
facchinm Oct 19, 2017
e2e9471
Lower max commandline length bound
facchinm Oct 20, 2017
a888c62
[CMAKE] export only preprocessed source
facchinm Oct 31, 2017
15baf78
[CMAKE] use single group for all libraries
facchinm Oct 31, 2017
e7600b5
[CMAKE] include Arduino.h in main sketch file
facchinm Oct 31, 2017
140e24f
Fix past-end-of-cache handling in includeCache.ExpectFile
matthijskooijman Jun 6, 2017
85c5781
Convert IncludesFinderWithRegExp to a normal function
matthijskooijman Jun 6, 2017
39e3c84
Convert GCCPreprocRunner(ForDiscoveringIncludes) to a normal function
matthijskooijman Jun 6, 2017
652f830
Refactor path generation for ctags_target_for_gcc_minus_e.cpp
matthijskooijman Jun 6, 2017
edff07d
Pass FileToRead to ReadFileAndStoreInContext explicitly
matthijskooijman Jun 6, 2017
b6b8a83
Remove GCCPreprocSourceSaver
matthijskooijman Jun 6, 2017
e56a5f5
execSizeRecipe: Fix typo in method name
matthijskooijman Jun 16, 2017
b3106c0
Pass types.Context down into compilation helpers
matthijskooijman Jun 16, 2017
59d3251
Show the sizer commandline in verbose mode
matthijskooijman Jun 16, 2017
79afcb6
Show stdout of preproc commands in verbose mode
matthijskooijman Jun 16, 2017
deaed66
Do not ignore command errors in ExecRecipeCollectStdErr
matthijskooijman Jun 16, 2017
8563553
Let ExecRecipeCollectStdErr return []byte for stderr
matthijskooijman Jun 16, 2017
fcc9c5d
Improve error handling in include detection
matthijskooijman Jun 16, 2017
8ec1f02
Merge ExecRecipeCollectStdErr into ExecRecipe
matthijskooijman Jun 16, 2017
4f014d1
Merge some duplicate code into prepareGCCPreprocRecipeProperties
matthijskooijman Jun 16, 2017
5549e8a
Let utils.ExecCommand print the command in verbose mode
matthijskooijman Jun 16, 2017
417b6af
Fix removal of -MMD option when running the preprocessor
matthijskooijman Jun 16, 2017
36b60f5
Pass Context to ObjFileIsUpToDate
matthijskooijman Nov 30, 2017
fc9a824
Let ObjFileIsUpToDate output verbose debug output
matthijskooijman Mar 2, 2017
cfc4fd0
ContainerFindIncludes: Add some temporary variables
matthijskooijman Mar 2, 2017
70f45cc
Fix merge conflicts
facchinm Jan 10, 2018
2fc66f3
update arduino-preprocessor to 0.1.4
facchinm Dec 13, 2017
a32d158
Make progress smoother
facchinm Jan 23, 2018
99397e2
Fix Travis build if new dependencies are added
facchinm Jan 23, 2018
17e7af2
Fix import in example grpc client
facchinm Jan 23, 2018
243b313
Print ExecCommand cmdline only once with proper escape
facchinm Jan 23, 2018
571b922
Use absolute filepath for preprocessed cpp
facchinm Jan 23, 2018
849faa1
Wipe build directory if any additional file has been added/removed fr…
facchinm Jan 24, 2018
9b0a81a
Wipe build dir only if txt build rules has changed
facchinm Jan 24, 2018
9b7af5e
update arduino-preprocessor to 0.1.5
facchinm Jan 24, 2018
748c70d
Revert "[CMAKE] include Arduino.h in main sketch file"
facchinm Jan 24, 2018
eab9474
sort objectFiles slice alphabetically
Rocketct Mar 14, 2018
b324f9b
Merge pull request #1 from Rocketct/rpc_experiments
facchinm Mar 14, 2018
ffe9669
Introduce compiler.libraries.ldflags
facchinm Apr 12, 2018
2b1cfdd
Add runtime.ide.path env variable
facchinm Apr 20, 2018
55251c5
Move arduino-proprocessor under experimental flag
facchinm May 22, 2018
14b777f
Allow multiple precompiled libraries to be included and linked
facchinm May 30, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ install:
- go get github.com/arduino/go-timeutils

script:
- go get github.com/arduino/arduino-builder/arduino-builder
- go build -o $HOME/arduino-builder -v github.com/arduino/arduino-builder/arduino-builder
- export TEST_PACKAGES=`go list github.com/arduino/arduino-builder/...`
- RES=0; I=0; for PKG in $TEST_PACKAGES; do go test -v -timeout 30m -covermode=count -coverprofile=coverage.$I.out $PKG; ((RES=RES+$?)); ((I++)); done; ( exit $RES )
Expand Down
67 changes: 66 additions & 1 deletion arduino-builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@ import (
"io/ioutil"
"os"
"os/exec"
"runtime"
"strings"
"syscall"

"runtime/pprof"
"runtime/trace"

"github.com/arduino/arduino-builder"
"github.com/arduino/arduino-builder/gohasissues"
"github.com/arduino/arduino-builder/grpc"
"github.com/arduino/arduino-builder/i18n"
"github.com/arduino/arduino-builder/types"
"github.com/arduino/arduino-builder/utils"
Expand All @@ -54,6 +59,7 @@ const VERSION = "1.3.25"
const FLAG_ACTION_COMPILE = "compile"
const FLAG_ACTION_PREPROCESS = "preprocess"
const FLAG_ACTION_DUMP_PREFS = "dump-prefs"
const FLAG_ACTION_CODE_COMPLETE_AT = "code-complete-at"
const FLAG_BUILD_OPTIONS_FILE = "build-options-file"
const FLAG_HARDWARE = "hardware"
const FLAG_TOOLS = "tools"
Expand All @@ -78,7 +84,11 @@ const FLAG_LOGGER_HUMAN = "human"
const FLAG_LOGGER_HUMANTAGS = "humantags"
const FLAG_LOGGER_MACHINE = "machine"
const FLAG_VERSION = "version"
const FLAG_DAEMON = "daemon"
const FLAG_VID_PID = "vid-pid"
const FLAG_JOBS = "jobs"
const FLAG_TRACE = "trace"
const FLAG_EXPERIMENTAL = "experimental"

type foldersFlag []string

Expand Down Expand Up @@ -118,6 +128,7 @@ func (h *propertiesFlag) Set(value string) error {
var compileFlag *bool
var preprocessFlag *bool
var dumpPrefsFlag *bool
var codeCompleteAtFlag *string
var buildOptionsFileFlag *string
var hardwareFoldersFlag foldersFlag
var toolsFoldersFlag foldersFlag
Expand All @@ -135,12 +146,17 @@ var debugLevelFlag *int
var warningsLevelFlag *string
var loggerFlag *string
var versionFlag *bool
var daemonFlag *bool
var vidPidFlag *string
var jobsFlag *int
var traceFlag *bool
var experimentalFeatures *bool

func init() {
compileFlag = flag.Bool(FLAG_ACTION_COMPILE, false, "compiles the given sketch")
preprocessFlag = flag.Bool(FLAG_ACTION_PREPROCESS, false, "preprocess the given sketch")
dumpPrefsFlag = flag.Bool(FLAG_ACTION_DUMP_PREFS, false, "dumps build properties used when compiling")
codeCompleteAtFlag = flag.String(FLAG_ACTION_CODE_COMPLETE_AT, "", "output code completions for sketch at a specific location. Location format is \"file:line:col\"")
buildOptionsFileFlag = flag.String(FLAG_BUILD_OPTIONS_FILE, "", "Instead of specifying --"+FLAG_HARDWARE+", --"+FLAG_TOOLS+" etc every time, you can load all such options from a file")
flag.Var(&hardwareFoldersFlag, FLAG_HARDWARE, "Specify a 'hardware' folder. Can be added multiple times for specifying multiple 'hardware' folders")
flag.Var(&toolsFoldersFlag, FLAG_TOOLS, "Specify a 'tools' folder. Can be added multiple times for specifying multiple 'tools' folders")
Expand All @@ -158,12 +174,40 @@ func init() {
warningsLevelFlag = flag.String(FLAG_WARNINGS, "", "Sets warnings level. Available values are '"+FLAG_WARNINGS_NONE+"', '"+FLAG_WARNINGS_DEFAULT+"', '"+FLAG_WARNINGS_MORE+"' and '"+FLAG_WARNINGS_ALL+"'")
loggerFlag = flag.String(FLAG_LOGGER, FLAG_LOGGER_HUMAN, "Sets type of logger. Available values are '"+FLAG_LOGGER_HUMAN+"', '"+FLAG_LOGGER_HUMANTAGS+"', '"+FLAG_LOGGER_MACHINE+"'")
versionFlag = flag.Bool(FLAG_VERSION, false, "prints version and exits")
daemonFlag = flag.Bool(FLAG_DAEMON, false, "daemonizes and serves its functions via rpc")
vidPidFlag = flag.String(FLAG_VID_PID, "", "specify to use vid/pid specific build properties, as defined in boards.txt")
jobsFlag = flag.Int(FLAG_JOBS, 0, "specify how many concurrent gcc processes should run at the same time. Defaults to the number of available cores on the running machine")
traceFlag = flag.Bool(FLAG_TRACE, false, "traces the whole process lifecycle")
experimentalFeatures = flag.Bool(FLAG_EXPERIMENTAL, false, "enables experimental features")
}

func main() {

flag.Parse()

if *traceFlag {
f, err := os.Create("trace.out")
if err != nil {
panic(err)
}
defer f.Close()

f2, err := os.Create("profile.out")
if err != nil {
panic(err)
}
defer f2.Close()

pprof.StartCPUProfile(f2)
defer pprof.StopCPUProfile()

err = trace.Start(f)
if err != nil {
panic(err)
}
defer trace.Stop()
}

if *versionFlag {
fmt.Println("Arduino Builder " + VERSION)
fmt.Println("Copyright (C) 2015 Arduino LLC and contributors")
Expand All @@ -173,8 +217,28 @@ func main() {
return
}

if *jobsFlag > 0 {
runtime.GOMAXPROCS(*jobsFlag)
} else {
runtime.GOMAXPROCS(runtime.NumCPU())
}

ctx := &types.Context{}

// place here all experimental features that should live under this flag
if *experimentalFeatures {
ctx.UseArduinoPreprocessor = true
}

if *daemonFlag {
var loggerBuffer []string
logger := i18n.AccumulatorLogger{}
logger.Buffer = &loggerBuffer
//logger := i18n.HumanLogger{}
ctx.SetLogger(logger)
jsonrpc.RegisterAndServeJsonRPC(ctx)
}

if *buildOptionsFileFlag != "" {
buildOptions := make(properties.Map)
if _, err := os.Stat(*buildOptionsFileFlag); err == nil {
Expand Down Expand Up @@ -330,7 +394,8 @@ func main() {

if *dumpPrefsFlag {
err = builder.RunParseHardwareAndDumpBuildProperties(ctx)
} else if *preprocessFlag {
} else if *preprocessFlag || *codeCompleteAtFlag != "" {
ctx.CodeCompleteAt = *codeCompleteAtFlag
err = builder.RunPreprocess(ctx)
} else {
if flag.NArg() == 0 {
Expand Down
43 changes: 22 additions & 21 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"strconv"
"time"

"github.com/arduino/arduino-builder/builder_utils"
"github.com/arduino/arduino-builder/constants"
"github.com/arduino/arduino-builder/i18n"
"github.com/arduino/arduino-builder/phases"
Expand Down Expand Up @@ -89,7 +90,7 @@ func (s *Builder) Run(ctx *types.Context) error {
&WarnAboutArchIncompatibleLibraries{},

utils.LogIfVerbose(constants.LOG_LEVEL_INFO, "Generating function prototypes..."),
&ContainerAddPrototypes{},
&PreprocessSketch{},

utils.LogIfVerbose(constants.LOG_LEVEL_INFO, "Compiling sketch..."),
&RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_SKETCH_PREBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX},
Expand Down Expand Up @@ -128,6 +129,8 @@ func (s *Builder) Run(ctx *types.Context) error {

&PrintUsedLibrariesIfVerbose{},

&ExportProjectCMake{SketchError: mainErr != nil},

&phases.Sizer{SketchError: mainErr != nil},
}
otherErr := runCommands(ctx, commands, false)
Expand All @@ -139,6 +142,18 @@ func (s *Builder) Run(ctx *types.Context) error {
return otherErr
}

type PreprocessSketch struct{}

func (s *PreprocessSketch) Run(ctx *types.Context) error {
var commands []types.Command
if ctx.UseArduinoPreprocessor {
commands = append(commands, &PreprocessSketchArduino{})
} else {
commands = append(commands, &ContainerAddPrototypes{})
}
return runCommands(ctx, commands, true)
}

type Preprocess struct{}

func (s *Preprocess) Run(ctx *types.Context) error {
Expand All @@ -158,7 +173,7 @@ func (s *Preprocess) Run(ctx *types.Context) error {

&WarnAboutArchIncompatibleLibraries{},

&ContainerAddPrototypes{},
&PreprocessSketch{},

&PrintPreprocessedSource{},
}
Expand All @@ -181,36 +196,22 @@ func (s *ParseHardwareAndDumpBuildProperties) Run(ctx *types.Context) error {
}

func runCommands(ctx *types.Context, commands []types.Command, progressEnabled bool) error {
commandsLength := len(commands)
progressForEachCommand := float32(100) / float32(commandsLength)

progress := float32(0)
ctx.Progress.PrintEnabled = progressEnabled
ctx.Progress.Progress = 0

for _, command := range commands {
PrintRingNameIfDebug(ctx, command)
printProgressIfProgressEnabledAndMachineLogger(progressEnabled, ctx, progress)
ctx.Progress.Steps = 100.0 / float64(len(commands))
builder_utils.PrintProgressIfProgressEnabledAndMachineLogger(ctx)
err := command.Run(ctx)
if err != nil {
return i18n.WrapError(err)
}
progress += progressForEachCommand
}

printProgressIfProgressEnabledAndMachineLogger(progressEnabled, ctx, 100)

return nil
}

func printProgressIfProgressEnabledAndMachineLogger(progressEnabled bool, ctx *types.Context, progress float32) {
if !progressEnabled {
return
}

log := ctx.GetLogger()
if log.Name() == "machine" {
log.Println(constants.LOG_LEVEL_INFO, constants.MSG_PROGRESS, strconv.FormatFloat(float64(progress), 'f', 2, 32))
}
}

func PrintRingNameIfDebug(ctx *types.Context, command types.Command) {
if ctx.DebugLevel >= 10 {
ctx.GetLogger().Fprintln(os.Stdout, constants.LOG_LEVEL_DEBUG, constants.MSG_RUNNING_COMMAND, strconv.FormatInt(time.Now().Unix(), 10), reflect.Indirect(reflect.ValueOf(command)).Type().Name())
Expand Down
Loading