Undefined reference to included function

I'm trying to learn about library creation and have gotten stuck on what I suspect is a really simple error. My sketch includes a pair of simple files in their own subdirectory: led/blinkfile.h and led/blinkfile.cpp, but the compiler is complaining about the lone function inside them.

Here's my main sketch code:

#include "led/blinkfile.h"

bool ledState = true;

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  ledState = !ledState;
  setLed(ledState);
  delay (200);
}

My header file ("led/blinkfile.h"):


#include <Arduino.h>

void setLed(bool);

My C++ file ("led/blinkfile.cpp"):


void setLed(bool lState)
{
  digitalWrite(13, lState);
}

If I move the contents of "led/blinkfile.cpp" to the end of "led/blinkfile.h", the sketch compiles and functions as intended, but my goal is to learn how to create separate header and source files properly. Any help would be greatly appreciated!

Show the verbose error log in code tags.
Without seeing that, where is the blinkfile.cpp? What I mean is, is it in the source folder, or one of the library folders?

And therein lies the problem. The Adrduino IDE knows nothing of .cpp files in subdirectories.

Move the .h and .cpp files to the sketch directory. Change the include to remove the subdirectory reference. Add #include <Arduino.h> to your .cpp file (otherwise it knows nothing of the Arduino functions, like digitalWrite). Compiles like a charm.

i renamed your files

  • blinkfile.cpp to tuc.cpp
  • blinkfile.h to tuc.h, and
  • change the #include your .ino accordingly.

with just these changes, digitalWrite() is undeclared until i moved the #include "Arduino.h"; to tuc.cpp.

the code compiles and the LED flashes

Shouldn't a subdirectory structure like src/led/blinkfile.h (within the sketch root folder) also work?

1 Like

https://docs.arduino.cc/arduino-cli/sketch-specification/#src-subfolder :

src subfolder

The contents of the src subfolder are compiled recursively. Unlike the code files in the sketch root folder, these files are not shown as tabs in the IDEs.

1 Like

I neglected to specify that the subdirectory containing my .h and .cpp files is located in my sketch's directory.

Here's the error log:

FQBN: arduino:avr:uno
Using board 'uno' from platform in folder: /home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6
Using core 'arduino' from platform in folder: /home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6

Detecting libraries used...
/home/bt/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino -I/home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6/variants/standard /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/sketch/basic_library_test.ino.cpp -o /dev/null
Generating function prototypes...
/home/bt/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino -I/home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6/variants/standard /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/sketch/basic_library_test.ino.cpp -o /tmp/3941653225/sketch_merged.cpp
/home/bt/.arduino15/packages/builtin/tools/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /tmp/3941653225/sketch_merged.cpp

Compiling sketch...
/home/bt/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino -I/home/bt/.arduino15/packages/arduino/hardware/avr/1.8.6/variants/standard /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/sketch/basic_library_test.ino.cpp -o /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/sketch/basic_library_test.ino.cpp.o
Compiling libraries...
Compiling core...
Using precompiled core: /home/bt/.cache/arduino/cores/arduino_avr_uno_050da7a295295d30c066a7c49d0955b0/core.a
Linking everything together...
/home/bt/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc -Wall -Wextra -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/basic_library_test.ino.elf /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/sketch/basic_library_test.ino.cpp.o /home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD/../../cores/arduino_avr_uno_050da7a295295d30c066a7c49d0955b0/core.a -L/home/bt/.cache/arduino/sketches/C3B25C32EC53E7491701D920D6F16CDD -lm
/tmp/ccog6V6j.ltrans0.ltrans.o: In function `loop':
/home/bt/Arduino/tests/basic_library_test/basic_library_test.ino:14: undefined reference to `setLed(bool)'
collect2: error: ld returned 1 exit status
exit status 1

Compilation error: exit status 1

The problem is that your blinkfile.cpp does not get compiled. The Arduino IDE does not compile files in arbitrary subdirectories of the sketch directory. All files you want to be compiled must be located in a subdirectory (tree) namend 'src' within your sktech directory.

This is what I was trying to achieve, a modular library that it self-contained within the sketch. Thanks to your reply, I just discovered my error: I had the "led" directory right there in the sketch's root directory. I just now added a "src" directory, moved the "led" directory into it, and changed the path in my sketch to "src/led/blinkfile.h" and it works!

2 Likes

Exactly! That's what I just learned.

I knew I had to be overlooking something simple. :grinning_face_with_smiling_eyes:

Thank you to everyone who replied!

Glad I could help. If your problem has been solved, please mark the corresponding answer as the thread "Solution", by clicking the :white_check_mark: below the comment.

Or include the header for the cpp in the cpp file, not uncommon. It has the Arduino.h aready.

a7

Will do.

Everyone's reply provided good information, but the reply from MicroBahner concisely describes exactly what I had to do and why, so I would like to mark that one as the solution.

1 Like