Changes to library not present at compilation

Hey everyone,

I am writing a library that depends upon the Wire library. I needed to add some extra functionality to the Wire library so I created an extra method. But when I compile my test sketch I receive this error:

/var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/CapTouch/CapTouch.cpp.o: In function `CapTouch::executeCommand(command, unsigned char, unsigned char const*)':
/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/CapTouch/CapTouch.cpp:158: undefined reference to `TwoWire::readSlave(unsigned char)'
/var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/CapTouch/CapTouch.cpp.o: In function `CapTouch::start()':
/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/CapTouch/CapTouch.cpp:66: undefined reference to `TwoWire::readSlave(unsigned char)'
collect2: error: ld returned 1 exit status
Error compiling.

In my implementation of the Wire library I believe I have implemented my method correctly. Here is my function prototype:

  public:
    TwoWire();
    void begin();
    ...
    uint8_t readSlave(uint8_t);
    uint8_t requestFrom(uint8_t, uint8_t);
    ...

And in Wire.cpp

uint8_t TwoWire::readSlave(uint8_t address) {
  uint8_t tmp __atribute((unused));
...

I then use a script to place both of these in .../arduino/avr/libraries/Wire/. And this appears to be working correctly. When I look at the compilation output I see

/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire/Wire.cpp -o /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/Wire/Wire.cpp.o

And this file at this location has the correct changes that I made. I have tried restarting the Arduino IDE and deleting the temporary build directories but these did not solve the problem. It also appears to be using the correct object file when it does final compilation

/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-gcc -w -Os -Wl,--gc-sections -mmcu=atmega328p -o /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/APITest.cpp.elf /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/APITest.cpp.o /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/Wire/Wire.cpp.o /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/Wire/utility/twi.c.o /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/CapTouch/CapTouch.cpp.o /var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp/core.a -L/var/folders/q7/pf2zqzhj5gx2_40kld54z3b00000gp/T/build7775033036328170875.tmp -lm

I have tried making other changes to Wire.cpp in existing methods and none of those were present either. I also move my CapTouch library to .../arduino/avr/libraries/CapTouch/ and it is clearly found. I can open my CapTouch examples through the Arduino IDE GUI.

I am using an Arduino Uno. From what I see, it appears to be using a different version of the Wire library. But I don't see how that is possible when looking at the compilation output. I would appreciate any insight, I am probably making a stupid mistake.

My advice is to give your library a different name. Whatever stuff the IDE is going through to mis-identify your changes will be eliminated if you just rename things (eg. Wire to myWire and TwoWire to myTwoWire).

Even after renaming everything I continue to receive the same error. I have reinstalled the IDE as well. I am now clueless to what it may be. Any other ideas?

Is it an issue with being a class instance method or a class static method ?

Is it an issue with the users' libraries being in a different location to the standard arduino libraries ?

I remember I had a problem similar to this a couple of years ago, but I can't reproduce it now because that PC is broken.

Please post your sketch and the revised libraries. You can zip them up and attach the .zip file.

CapTouch is the library I am creating. TWire is my new Wire library, I renamed TwoWire to Two2Wire. And the method that it says is undefined is readMTCH6301. The sketch I am using is APITest.ino.

NewWire.zip (17.7 KB)

I tried to reproduce your problem, and Notepad++ won't even let me save an edited version of Wire.h

There seems to be some kind of stupid file protection BS going on.

So why isn't your readSlave( ) function in this TWire ?

I ended up renaming to readMTCH6301 just in case it was a naming issue. I believe it's in there with that name.

This doesn't look good, in CapTouch.h:

...
#include <stdio.h> //for size_t
#include "Arduino.h"
#include "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/TWire/TWire.h"

Note the last line, with its full pathname.

Also in CapTouch.h:

class TWire;

See TWire.h:

extern Two2Wire TWire;

The class is Two2Wire. An instance of the class is TWire.

#include "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/TWire/TWire.h"

You certainly should not be modifying libraries inside the application package. Your own libraries go into the libraries folder underneath your sketches folder. Don't change the application at all.

I tried again to reproduce your problem, and the reason I was having trouble is that your files are supposedly encrypted, which is giving me all sorts of anti-trojan grief at the moment.

And the method that it says is undefined is readMTCH6301.

So that is actually the same problem, then.

michinyon:
I tried again to reproduce your problem, and the reason I was having trouble is that your files are supposedly encrypted, which is giving me all sorts of anti-trojan grief at the moment.

I unzipped them OK under Ubuntu.

Ok I see how that was incorrect. I was confused by a few of the posts I read through for setting that up. Now I have the libraries in my sketches and in my CapTouch.h I am only using #include "TWire.h". I removed my libraries from the application package and compilation shows it is using the ones in my sketches directory. But I am still receiving the same error message.

Is this the proper way to use TWire in my CapTouch? These are my includes in CapTouch.h, got rid of Class TWire;

#include <stdio.h> //for size_t
#include "Arduino.h"

#include "TWire.h"

Then in my sketch I have

#include <TWire.h>
#include <CapTouch.h>
    uint8_t _irq, _touchX, _touchY, _reset, _touchCap, _touchCount = 0;
...
    uint8_t _pressPins[11] = { 0, };
    void (*_callbacks[11])(uint8_t, uint8_t) = { 0, };

...

/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:112: error: ISO C++ forbids initialization of member ‘_touchCount’
In file included from APITest.ino:2:
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:114: error: a brace-enclosed initializer is not allowed here before ‘{’ token
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:114: error: ISO C++ forbids initialization of member ‘_pressPins’
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:114: error: making ‘_pressPins’ static
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:114: error: invalid in-class initialization of static data member of non-integral type ‘uint8_t [11]’
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:115: error: a brace-enclosed initializer is not allowed here before ‘{’ token
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:115: error: ISO C++ forbids initialization of member ‘_callbacks’
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:115: error: making ‘_callbacks’ static
/home/nick/sketchbook/libraries/CapTouch/CapTouch.h:115: error: invalid in-class initialization of static data member of non-integral type ‘void (* [11])(uint8_t, uint8_t)’

Those messages are correct, you can't have initializers there.


The plot thickens. I edited TWire.cpp and added this line:

#error foo

It compiled without error, which it shouldn't have.

You need to get that error (foo) to show up to confirm you are compiling the file you think you are.

Right. You had me going for a while there.

Your new function:

uint8_t Two2Wire::readMTCH6301(uint8_t address)

... is in part of the code that is not active because it is inside:

#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__)
...
#endif

So, you put the new function in the wrong place.

Yep that is it. Thank you both for taking time to help me, I really appreciate it.