@@ -13,7 +13,7 @@ import (
13
13
"github.com/pkg/errors"
14
14
)
15
15
16
- func generateCpp (inoCode []byte , name , fqbn string ) (cppPath string , cppCode []byte , err error ) {
16
+ func generateCpp (inoCode []byte , sourcePath , fqbn string ) (cppPath string , cppCode []byte , err error ) {
17
17
rawTempDir , err := ioutil .TempDir ("" , "ino2cpp-" )
18
18
if err != nil {
19
19
err = errors .Wrap (err , "Error while creating temporary directory." )
@@ -26,6 +26,7 @@ func generateCpp(inoCode []byte, name, fqbn string) (cppPath string, cppCode []b
26
26
}
27
27
28
28
// Write source file to temp dir
29
+ name := filepath .Base (sourcePath )
29
30
if ! strings .HasSuffix (name , ".ino" ) {
30
31
name += ".ino"
31
32
}
@@ -41,7 +42,7 @@ func generateCpp(inoCode []byte, name, fqbn string) (cppPath string, cppCode []b
41
42
42
43
// Generate compile_flags.txt
43
44
cppPath = filepath .Join (tempDir , name + ".cpp" )
44
- flagsPath , err := generateCompileFlags (tempDir , inoPath , fqbn )
45
+ flagsPath , err := generateCompileFlags (tempDir , inoPath , sourcePath , fqbn )
45
46
if err != nil {
46
47
return
47
48
}
@@ -54,7 +55,7 @@ func generateCpp(inoCode []byte, name, fqbn string) (cppPath string, cppCode []b
54
55
return
55
56
}
56
57
57
- func updateCpp (inoCode []byte , fqbn string , fqbnChanged bool , cppPath string ) (cppCode []byte , err error ) {
58
+ func updateCpp (inoCode []byte , sourcePath , fqbn string , fqbnChanged bool , cppPath string ) (cppCode []byte , err error ) {
58
59
tempDir := filepath .Dir (cppPath )
59
60
inoPath := strings .TrimSuffix (cppPath , ".cpp" )
60
61
if inoCode != nil {
@@ -64,22 +65,29 @@ func updateCpp(inoCode []byte, fqbn string, fqbnChanged bool, cppPath string) (c
64
65
err = errors .Wrap (err , "Error while writing source file to temporary directory." )
65
66
return
66
67
}
68
+ if enableLogging {
69
+ log .Println ("Source file written to" , inoPath )
70
+ }
67
71
}
68
72
69
73
if fqbnChanged {
70
74
// Generate compile_flags.txt
71
- _ , err = generateCompileFlags (tempDir , inoPath , fqbn )
75
+ var flagsPath string
76
+ flagsPath , err = generateCompileFlags (tempDir , inoPath , sourcePath , fqbn )
72
77
if err != nil {
73
78
return
74
79
}
80
+ if enableLogging {
81
+ log .Println ("Compile flags written to" , flagsPath )
82
+ }
75
83
}
76
84
77
85
// Generate target file
78
86
cppCode , err = generateTargetFile (tempDir , inoPath , cppPath , fqbn )
79
87
return
80
88
}
81
89
82
- func generateCompileFlags (tempDir , inoPath , fqbn string ) (string , error ) {
90
+ func generateCompileFlags (tempDir , inoPath , sourcePath , fqbn string ) (string , error ) {
83
91
var cliArgs []string
84
92
if len (fqbn ) > 0 {
85
93
cliArgs = []string {"compile" , "--fqbn" , fqbn , "--show-properties" , inoPath }
@@ -105,6 +113,7 @@ func generateCompileFlags(tempDir, inoPath, fqbn string) (string, error) {
105
113
106
114
printer := Printer {Writer : bufio .NewWriter (outFile )}
107
115
printCompileFlags (properties , & printer , fqbn )
116
+ printLibraryPaths (sourcePath , & printer )
108
117
printer .Flush ()
109
118
return flagsPath , printer .Err
110
119
}
@@ -154,33 +163,56 @@ func printCompileFlags(properties map[string]string, printer *Printer, fqbn stri
154
163
printer .Println ("--target=arm-none-eabi" )
155
164
}
156
165
cppFlags := expandProperty (properties , "compiler.cpp.flags" )
157
- printer .Println (strings . ReplaceAll (cppFlags , " " , " \n " ))
166
+ printer .Println (splitFlags (cppFlags ))
158
167
mcu := expandProperty (properties , "build.mcu" )
159
168
if strings .Contains (fqbn , ":avr:" ) {
160
- printer .Println ("-mmcu=" + mcu )
169
+ printer .Println ("-mmcu=" , mcu )
161
170
} else if strings .Contains (fqbn , ":sam:" ) {
162
- printer .Println ("-mcpu=" + mcu )
171
+ printer .Println ("-mcpu=" , mcu )
163
172
}
164
173
fcpu := expandProperty (properties , "build.f_cpu" )
165
- printer .Println ("-DF_CPU=" + fcpu )
174
+ printer .Println ("-DF_CPU=" , fcpu )
166
175
ideVersion := expandProperty (properties , "runtime.ide.version" )
167
- printer .Println ("-DARDUINO=" + ideVersion )
176
+ printer .Println ("-DARDUINO=" , ideVersion )
168
177
board := expandProperty (properties , "build.board" )
169
- printer .Println ("-DARDUINO_" + board )
178
+ printer .Println ("-DARDUINO_" , board )
170
179
arch := expandProperty (properties , "build.arch" )
171
- printer .Println ("-DARDUINO_ARCH_" + arch )
180
+ printer .Println ("-DARDUINO_ARCH_" , arch )
172
181
if strings .Contains (fqbn , ":sam:" ) {
173
182
libSamFlags := expandProperty (properties , "compiler.libsam.c.flags" )
174
- printer .Println (strings . ReplaceAll (libSamFlags , " " , " \n " ))
183
+ printer .Println (splitFlags (libSamFlags ))
175
184
}
176
185
extraFlags := expandProperty (properties , "build.extra_flags" )
177
- printer .Println (strings . ReplaceAll (extraFlags , " " , " \n " ))
186
+ printer .Println (splitFlags (extraFlags ))
178
187
corePath := expandProperty (properties , "build.core.path" )
179
- printer .Println ("-I" + corePath )
188
+ printer .Println ("-I" , corePath )
180
189
variantPath := expandProperty (properties , "build.variant.path" )
181
- printer .Println ("-I" + variantPath )
182
- avrgccPath := expandProperty (properties , "runtime.tools.avr-gcc.path" )
183
- printer .Println ("-I" + filepath .Join (avrgccPath , "avr" , "include" ))
190
+ printer .Println ("-I" , variantPath )
191
+ if strings .Contains (fqbn , ":avr:" ) {
192
+ avrgccPath := expandProperty (properties , "runtime.tools.avr-gcc.path" )
193
+ printer .Println ("-I" , filepath .Join (avrgccPath , "avr" , "include" ))
194
+ }
195
+
196
+ printLibraryPaths (corePath , printer )
197
+ }
198
+
199
+ func printLibraryPaths (basePath string , printer * Printer ) {
200
+ parentDir := filepath .Dir (basePath )
201
+ if strings .HasSuffix (parentDir , string (filepath .Separator )) || strings .HasSuffix (parentDir , "." ) {
202
+ return
203
+ }
204
+ libsDir := filepath .Join (parentDir , "libraries" )
205
+ if libraries , err := ioutil .ReadDir (libsDir ); err == nil {
206
+ for _ , libInfo := range libraries {
207
+ if libInfo .IsDir () {
208
+ srcDir := filepath .Join (libsDir , libInfo .Name (), "src" )
209
+ if srcInfo , err := os .Stat (srcDir ); err == nil && srcInfo .IsDir () {
210
+ printer .Println ("-I" , srcDir )
211
+ }
212
+ }
213
+ }
214
+ }
215
+ printLibraryPaths (parentDir , printer )
184
216
}
185
217
186
218
// Printer prints to a Writer and stores the first error.
@@ -189,10 +221,20 @@ type Printer struct {
189
221
Err error
190
222
}
191
223
192
- // Println prints the given text followed by a line break.
193
- func (printer * Printer ) Println (text string ) {
194
- if len (text ) > 0 {
195
- _ , err := printer .Writer .WriteString (text + "\n " )
224
+ // Println prints the given strings followed by a line break.
225
+ func (printer * Printer ) Println (text ... string ) {
226
+ totalLen := 0
227
+ for i := range text {
228
+ if len (text [i ]) > 0 {
229
+ _ , err := printer .Writer .WriteString (text [i ])
230
+ if err != nil && printer .Err == nil {
231
+ printer .Err = err
232
+ }
233
+ totalLen += len (text [i ])
234
+ }
235
+ }
236
+ if totalLen > 0 {
237
+ _ , err := printer .Writer .WriteString ("\n " )
196
238
if err != nil && printer .Err == nil {
197
239
printer .Err = err
198
240
}
@@ -207,6 +249,27 @@ func (printer *Printer) Flush() {
207
249
}
208
250
}
209
251
252
+ func splitFlags (flags string ) string {
253
+ flagsBytes := []byte (flags )
254
+ result := make ([]byte , len (flagsBytes ))
255
+ inSingleQuotes := false
256
+ inDoubleQuotes := false
257
+ for i , b := range flagsBytes {
258
+ if b == '\'' && ! inDoubleQuotes {
259
+ inSingleQuotes = ! inSingleQuotes
260
+ }
261
+ if b == '"' && ! inSingleQuotes {
262
+ inDoubleQuotes = ! inDoubleQuotes
263
+ }
264
+ if b == ' ' && ! inSingleQuotes && ! inDoubleQuotes {
265
+ result [i ] = '\n'
266
+ } else {
267
+ result [i ] = b
268
+ }
269
+ }
270
+ return string (result )
271
+ }
272
+
210
273
func logCommandErr (command string , stdout []byte , err error , filter func (string ) string ) error {
211
274
message := ""
212
275
log .Println ("Command error:" , command , err )
0 commit comments