@@ -13,7 +13,7 @@ import (
1313 "github.com/pkg/errors"
1414)
1515
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 ) {
1717 rawTempDir , err := ioutil .TempDir ("" , "ino2cpp-" )
1818 if err != nil {
1919 err = errors .Wrap (err , "Error while creating temporary directory." )
@@ -26,6 +26,7 @@ func generateCpp(inoCode []byte, name, fqbn string) (cppPath string, cppCode []b
2626 }
2727
2828 // Write source file to temp dir
29+ name := filepath .Base (sourcePath )
2930 if ! strings .HasSuffix (name , ".ino" ) {
3031 name += ".ino"
3132 }
@@ -41,7 +42,7 @@ func generateCpp(inoCode []byte, name, fqbn string) (cppPath string, cppCode []b
4142
4243 // Generate compile_flags.txt
4344 cppPath = filepath .Join (tempDir , name + ".cpp" )
44- flagsPath , err := generateCompileFlags (tempDir , inoPath , fqbn )
45+ flagsPath , err := generateCompileFlags (tempDir , inoPath , sourcePath , fqbn )
4546 if err != nil {
4647 return
4748 }
@@ -54,7 +55,7 @@ func generateCpp(inoCode []byte, name, fqbn string) (cppPath string, cppCode []b
5455 return
5556}
5657
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 ) {
5859 tempDir := filepath .Dir (cppPath )
5960 inoPath := strings .TrimSuffix (cppPath , ".cpp" )
6061 if inoCode != nil {
@@ -64,22 +65,29 @@ func updateCpp(inoCode []byte, fqbn string, fqbnChanged bool, cppPath string) (c
6465 err = errors .Wrap (err , "Error while writing source file to temporary directory." )
6566 return
6667 }
68+ if enableLogging {
69+ log .Println ("Source file written to" , inoPath )
70+ }
6771 }
6872
6973 if fqbnChanged {
7074 // Generate compile_flags.txt
71- _ , err = generateCompileFlags (tempDir , inoPath , fqbn )
75+ var flagsPath string
76+ flagsPath , err = generateCompileFlags (tempDir , inoPath , sourcePath , fqbn )
7277 if err != nil {
7378 return
7479 }
80+ if enableLogging {
81+ log .Println ("Compile flags written to" , flagsPath )
82+ }
7583 }
7684
7785 // Generate target file
7886 cppCode , err = generateTargetFile (tempDir , inoPath , cppPath , fqbn )
7987 return
8088}
8189
82- func generateCompileFlags (tempDir , inoPath , fqbn string ) (string , error ) {
90+ func generateCompileFlags (tempDir , inoPath , sourcePath , fqbn string ) (string , error ) {
8391 var cliArgs []string
8492 if len (fqbn ) > 0 {
8593 cliArgs = []string {"compile" , "--fqbn" , fqbn , "--show-properties" , inoPath }
@@ -105,6 +113,7 @@ func generateCompileFlags(tempDir, inoPath, fqbn string) (string, error) {
105113
106114 printer := Printer {Writer : bufio .NewWriter (outFile )}
107115 printCompileFlags (properties , & printer , fqbn )
116+ printLibraryPaths (sourcePath , & printer )
108117 printer .Flush ()
109118 return flagsPath , printer .Err
110119}
@@ -154,33 +163,56 @@ func printCompileFlags(properties map[string]string, printer *Printer, fqbn stri
154163 printer .Println ("--target=arm-none-eabi" )
155164 }
156165 cppFlags := expandProperty (properties , "compiler.cpp.flags" )
157- printer .Println (strings . ReplaceAll (cppFlags , " " , " \n " ))
166+ printer .Println (splitFlags (cppFlags ))
158167 mcu := expandProperty (properties , "build.mcu" )
159168 if strings .Contains (fqbn , ":avr:" ) {
160- printer .Println ("-mmcu=" + mcu )
169+ printer .Println ("-mmcu=" , mcu )
161170 } else if strings .Contains (fqbn , ":sam:" ) {
162- printer .Println ("-mcpu=" + mcu )
171+ printer .Println ("-mcpu=" , mcu )
163172 }
164173 fcpu := expandProperty (properties , "build.f_cpu" )
165- printer .Println ("-DF_CPU=" + fcpu )
174+ printer .Println ("-DF_CPU=" , fcpu )
166175 ideVersion := expandProperty (properties , "runtime.ide.version" )
167- printer .Println ("-DARDUINO=" + ideVersion )
176+ printer .Println ("-DARDUINO=" , ideVersion )
168177 board := expandProperty (properties , "build.board" )
169- printer .Println ("-DARDUINO_" + board )
178+ printer .Println ("-DARDUINO_" , board )
170179 arch := expandProperty (properties , "build.arch" )
171- printer .Println ("-DARDUINO_ARCH_" + arch )
180+ printer .Println ("-DARDUINO_ARCH_" , arch )
172181 if strings .Contains (fqbn , ":sam:" ) {
173182 libSamFlags := expandProperty (properties , "compiler.libsam.c.flags" )
174- printer .Println (strings . ReplaceAll (libSamFlags , " " , " \n " ))
183+ printer .Println (splitFlags (libSamFlags ))
175184 }
176185 extraFlags := expandProperty (properties , "build.extra_flags" )
177- printer .Println (strings . ReplaceAll (extraFlags , " " , " \n " ))
186+ printer .Println (splitFlags (extraFlags ))
178187 corePath := expandProperty (properties , "build.core.path" )
179- printer .Println ("-I" + corePath )
188+ printer .Println ("-I" , corePath )
180189 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 )
184216}
185217
186218// Printer prints to a Writer and stores the first error.
@@ -189,10 +221,20 @@ type Printer struct {
189221 Err error
190222}
191223
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 " )
196238 if err != nil && printer .Err == nil {
197239 printer .Err = err
198240 }
@@ -207,6 +249,27 @@ func (printer *Printer) Flush() {
207249 }
208250}
209251
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+
210273func logCommandErr (command string , stdout []byte , err error , filter func (string ) string ) error {
211274 message := ""
212275 log .Println ("Command error:" , command , err )
0 commit comments