sudar / Arduino-Makefile

Makefile for Arduino sketches. It defines the workflows for compiling code, flashing it to Arduino and even communicating through Serial.
http://hardwarefun.com/tutorials/compiling-arduino-sketches-using-makefile
GNU Lesser General Public License v2.1
2.02k stars 449 forks source link

Makefile miscompiles IRremote #376

Closed audetto closed 9 years ago

audetto commented 9 years ago

Hi,

I am trying to compile IRremote from

https://github.com/z3t0/Arduino-IRremote

with the Makefile

the Makefile I use is

BOARD_TAG=uno
ARDUINO_DIR=/home/andrea/projects/pi/ide/arduino-1.6.5
ARDUINO_SKETCHBOOK=/home/andrea/Arduino

include /home/andrea/projects/cvs/3rdParty/Arduino-Makefile/Arduino.mk

and the library IRremote is in /home/andrea/Arduino

the sketch is

#include <IRremote.h>

int RECV_PIN = 2;
int LED = A5;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  Serial.println("Here we are");
  delay(100);

  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);
  delay(100);

  irrecv.enableIRIn(); // Start the receiver
  delay(100);
}

void loop() {
  if (irrecv.decode(&results))
  {
    Serial.println(results.value, HEX);
    Serial.println(results.decode_type);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}

which is based on one of the examples of the library. But if I compile with the Makefile nothing works, with arduino 1.6.5 it is good. With the Makefile it compiles, links, uploads, but it is like some parts of the code are not there.

This started happening at this revision

https://github.com/z3t0/Arduino-IRremote/commit/88e243fe068e06d2ed602fefe6bd5effd07006e1

which seems to have split the library in many pieces.

Compilation log with Arduino 1.6.5

http://pastebin.com/ZZYU2dtC

with this Makefile

http://pastebin.com/3kv4HznZ

sej7278 commented 9 years ago

i suspect this is related to #93 where libraries that include other libraries aren't detected.

you probably need to look for all the #include lines and add them to your main sketch, for example IRremote.h calls #include "IRremoteInt.h"

that said, i changed the first line of your sketch to #include "IRremote.h" and it compiled fine with arduino 1.0.5 with just some warnings:

IRremote/irRecv.cpp:197:2: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
  long  hash = FNV_BASIS_32;
  ^

IRremote/ir_Aiwa.cpp: In member function ‘void IRsend::sendAiwaRCT501(int)’:
/home/simon/programming/c++/arduino/libraries/IRremote/ir_Aiwa.cpp:31:17: warning: unused variable ‘mask’ [-Wunused-variable]
  int            mask;
                 ^
audetto commented 9 years ago

The compilation is not the problem. Nor is linking.

IRremoteInt.h is not an other library, is just an other header file in the same library. There are no other libraries used.

The problem can only be detected at run time when the sketch fails to run properly. It gets stuck probably in the call

irrecv.enableIRIn();

and never gets to the end of setup().

The issue #93 seems to be with compilation issues.

sej7278 commented 9 years ago

the two build outputs don't seem to be for the same sketch - they have different names and are considerably different in size. not sure what we can do if it builds/links/uploads ok. it may be worth while asking the library authors what they think it may be....?

audetto commented 9 years ago

The sketch was the same, I put it in 2 separate folders just to void interference.

Till the last rev working the sizes of arduino vs makefile are very similar 8622 vs 8628 and variables are well 445 vs 445

with master on the other hand 10334 vs 9876 451 vs 451

something is different. But all files seems to be included in both builds, and files cannot be excluded from the build without a linker error. I will try to ask and replicate the 2 builds and see exactly if the flags passed to gcc are the same.

https://github.com/z3t0/Arduino-IRremote/issues/214

This is the output from the file in the same location

http://pastebin.com/n2ySD6jJ http://pastebin.com/gp4GDPY1

audetto commented 9 years ago

Found it.

The IDE and the Makefile link the sketch in 2 different ways

The difference is where the code for the libraries goes:

Apparently the linker will include all objects explicitly mentioned and pick from the static lib only objects really needed.

In IRremote there is a file irISR.cpp which exports no symbols, but defines the timer/interrupt, so if the linker is not forced it will NOT link it.

Probably this is a weak feature of the linker to rely on, but at the same time the IDE is "the" reference. What do you guys think?

I will propose to IRremote a change to fix this.

sej7278 commented 9 years ago

ah well done!

i suspect this is a side effect of the preprocessing that the ide does - basically concatenates all of the libraries and the sketch into one giant c++ file.

see https://github.com/arduino/Arduino/wiki/Build-Process and #59, i don't think its something we can simulate with the makefile.

i guess it guarantees that everything will get linked and users don't have to declare their methods before calling them etc. as you do with "proper" c++; the side effect is that all libraries get compiled (#29)

thanks for raising it with the IRremote guys, they seem pretty receptive. funnily enough i tried this library a few weeks back and it didn't work for me - i think it sent something as my camera picked up the led flashes, but my tv did nothing, and i certainly didn't receive anything back from my remote control, this perhaps explains why!

audetto commented 9 years ago

The fix has been applied to IRremote. Works well now.