Can't link libraries without framework

I have tried including libraries into my project. I’m using pure avr-gcc without any functions or anything from any framework. However, when I try linking libraries onto it, things don’t work well.

My libraries are clonned from vcs into the lib folder. There are two of them, OLED library depends on an I2C library. In main.cpp I only include the OLED library, as I don’t call anything from I2C library. All references to the I2C library are within the OLED library.

With line framework = arduino in the platform.ini file. My dependency graph looks like this:

Dependency Graph
|-- TinierI2C @ 2.0.2
|-- tinierOLED
|   |-- TinierI2C @ 2.0.2

However, when I comment that line out, it changes into this:

|-- tinierOLED

And it’s followed by many linking errors, sine it cannot find an object, which was declared as extern in I2C library. A snippet from a long list of very simillar errors looks like this:

Linking .pio/build/ATtiny404/firmware.elf
/tmp/cc8IJbnN.ltrans0.ltrans.o: In function `SSD1306Device::ssd1306_send_command_start() [clone .constprop.11]':
<artificial>:(.text+0x8): undefined reference to `TinierI2C'
<artificial>:(.text+0xa): undefined reference to `TinierI2C'
<artificial>:(.text+0xc): undefined reference to `TinierI2CMaster::start(unsigned char, long)'
<artificial>:(.text+0x10): undefined reference to `TinierI2C'
...

What could cause the problem? I’m very confused, since everything works with framework set to arduino.

Full output of the command /usr/bin/pio run -t upload -e ATtiny404 -v is here:

Processing ATtiny404 (platform: atmelmegaavr; board: ATtiny404; board_build.f_cpu: 4000000UL)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/atmelmegaavr/ATtiny404.html
PLATFORM: Atmel megaAVR (1.9.0) > ATtiny404
HARDWARE: ATTINY404 4MHz, 256B RAM, 4KB Flash
PACKAGES: 
 - tool-avrdude @ 1.70100.0 (7.1.0) 
 - toolchain-atmelavr @ 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Framework incompatible library /home/martin/CLionProjects/avr-radio/lib/tinier-i2c
More details about "Library Compatibility Mode": https://docs.platformio.org/page/librarymanager/ldf.html#ldf-compat-mode
Found 1 compatible libraries
Scanning dependencies...
Dependency Graph
|-- tinierOLED (License: Unknown, Path: /home/martin/CLionProjects/avr-radio/lib/tinierOLED)
Building in release mode
avr-g++ -o .pio/build/ATtiny404/src/main.o -c -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -fpermissive -Wno-error=narrowing -mmcu=attiny404 -Os -w -ffunction-sections -fdata-sections -flto -DF_CPU=4000000UL -DPLATFORMIO=60106 -DARDUINO_attinyxy4 -DMILLIS_USE_TIMERA0 -DUARTBAUD5V -Iinclude -Isrc -Ilib/tinierOLED/src src/main.cpp
avr-g++ -o .pio/build/ATtiny404/lib73d/tinierOLED/tinierOLED.o -c -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -fpermissive -Wno-error=narrowing -mmcu=attiny404 -Os -w -ffunction-sections -fdata-sections -flto -DF_CPU=4000000UL -DPLATFORMIO=60106 -DARDUINO_attinyxy4 -DMILLIS_USE_TIMERA0 -DUARTBAUD5V -Ilib/tinierOLED/src lib/tinierOLED/src/tinierOLED.cpp
avr-gcc-ar rc .pio/build/ATtiny404/lib73d/libtinierOLED.a .pio/build/ATtiny404/lib73d/tinierOLED/tinierOLED.o
avr-gcc-ranlib .pio/build/ATtiny404/lib73d/libtinierOLED.a
avr-g++ -o .pio/build/ATtiny404/firmware.elf -mmcu=attiny404 -Os -flto -Wl,--gc-sections -Wl,--section-start=.text=0x0 -fuse-linker-plugin .pio/build/ATtiny404/src/main.o -L.pio/build/ATtiny404 -Wl,--start-group .pio/build/ATtiny404/lib73d/libtinierOLED.a -lm -Wl,--end-group
/tmp/cc5Z20lK.ltrans0.ltrans.o: In function `SSD1306Device::ssd1306_send_command_start() [clone .constprop.11]':
<artificial>:(.text+0x8): undefined reference to `TinierI2C'
<artificial>:(.text+0xa): undefined reference to `TinierI2C'
<artificial>:(.text+0xc): undefined reference to `TinierI2CMaster::start(unsigned char, long)'
<artificial>:(.text+0x10): undefined reference to `TinierI2C'
...
<artificial>:(.text.startup+0xfa): undefined reference to `TinierI2CMaster::stop()'
collect2: error: ld returned 1 exit status
*** [.pio/build/ATtiny404/firmware.elf] Error 1

If no dependency is detected from the tinierOLED library to the TinierI2C library, something’s wrong. It could be a multitde of things, like bad library.json files that require a framework or manually set include build flags to the dependency, or lib_ldf_mode, or lib_compat_mode.

It’s hard to say without seeing the exact project files. Can you upload them, or a minimal version thereof?

1 Like

It indeed was the library.json file, thank you. OLED library didn’t have that file at all and it was fine. But the I2C library was a fork of a project which had this file and there was the following setting: "frameworks": "arduino". Removing this line solved the issue.

Thank you for pointing me in the right direction.