Help with compile error, please

In brief, here's the error:

D:\River Documents\Halloween\2021\src\Lid/setup.ino:19: undefined reference to `_Z8eyes_DIMv'

And here is line 19 of setup.ino (I like to use tabs).

  Serial.println(F("---------- Starting ----------"));

I've tried re-typing that line and a few lines before and after it. Same error.
A search for "Z8" anywhere in my sketch reveals nothing.
I comment out line 19 and line 20, and the same error is now on line 22.
I restarted the IDE; same error.

Any tips on where I should be looking?
(The code has been working for weeks).

Here's the complete setup.ino:

//=============== setup ===============
void setup() {
  pinMode(closedSwitch, INPUT_PULLUP);
  pinMode(openSwitch, INPUT_PULLUP);
  //pinMode(buttonPin, INPUT_PULLUP);
  pinMode (BUTTON_PIN, INPUT_PULLUP);
  pinMode(BLUE_LED_PIN, OUTPUT);
  analogWrite(motorPin, 0);             //PWM pin, start at zero.
  pinMode(EYES_PIN, OUTPUT);
  pinMode(FAN_PIN, OUTPUT);

  beginSerial();
  setup_wifi();
  start_OTA();
  setup_mqtt();                         //Generate the topics
  client.setServer(mqttServer, mqttPort);
    mqttConnect();

  Serial.println(F("---------- Starting ----------"));
  client.publish (statusTopic, "Starting");

  lidState = 0;     //Open
  drawMenu();

  button.attachDoubleClick(doubleclick);
  button.attachClick(singleClick);
  button.attachLongPressStop(longPress);


  //Cycle through the eyes' LED intensity.
  for (int j = 0; j < 4; j++) {
    for (int i = 10; i < 255; i++) {
      analogWrite(EYES_PIN, i);
      delay(2);
    }
    for (int i = 255; i > 10; i--) {
      analogWrite(EYES_PIN, i);
      delay(2);
    }
  }
  eyesVal = EYES_MIN;
  analogWrite(EYES_PIN, eyesVal);
  delay(1000);

  //Fan
  analogWrite(FAN_PIN, FAN_MAX);
  delay(2000);
  analogWrite(FAN_PIN, 0);
  delay(1000);                                //Wait a second before opening the lid

  //Lid
  openTheLid();
  delay(1000);
  closeTheLid();

  analogWrite(FAN_PIN, FAN_MIN);


  //Start the LED timers
  eyes_ON();
}

Don't.

Or at least, glue it all back together while you figure out the issue. I'm not sure what the IDE does precisely, but I recall that it takes all your ino files and combines them (in alphabetical order?) so it may be confused as to where the error is.

Maybe consider using cpp files to separate code instead?

_Z8eyes_DIMv is a C++ way to encode symbols in the object file (look up "name mangling"). The name is actually eyes_DIM. Is that symbol referenced anywhere else? Maybe in the definition of something like EYES_PIN in another tab?

At the start of compilation, the Arduino IDE makes some small changes to your .ino files to ensure it's valid C++. It will add function prototypes for any function that doesn't already have one. This is intended to make it easier for beginners to write code in the Arduino IDE, and also automates a tedious task. After inserting the function prototypes, the IDE adds #line directives so that error/warning messages will still match your sketch. In some rare cases, the Arduino IDE does not take the correct action during function prototype generation. This can lead to very confusing errors. Sometimes the error messages don't even match the code in your sketch, since the error line is the "hidden" code inserted by the Arduino IDE. I suspect this is the case with the error you are getting.

When you encounter such an error, it can be very helpful to examine the post-sketch preprocessing output:

  1. File > Preferences
  2. Check the box next to "Show verbose output during: compilation'
  3. Click the OK button.
  4. Sketch > Verify/Compile
  5. After compilation fails, scroll the black console window at the bottom of the Arduino IDE window all the way to the top.
  6. Examine the first line of output to find the value of the "-build-path" option.

For example, if you had this:

C:\ArduinoIDE\arduino-nightly\arduino-builder -dump-prefs -logger=machine -hardware C:\ArduinoIDE\arduino-nightly\hardware -hardware C:\Users\<user name>\AppData\Local\Arduino15\packages -hardware E:\electronics\arduino\hardware -tools C:\ArduinoIDE\arduino-nightly\tools-builder -tools C:\ArduinoIDE\arduino-nightly\hardware\tools\avr -tools C:\Users\<user name>\AppData\Local\Arduino15\packages -built-in-libraries C:\ArduinoIDE\arduino-nightly\libraries -libraries E:\electronics\arduino\libraries -fqbn=esp32:esp32:node32s:FlashFreq=80,UploadSpeed=921600 -vid-pid=0X2341_0X0042 -ide-version=10809 -build-path C:\Users\<user name>\AppData\Local\Temp\arduino_build_889992 -warnings=all -build-cache C:\Users\<user name>\AppData\Local\Temp\arduino_cache_764477 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.esptool.path=C:\Users\<user name>\AppData\Local\Arduino15\packages\esp32\tools\esptool\2.3.1 -prefs=runtime.tools.esptool-2.3.1.path=C:\Users\<user name>\AppData\Local\Arduino15\packages\esp32\tools\esptool\2.3.1 -prefs=runtime.tools.mkspiffs.path=C:\Users\<user name>\AppData\Local\Arduino15\packages\esp32\tools\mkspiffs\0.2.3 -prefs=runtime.tools.mkspiffs-0.2.3.path=C:\Users\<user name>\AppData\Local\Arduino15\packages\esp32\tools\mkspiffs\0.2.3 -prefs=runtime.tools.xtensa-esp32-elf-gcc.path=C:\Users\<user name>\AppData\Local\Arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0 -prefs=runtime.tools.xtensa-esp32-elf-gcc-1.22.0-80-g6c4433a-5.2.0.path=C:\Users\<user name>\AppData\Local\Arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0 -verbose C:\Users\<user name>\AppData\Local\Temp\arduino_modified_sketch_19197\sketch_dec31a.ino

the temporary build folder is C:\Users\<user name>\AppData\Local\Temp\arduino_build_889992.

Now open the .ino.cpp file you find in the sketch subfolder of the temporary build folder with a text editor. You can examine the contents to see if you can spot the issue, or post it here and we'll take a look.


NOTE: The temporary build folder will be deleted when you exit the Arduino IDE.

Then I suggestion doing it the way I describe in Post #5 Here. The "Arduino Way" of multiple .ino files is (IMO) brain-dead.

I've never once seen a problem like that. What I have seen is forum regulars spreading FUD about .ino file tabs even though they don't have experience with using them or understanding of how they work.

Or maybe consider focusing on finding the problem rather than rearchitecting the sketch just to hide from it?

I've seen compilation errors in a single ino file caused by the IDE putting prototypes in, so I have little confidence that it is infallible when it comes to munging source files together. YMMV.

Thanks for the tip. I didn't know where to find the cpp file, but that led me tothe solution. There was a protoype for eyes_DIM(), but the function was named eyesDIM.

That was a head scratcher. I would have expected a different compile error.

I've seen Gfvalvo comments on tabs before and plan to look at cpp files in a future project. This one is too far along to shift focus now.

As I said in another post, the problem turned out to be in a misnamed function. Or more specifically, my callback function didn't exist, but the prototype did.

I am not disagreeing with you here. I have been using tabs and multiple ino files for a couple of years. This particular sketch has been in development for weeks, so getting this strange compile error was a surprise.

Using separate CPP files is likely a better solution than what I have been using, but namespace is something I don't grok. Your 'speakingClock' sketch may be the Rosetta Stone I need.

I suspect that your method may be better because, well here's an example. If I want to use OTA in my sketch, I copy 'ota.ino' to my sketch, then I have to add the declarations and globals to my main sketch. If I am understanding your example, I can do the declarations and global variables in the .cpp and never have to copy them into my main sketch. If I am reading this right, it could make my life easier.

This is the way to go. Also, while the function prototypes are supposed to be handled automagically, sometimes actually writing them is the cure.

I agree, but other than Gvalvo's example, I have never seen anyone use cpp files, so references are not easy to find.

But, not in this project. As the comments in the code indicate, this is a Halloween prop and that's only a couple of weeks away.

Was that a compile error or a link error? It looks like a link error. If it is, it means that you called a function with one set of arguments but defined it with a different set of arguments (or in a .c file). The 'mangled' names are used to implement 'function overloading' where you can have functions of the 'same' name taking different arguments.

Yes, it is a linker error. The problem was that my callback function didn't exist, but it was prototyped, so it compiled OK.

void xyz();
callback(..., xyz);

void (xxx){
...
}