Skip to content

Commit c9da4cc

Browse files
committed
Implemented arduino compile command.
1 parent 456b9c5 commit c9da4cc

File tree

4 files changed

+201
-22
lines changed

4 files changed

+201
-22
lines changed

cmd/arduino.go

+34-21
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,28 @@ import (
5757

5858
const (
5959
bashAutoCompletionFunction = `
60-
__arduino_autocomplete()
61-
{
62-
case $(last_command) in
63-
arduino)
64-
opts="lib core help version"
65-
;;
66-
arduino_lib)
67-
opts="install uninstall list search version --update-index"
68-
;;
60+
__arduino_autocomplete()
61+
{
62+
case $(last_command) in
63+
arduino)
64+
opts="lib core help version"
65+
;;
66+
arduino_lib)
67+
opts="install uninstall list search version --update-index"
68+
;;
6969
arduino_core)
70-
opts="install uninstall list search version --update-index"
70+
opts="install uninstall list search version --update-index"
7171
;;
72-
arduino_help)
73-
opts="lib core version"
74-
;;
75-
esac
76-
if [[ ${cur} == " *" ]] ; then
77-
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
78-
return 0
79-
fi
80-
return 1
81-
}`
72+
arduino_help)
73+
opts="lib core version"
74+
;;
75+
esac
76+
if [[ ${cur} == " *" ]] ; then
77+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
78+
return 0
79+
fi
80+
return 1
81+
}`
8282

8383
// ArduinoVersion represents Arduino CLI version number.
8484
ArduinoVersion = "0.1.0-alpha.preview"
@@ -170,6 +170,7 @@ func InitFlags() {
170170

171171
arduinoSketchSyncCmd.ResetFlags()
172172
arduinoLoginCmd.ResetFlags()
173+
arduinoCompileCmd.ResetFlags()
173174

174175
ArduinoCmd.PersistentFlags().BoolVar(&GlobalFlags.Debug, "debug", false, "enables debug output (super verbose, used to debug the CLI)")
175176

@@ -198,6 +199,17 @@ func InitFlags() {
198199
arduinoSketchSyncCmd.Flags().StringVar(&arduinoSketchSyncFlags.Priority, "conflict-policy", "skip", "The decision made by default on conflicting sketches. Can be push-local, pull-remote, skip, ask-once, ask-always.")
199200
arduinoLoginCmd.Flags().StringVarP(&arduinoLoginFlags.User, "user", "u", "", "The username used to log in")
200201
arduinoLoginCmd.Flags().StringVarP(&arduinoLoginFlags.Password, "password", "p", "", "The username used to log in")
202+
203+
arduinoCompileCmd.Flags().StringVarP(&arduinoCompileFlags.FullyQualifiedBoardName, "fqbn", "b", "", "Fully Qualified Board Name, e.g.: arduino:avr:uno")
204+
arduinoCompileCmd.Flags().StringVarP(&arduinoCompileFlags.SketchName, "sketch", "s", "", "The Name of the sketch to compile.")
205+
arduinoCompileCmd.Flags().BoolVar(&arduinoCompileFlags.DumpPreferences, "dump-prefs", false, "Show all build preferences used instead of compiling.")
206+
arduinoCompileCmd.Flags().BoolVar(&arduinoCompileFlags.Preprocess, "preprocess", false, "Print preprocessed code to stdout instead of compiling.")
207+
arduinoCompileCmd.Flags().StringVar(&arduinoCompileFlags.BuildPath, "build-path", "", "Folder where to save compiled files. If omitted, a folder will be created in the temporary folder specified by your OS.")
208+
arduinoCompileCmd.Flags().StringVar(&arduinoCompileFlags.Warnings, "warnings", "none", `Optional, can be "none", "default", "more" and "all". Defaults to "none". Used to tell gcc which warning level to use (-W flag).`)
209+
arduinoCompileCmd.Flags().BoolVar(&arduinoCompileFlags.Verbose, "verbose", false, "Optional, turns on verbose mode.")
210+
arduinoCompileCmd.Flags().BoolVar(&arduinoCompileFlags.Quiet, "quiet", false, "Optional, supresses almost every output.")
211+
arduinoCompileCmd.Flags().IntVar(&arduinoCompileFlags.DebugLevel, "debug-level", 5, "Optional, defaults to 5. Used for debugging. Set it to 10 when submitting an issue.")
212+
arduinoCompileCmd.Flags().StringVar(&arduinoCompileFlags.VidPid, "vid-pid", "", "When specified, VID/PID specific build properties are used, if boards supports them.")
201213
}
202214

203215
// InitCommands reinitialize commands (useful for testing too)
@@ -208,9 +220,10 @@ func InitCommands() {
208220
arduinoConfigCmd.ResetCommands()
209221
arduinoBoardCmd.ResetCommands()
210222
arduinoSketchCmd.ResetCommands()
223+
arduinoCompileCmd.ResetCommands()
211224

212225
ArduinoCmd.AddCommand(arduinoVersionCmd, arduinoLibCmd, arduinoCoreCmd, arduinoConfigCmd,
213-
arduinoBoardCmd, arduinoSketchCmd, arduinoLoginCmd)
226+
arduinoBoardCmd, arduinoSketchCmd, arduinoLoginCmd, arduinoCompileCmd)
214227

215228
arduinoLibCmd.AddCommand(arduinoLibInstallCmd, arduinoLibUninstallCmd, arduinoLibSearchCmd,
216229
arduinoLibVersionCmd, arduinoLibListCmd, arduinoLibDownloadCmd)

cmd/arduino_compile.go

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* This file is part of arduino-cli.
3+
*
4+
* arduino-cli is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*
18+
* As a special exception, you may use this file as part of a free software
19+
* library without restriction. Specifically, if other files instantiate
20+
* templates or use macros or inline functions from this file, or you compile
21+
* this file and link it with other files to produce an executable, this
22+
* file does not by itself cause the resulting executable to be covered by
23+
* the GNU General Public License. This exception does not however
24+
* invalidate any other reasons why the executable file might be covered by
25+
* the GNU General Public License.
26+
*
27+
* Copyright 2017 ARDUINO AG (http://www.arduino.cc/)
28+
*/
29+
30+
package cmd
31+
32+
import (
33+
"os"
34+
"path/filepath"
35+
"strings"
36+
37+
builder "github.com/arduino/arduino-builder"
38+
"github.com/arduino/arduino-builder/types"
39+
"github.com/arduino/arduino-builder/utils"
40+
"github.com/bcmi-labs/arduino-cli/cmd/formatter"
41+
"github.com/bcmi-labs/arduino-cli/common"
42+
"github.com/sirupsen/logrus"
43+
"github.com/spf13/cobra"
44+
)
45+
46+
var arduinoCompileCmd = &cobra.Command{
47+
Use: `compile`,
48+
Short: `Compiles Arduino sketches`,
49+
Long: `Compiles Arduino sketches`,
50+
Example: `arduino compile --fqbn arduino:avr:uno --sketch mySketch`,
51+
Args: cobra.NoArgs,
52+
Run: executeCompileCommand,
53+
}
54+
55+
// TODO: convert required flags to arguments, install ctags and core if missing
56+
func executeCompileCommand(cmd *cobra.Command, args []string) {
57+
logrus.Info("Executing `arduino compile`")
58+
isCorrectSyntax := true
59+
if arduinoCompileFlags.SketchName == "" {
60+
formatter.PrintErrorMessage("No sketch name provided")
61+
isCorrectSyntax = false
62+
}
63+
var packageName string
64+
if arduinoCompileFlags.FullyQualifiedBoardName == "" {
65+
formatter.PrintErrorMessage("No Fully Qualified Board Name provided")
66+
isCorrectSyntax = false
67+
} else {
68+
fqbnParts := strings.Split(arduinoCompileFlags.FullyQualifiedBoardName, ":")
69+
if len(fqbnParts) != 3 {
70+
formatter.PrintErrorMessage("Fully Qualified Board Name has incorrect format")
71+
isCorrectSyntax = false
72+
} else {
73+
packageName = fqbnParts[0]
74+
}
75+
}
76+
if !isCorrectSyntax {
77+
os.Exit(errBadCall)
78+
}
79+
80+
ctx := &types.Context{}
81+
82+
ctx.FQBN = arduinoCompileFlags.FullyQualifiedBoardName
83+
ctx.SketchLocation = filepath.Join(common.SketchbookFolder, arduinoCompileFlags.SketchName)
84+
85+
packagesFolder, err := common.GetDefaultPkgFolder()
86+
if err != nil {
87+
formatter.PrintError(err, "Cannot get packages folder")
88+
os.Exit(errCoreConfig)
89+
}
90+
ctx.HardwareFolders = []string{packagesFolder}
91+
92+
toolsFolder, err := common.GetDefaultToolsFolder(packageName)
93+
if err != nil {
94+
formatter.PrintError(err, "Cannot get tools folder")
95+
os.Exit(errCoreConfig)
96+
}
97+
ctx.ToolsFolders = []string{toolsFolder}
98+
99+
librariesFolder, err := common.GetDefaultLibFolder()
100+
if err != nil {
101+
formatter.PrintError(err, "Cannot get libraries folder")
102+
os.Exit(errCoreConfig)
103+
}
104+
ctx.OtherLibrariesFolders = []string{librariesFolder}
105+
106+
ctx.BuildPath = arduinoCompileFlags.BuildPath
107+
if ctx.BuildPath != "" {
108+
// TODO: Needed?
109+
/*_, err = os.Stat(ctx.BuildPath)
110+
if err != nil {
111+
fmt.Fprintln(os.Stderr, err)
112+
os.Exit(errBadCall)
113+
}*/
114+
115+
err = utils.EnsureFolderExists(ctx.BuildPath)
116+
if err != nil {
117+
formatter.PrintError(err, "Cannot create the build folder")
118+
os.Exit(errBadCall)
119+
}
120+
}
121+
122+
ctx.Verbose = arduinoCompileFlags.Verbose
123+
ctx.DebugLevel = arduinoCompileFlags.DebugLevel
124+
125+
ctx.USBVidPid = arduinoCompileFlags.VidPid
126+
ctx.WarningsLevel = arduinoCompileFlags.Warnings
127+
128+
// TODO:
129+
ctx.ArduinoAPIVersion = "10600"
130+
//ctx.BuiltInLibrariesFolders = ?
131+
//ctx.CustomBuildProperties = ?
132+
//ctx.BuildCachePath = ?
133+
134+
if arduinoCompileFlags.DumpPreferences {
135+
err = builder.RunParseHardwareAndDumpBuildProperties(ctx)
136+
} else if arduinoCompileFlags.Preprocess {
137+
err = builder.RunPreprocess(ctx)
138+
} else {
139+
err = builder.RunBuilder(ctx)
140+
}
141+
142+
if err != nil {
143+
formatter.PrintError(err, "Compilation failed")
144+
os.Exit(errGeneric)
145+
}
146+
}

cmd/flags.go

+14
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,17 @@ var arduinoLoginFlags struct {
9191
User string // The user who asks to login.
9292
Password string // The password used to authenticate.
9393
}
94+
95+
// arduinoCompileFlags represents `arduino compile` flags.
96+
var arduinoCompileFlags struct {
97+
FullyQualifiedBoardName string // Fully Qualified Board Name, e.g.: arduino:avr:uno.
98+
SketchName string // The name of the sketch to compile.
99+
DumpPreferences bool // Show all build preferences used instead of compiling.
100+
Preprocess bool // Print preprocessed code to stdout.
101+
BuildPath string // Folder where to save compiled files.
102+
Warnings string // Used to tell gcc which warning level to use.
103+
Verbose bool // Turns on verbose mode.
104+
Quiet bool // Supresses almost every output.
105+
DebugLevel int // Used for debugging.
106+
VidPid string // VID/PID specific build properties.
107+
}

cores/install_uninstall.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,13 @@ func InstallTool(packager, name string, release releases.Release) error {
171171
}
172172
defer file.Close()
173173

174-
err = extract.Archive(file, tempFolder, nil)
174+
// Ignore the top level directory inside archives. E.g. not "avr/bin/avr-g++"", but "bin/avr-g++"".
175+
var shift = func(path string) string {
176+
parts := strings.Split(path, string(filepath.Separator))
177+
parts = parts[1:]
178+
return strings.Join(parts, string(filepath.Separator))
179+
}
180+
err = extract.Archive(file, tempFolder, shift)
175181
if err != nil {
176182
return err
177183
}

0 commit comments

Comments
 (0)