Undefined reference error during linking

I’m just starting into a new project which has to be highly configurable for lots of different hardware so I am building up an organization of configuration.h + folders,+ driver files. To do this, I am starting with a “blinking LED” program, but breaking everything out to include a main.cpp, configuration.h, includes.h, init.c, and heartBeat.c. Everything goes fine until I break the flashing LED code into heartBeat.c. The error does not appear until the linking part of the build.

c:/users/peted/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: .pio\build\um_feathers3\src\main.cpp.o:(.literal._Z4loopv+0x0): undefined reference to `heartBeat()'
c:/users/peted/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: .pio\build\um_feathers3\src\main.cpp.o: in function `loop()':
C:\Users\peted\OneDrive\Documents\PlatformIO\Projects\Feather3Test/src/main.cpp:15: undefined reference to `heartBeat()'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\um_feathers3\firmware.elf] Error 1

heartBeat.c and heartBeat.h live in the src/utils directory but I get the same error even if they are in the src directory along with all the other code files.

I know this is a complex structure for just a flashing LED program but it is as simple an example of the structure I am trying to set up for a much more complex program.

WHY DO I GET THIS ERROR AT LINK TIME? Many thanks for helping me get over the hump here.

so here is are the relevant files…

includes.h:

#ifndef _INCLUDES_H_
#define _INCLUDES_H_

#include <Arduino.h>

#include "configuration.h"
#include "init.h"
#include "heartBeat.h"

#endif // _INCLUDES_H_

configuration.h

#ifndef _CONFIGURATION_H_
#define _CONFIGURATION_H_

#define FLASHING_LED

#endif  // _CONFIGURATION_H_

main.cpp

#include <includes.h>

void setup()
{
  init();
  Serial.begin();
}

void loop()
{
 #ifdef FLASHING_LED
   heartBeat();
 #endif
}

heartBeat.h

#ifndef _HEARTBEAT_H_

#define _HEARTBEAT_H_

#ifdef FLASHING_LED

void heartBeat(void);

#endif

#endif  // _HEARTBEAT_H_

heartBeat.c

#include "includes.h"

#ifdef FLASHING_LED
void heartBeat(void)
{
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
    delay(500);                      // wait for a second
    digitalWrite(LED_BUILTIN, LOW);  // turn the LED off by making the voltage LOW
    delay(1000);                     // wait for a second
}
#endif

platformio.ini:

[env:um_feathers3]
platform = espressif32
board = um_feathers3
upload_port = COM6
monitor_speed = 115200

src_dir = ./src
build_flags = -fmax-errors=5
  -I./src/
  -I./src/utils/

lib_ldf_mode = deep
lib_extra_dirs = ~/Documents/Arduino/libraries

framework = arduino

and just to be complete…
init.h:

#ifndef _INIT_H_

#define _INIT_H_

void init (void);

#endif //_INIT_H_

init.c:

#include "includes.h"

void init(void)

{

    #ifdef FLASHING_LED

    pinMode(LED_BUILTIN, OUTPUT);

    #endif

}

The problem is your mix of .c and .cpp file. It you really want to mix C and C++, you need to specify “C” linkage for C code used from C++.

Since Arduino is a C++ framework, I propose you use C++ only.

Thank you Manuel.

As with many things that get me wrapped around the axle for hours, this too had a very simple cause/solution.

Again, thank you.