PlatformIO Community

Undefined reference to.... for project libs

Hi all,

There are lots of results on the forums for undefined reference to errors but I can’t find any describing my problem with it happening with project libs. I can successfully build simple projects that don’t require anything outside of the project_root/src/ folder. However, when creating a simple library within the project_root/lib/ folder I get linker errors.

The library I’m trying to create is a simple two file library. The project layout is:

.
├── include
│   └── README
├── lib
│   ├── README
│   └── spool
│       ├── spool.cpp
│       └── spool.h
├── platformio.ini
├── src
│   └── main.cpp
└── test
    ├── main_test.cpp
    └── README

Within spool.h I have:

#ifndef SPOOL_H
#define SPOOL_H

#include <stdio.h>
#include <memory>

template <typename T>
class Spool {
    public:
    explicit Spool(size_t size) :
        buf_(std::unique_ptr<T[]>(new T[size])),
        max_size_(size)
    {};

    void put(T item);
    T get();
    void reset();
    bool empty() const;
	bool full() const;
	size_t capacity() const;
	size_t size() const;

    private:
    std::unique_ptr<T[]> buf_;
    const size_t max_size_;
    
    size_t head_ = 0;
	size_t tail_ = 0;
    bool full_ = false;
};

etc....

And the definition for those functions are within spool.cpp. I don’t believe the issue is with the definition of those functions as if I copy the content of spool.cpp into the bottom of spool.h everything works. An example definition (matching the error below):

template <typename T>
void Spool<T>::reset() {
    head_ = tail_;
    full_ = false;
}

Again, pasting that at the bottom of my header file works fine. At the top of my main_test.cpp (and my main.cpp within the src directory) I have:

#include <spool.h>

My current platformio.ini looks like:

;PlatformIO Project Configuration File

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino

[env:native]
platform = native
lib_ldf_mode=deep
lib_comp_mode=strict

I have tried various combinations of lib_ldf_mode and lib_comp_mode in an effort to get the linker to link the library properly.

When I try to run a test or build my project, I get:

LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ deep, Compatibility ~ soft
Found 1 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <spool>
Compiling .pio/build/native/test/main_test.o
Compiling .pio/build/native/test/output_export.o
Compiling .pio/build/native/lib602/spool/spool.o
Compiling .pio/build/native/UnityTestLib/unity.o
Archiving .pio/build/native/libUnityTestLib.a
Indexing .pio/build/native/libUnityTestLib.a
Archiving .pio/build/native/lib602/libspool.a
Indexing .pio/build/native/lib602/libspool.a
Linking .pio/build/native/program
/usr/bin/ld: .pio/build/native/test/main_test.o: in function `test_spool()':
main_test.cpp:(.text+0x52): undefined reference to `Spool<int>::reset()'                                                                                                                         
collect2: error: ld returned 1 exit status                                                                                                                                                       
*** [.pio/build/native/program] Error 1

I tried to get verbose output by running platformio test -e native --verbose but nothing seemed to change. As far as I can see, my project layout is identical to that of the calculator unit test example, minus the src folder within lib/spool. I tried with that src folder and got exactly the same results.

I’m currently at a loss of where to look to figure out why linking isn’t working. Any help would be greatly appreciated.

Thanks in advance,
Marcus

Of course, after searching and posting I look in recent posts and there’s Testing c++ code which looks similar. It doesn’t have a solution yet so may or may not be the same problem.

1 Like

Hi @savoirfaire! Please take a look at this page Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?.