Linker Problem?

Hi there,
i spent the last few evenings with a imop linker problem… Or maybe it’s me?

Given files: motor.h; motor.cpp; main.cpp.
Platform is ESP8266-12E, Arduino Framework.

Latest Updates & Librarys are installed.
Did a Intellisense Rebuild Index & Arduino Rebuild Intellisense Config.
Code was first written in a bigger project, but linking will fail even if used isolated.
If the .cpp & header files are stored within the “src” folder, linking is successful.
If .cpp & header files are stored within the “include” folder, build fails.
If i move the files mentioned above to a new folder (myfunc) and include them with an absolute path
(#include “C:\Users\dameda\Nextcloud\Code\klassentest1\myfunc\motor.cpp”) compilation and linking works fine…

Failed full build log:

Executing task: C:\Users\dameda\.platformio\penv\Scripts\platformio.exe run 

Processing esp12e (platform: espressif8266; board: esp12e; framework: arduino)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/esp12e.html
PLATFORM: Espressif 8266 (3.2.0) > Espressif ESP8266 ESP-12E
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES:
 - framework-arduinoespressif8266 @ 3.30002.0 (3.0.2)
 - tool-esptool @ 1.413.0 (4.13)
 - tool-esptoolpy @ 1.30000.201119 (3.0.0)
 - toolchain-xtensa @ 2.100300.210717 (10.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 35 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\esp12e\src\main.cpp.o
Generating LD script .pio\build\esp12e\ld\local.eagle.app.v6.common.ld
Archiving .pio\build\esp12e\libFrameworkArduinoVariant.a
Compiling .pio\build\esp12e\FrameworkArduino\Crypto.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Esp-frag.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Esp-version.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Esp.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\FS.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\FSnoop.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\FunctionalInterrupt.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\HardwareSerial.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\IPAddress.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\LwipDhcpServer-NonOS.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\LwipDhcpServer.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\LwipIntf.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\LwipIntfCB.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\MD5Builder.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Print.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Schedule.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\StackThunk.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Stream.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\StreamSend.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Tone.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\TypeConversion.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\Updater.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\WMath.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\WString.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\abi.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\aes_unwrap.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\base64.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\cbuf.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\cont.S.o
Compiling .pio\build\esp12e\FrameworkArduino\cont_util.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_app_entry_noextra4k.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_eboot_command.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_features.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_flash_quirks.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_flash_utils.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_i2s.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_main.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_non32xfer.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_noniso.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_phy.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_postmortem.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_si2c.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_sigma_delta.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_spi_utils.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_timer.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_vm.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_waveform_phase.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_waveform_pwm.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_wiring.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_wiring_analog.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_wiring_digital.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_wiring_pulse.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_wiring_pwm.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\core_esp8266_wiring_shift.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\crc32.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\debug.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\exc-c-wrapper-handler.S.o
Compiling .pio\build\esp12e\FrameworkArduino\exc-sethandler.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\flash_hal.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\gdb_hooks.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\heap.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\hwdt_app_entry.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\libb64\cdecode.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\libb64\cencode.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\libc_replacements.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\mmu_iram.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\reboot_uart_dwnld.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\spiffs\spiffs_cache.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\spiffs\spiffs_check.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\spiffs\spiffs_gc.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\spiffs\spiffs_hydrogen.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\spiffs\spiffs_nucleus.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\spiffs_api.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\sqrt32.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\stdlib_noniso.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\time.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\uart.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\umm_malloc\umm_info.c.o
Compiling .pio\build\esp12e\FrameworkArduino\umm_malloc\umm_integrity.c.o
Compiling .pio\build\esp12e\FrameworkArduino\umm_malloc\umm_local.c.o
Compiling .pio\build\esp12e\FrameworkArduino\umm_malloc\umm_malloc.cpp.o
Compiling .pio\build\esp12e\FrameworkArduino\umm_malloc\umm_poison.c.o
Archiving .pio\build\esp12e\libFrameworkArduino.a

Linking .pio\build\esp12e\firmware.elf
c:/users/dameda/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\esp12e\src\main.cpp.o:(.text.loop+0x0): undefined reference 
to `_ZN5MotorC1Ev'
c:/users/dameda/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\esp12e\src\main.cpp.o:(.text.loop+0x4): undefined reference 
to `_ZN5Motor4stopEv'
c:/users/dameda/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\esp12e\src\main.cpp.o:(.text.loop+0x8): undefined reference 
to `_ZN5MotorD1Ev'
c:/users/dameda/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\esp12e\src\main.cpp.o: in function `loop':
main.cpp:(.text.loop+0x13): undefined reference to `_ZN5MotorC1Ev'
c:/users/dameda/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: main.cpp:(.text.loop+0x1b): undefined reference to `_ZN5Motor4stopEv'  
c:/users/dameda/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: main.cpp:(.text.loop+0x23): undefined reference to `_ZN5MotorD1Ev'     
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\esp12e\firmware.elf] Error 1
======================================================================================== [FAILED] Took 6.34 seconds ========================================================================================

 *  The terminal process "C:\Users\dameda\.platformio\penv\Scripts\platformio.exe 'run'" terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

platformio.ini:

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
upload_port = COM11
upload_speed = 115200
monitor_speed = 115200

main.cpp:

#include <Arduino.h>
//#include "motor.h"
#include "motor.h"

void setup()
{
}

void loop()
{
  Motor motor;
  // motor.motorspeed(200);
  // motor.close(100);
  motor.stop();
}

motor.h:

#ifndef motor_h
#define motor_h
 //void Motor(int speed);
class Motor
{
    public: Motor(void);
    public: ~Motor(void);
    /// @brief Motorgeschwindigkeit setzen
    /// @param mspeed
    public: void motorspeed(int mspeed);
    /// @brief Motor anhalten ///
    public: void stop();
    public: void open(int mspeed);
    public: void close(int mspeed);
};

#endif

motor.cpp:

#include <Arduino.h>
//#include <motor.h>
#include "motor.h"

Motor::Motor(void)
{
int i = 0;
}
Motor::~Motor(void)
{
    int i = 1;
}

void Motor::close(int mspeed)
{
    digitalWrite(10, LOW);
    analogWrite(10,mspeed);
}

void Motor::motorspeed(int mspeed)
{
    digitalWrite(10, LOW);
    analogWrite(10,mspeed);
}

void Motor::open(int mspeed)
{
    digitalWrite(10, LOW);
    analogWrite(10,mspeed);
}

void Motor::stop()
{
    digitalWrite(10, LOW);    
}

pio system info:

pio system info
--------------------------  -------------------------------------------------------
PlatformIO Core             6.1.4
Python                      3.9.10-final.0
System Type                 windows_amd64
Platform                    Windows-10
File System Encoding        utf-8
Locale Encoding             cp1252
PlatformIO Core Directory   C:\Users\dameda\.platformio
PlatformIO Core Executable  C:\Users\dameda\.platformio\penv\Scripts\platformio.exe
Python Executable           C:\Users\dameda\.platformio\penv\Scripts\python.exe
Global Libraries            0
Development Platforms       3
Tools & Toolchains          26
--------------------------  -------------------------------------------------------

What am i missing?

Greets, Stephan :slight_smile:

Hi, it’s me again…
Should the Files have been stored in the “lib” dir?

Greetz, Stephan

No. .cpp files in include/ are not compiled. Move the motor.cpp file to src/.

Or, create a folder lib/motor and put both motor.h and motor.cpp in there.

include/ is only intended for .h files, the build system will not try to compile these files into object .o files and link them in the ELF.

1 Like