Compiler failed to find function definitions for header with adjacent source (undefined reference)

When I’m compiling a simple main.cpp (atmelavr platform) #included header and source in separate but adjacent file, linker fails to find the source and returns error code 1.

File tree:

.
├── include
│   ├── README
│   ├── hd.cxx
│   └── hd.hxx
├── lib
│   └── README
├── platformio.ini
├── src
│   └── main.cpp
└── test
    └── README

include/hd.hxx:

void run();

namespace T
{
    void run();
}

class Test
{
public:
    Test();
};

include/hd.cxx:

#include "hd.hxx"

void run()
{
}

void T::run()
{
}

Test::Test()
{
}

src/main.cpp:

#include <Arduino.h>
#include "hd.hxx"

void setup() {
  // put your main code here, to run once:
  run();
  T::run();
  Test();
}

void loop() {
  // put your main code here, to run repeatedly:
}

All three calls in setup() causes linker to fail.
Verbose build output:

> Executing task: platformio run --verbose <

Processing megaatmega2560 (platform: atmelavr; board: megaatmega2560; framework: arduino; upload_port: /dev/cu.usbmodem1471201)
-------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/megaatmega2560.html
PLATFORM: Atmel AVR 2.0.0 > Arduino Mega or Mega 2560 ATmega2560 (Mega 2560)
HARDWARE: ATMEGA2560 16MHz, 8KB RAM, 248KB Flash
PACKAGES: 
 - framework-arduino-avr 5.0.0 
 - toolchain-atmelavr 1.50400.190710 (5.4.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
avr-g++ -o .pio/build/megaatmega2560/firmware.elf -Os -mmcu=atmega2560 -Wl,--gc-sections -flto -fuse-linker-plugin .pio/build/megaatmega2560/src/main.cpp.o -L.pio/build/megaatmega2560 -Wl,--start-group .pio/build/megaatmega2560/libFrameworkArduinoVariant.a .pio/build/megaatmega2560/libFrameworkArduino.a -lm -Wl,--end-group
/var/folders/y2/kqr2bn7j3bqbb6xh3wqw1xxc0000gn/T//ccFrvf93.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0xea): undefined reference to `run()'
<artificial>:(.text.startup+0xee): undefined reference to `T::run()'
<artificial>:(.text.startup+0xf6): undefined reference to `Test::Test()'
collect2: error: ld returned 1 exit status
*** [.pio/build/megaatmega2560/firmware.elf] Error 1
================================== [FAILED] Took 0.63 seconds ==================================
The terminal process terminated with exit code: 1

Terminal will be reused by tasks, press any key to close it.

platformio.ini if needed:

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
upload_port = /dev/cu.usbmodem1471201

Why separated header and source file can be compiled if it is a library but can’t if it is in include directory?
Does anyone have idea?

Don’t put hd.cxx in include, put it in src.

See also Use headers give me an error - #7 by DrakoPD

1 Like

Aww thanks so much!
It works now.

1 Like