amperka / ino

Command line toolkit for working with Arduino hardware
http://inotool.org
MIT License
1.08k stars 231 forks source link

Ino picks wrong dependency #134

Open nh2 opened 10 years ago

nh2 commented 10 years ago

I'm trying to compile a project that does an #include <SPI.h>.

In the dependency scan, ino picks the wrong library:

$ find /usr/share/arduino/libraries -name SPI.h:

/usr/share/arduino/libraries/Robot_Control/SPI.h
/usr/share/arduino/libraries/SPI/SPI.h

R comes before S, so ino concludes Robot_Control is depended on.

Maybe ino should issue a loud warning if two libraries expose the same header name.

mwhooker commented 10 years ago

got bit by this too, this time for Robot_Control/Wire.h vs Wire/Wire.h

mwhooker commented 10 years ago

the wrong dependency list is being generated by avr-gcc it looks like. This is because it's being given an over-broad include path, and avr-gcc just grabs the first match it finds.

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=105 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -ffunction-sections -fdata-sections -g -Os -w -DUSB_VID=0x2341 -DUSB_PID=0x8037 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants/micro -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/avr-libc -Ilib/Adafruit_NeoPixel -Ilib/I2Cdev -Ilib/MPU6050 -Ilib/MPU6050/Examples -Ilib/MPU6050/Examples/MPU6050_DMP6 -Ilib/MPU6050/Examples/MPU6050_raw -Ilib/MPU6050/Examples/MPU6050_DMP6/Processing -Ilib/MPU6050/Examples/MPU6050_DMP6/Processing -I/Applications/Arduino.app/Contents/Resources/Java/libraries/EEPROM -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Esplora -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Ethernet -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Ethernet/utility -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata -I/Applications/Arduino.app/Contents/Resources/Java/libraries/GSM -I/Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Robot_Control -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Robot_Control/utility -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Robot_Motor -I/Applications/Arduino.app/Contents/Resources/Java/libraries/SD -I/Applications/Arduino.app/Contents/Resources/Java/libraries/SD/utility -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Servo -I/Applications/Arduino.app/Contents/Resources/Java/libraries/SoftwareSerial -I/Applications/Arduino.app/Contents/Resources/Java/libraries/SPI -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Stepper -I/Applications/Arduino.app/Contents/Resources/Java/libraries/TFT -I/Applications/Arduino.app/Contents/Resources/Java/libraries/TFT/utility -I/Applications/Arduino.app/Contents/Resources/Java/libraries/WiFi -I/Applications/Arduino.app/Contents/Resources/Java/libraries/WiFi/utility -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Wire -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Wire/utility  -MM src/position.cpp
position.o: src/position.cpp src/position.h lib/I2Cdev/I2Cdev.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Arduino.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/binary.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WCharacter.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WString.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Printable.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/USBAPI.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants/micro/pins_arduino.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants/micro/../leonardo/pins_arduino.h \
  /Applications/Arduino.app/Contents/Resources/Java/libraries/Robot_Control/Wire.h \
  /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.h \
  lib/MPU6050/MPU6050_6Axis_MotionApps20.h lib/MPU6050/helper_3dmath.h \
  lib/MPU6050/MPU6050.h

Perhaps the solution is to allow the user to specify their own include paths. Just adding everything like that (besides core) seems like a recipe for trouble

I was able to work around this by applying this

diff --git a/ino/commands/build.py b/ino/commands/build.py
index 7aea046..df9fffe 100644
--- a/ino/commands/build.py
+++ b/ino/commands/build.py
@@ -275,7 +275,6 @@ class Build(Command):
                 scanned_libs.add(lib)

         self.e['used_libs'] = used_libs
-        self.e['cppflags'].extend(self.recursive_inc_lib_flags(used_libs))

     def run(self, args):
         self.discover(args)

and passing -f -I<the only libraries I need> to ino build

michaelsproul commented 10 years ago

I've written an Ino-like tool called Xuino that handles this correctly. It considers libraries as folders, and allows the user to manually specify dependencies between them.

https://github.com/gnusouth/xuino

zxalexis commented 10 years ago

mwhooker, I think it's not the right patch to fix this issue. The Wire.d file (dependencies) still contains Robot_Control/twi.h as a path. I thinks it's up to the fact that current subdirs in lib's dir must be scanned first PRIOR to search path. Dependant on lib currently scanned. So the logic of dependency scanner must be fixed.