Build an Arduino library for ESP8266 locally

This project GitHub - ThingPulse/esp8266-weather-station: ESP8266 Weather Station library supporting OpenWeatherMap, Aeris and other sources builds fine on Travis CI but fails to link locally in VS Code


platform = espressif8266
board = d1_mini
framework = arduino
upload_speed = 921600
board_f_cpu = 160000000L
lib_deps =  JsonStreamingParser,
            DHT sensor library
            Adafruit Unified Sensor


Linking .pio/build/d1_mini/firmware.elf
/Users/marcelstoer/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: .pio/build/d1_mini/libFrameworkArduino.a(core_esp8266_main.cpp.o):(.text._ZL12loop_wrapperv+0x4): undefined reference to `setup'
/Users/marcelstoer/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: .pio/build/d1_mini/libFrameworkArduino.a(core_esp8266_main.cpp.o):(.text._ZL12loop_wrapperv+0x8): undefined reference to `loop'
/Users/marcelstoer/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: .pio/build/d1_mini/libFrameworkArduino.a(core_esp8266_main.cpp.o): in function `loop_wrapper()':
core_esp8266_main.cpp:(.text._ZL12loop_wrapperv+0x21): undefined reference to `setup'
/Users/marcelstoer/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: core_esp8266_main.cpp:(.text._ZL12loop_wrapperv+0x2d): undefined reference to `loop'
collect2: error: ld returned 1 exit status
*** [.pio/build/d1_mini/firmware.elf] Error 1

It looks as if it didn’t understand that this is actually Arduino code. Already deleted the .pio, .platformio and ~/.platformio/packages folders but that doesn’t help.

Since you didn’t mention what you’re trying to compile, I’m assume you mean one of the examples. I had a skim of most of them, and there’s no #include <Arduino.h> in a couple… which is most likely why you have the undefined reference to 'setup'/'loop' errors.

1 Like

I get your point, thanks. As this project is an Arduino library (for ESP8266) that includes examples the Travis file includes all the


definitions for each example. That works - with or without the #include <Arduino.h>.

I guess I was hoping I could build all at once locally with the minimal platformio.ini included in the project. That doesn’t seem to be case even if I add #include <Arduino.h> to all the examples it was missing (thanks for the hint).

Hm… I’ll counter with another question, but for @ivankravets… which could answer this for both of us… as I had tried to get this configuration working before but it wouldn’t play ball, and I am so close now it’s not funny.

Ivan, I managed to get my pet library to compiles examples in different envs using the following, but only if I rename the *.ino files to *.cpp. Is there anything I’m missing there? Is it possible to persuade PIO to accept *.ino files as well? .ino files are accepted if I point the [platformio] src_dir to a folder like $PROJECT_DIR/examples/timeouts, but that doesn’t help as that’s the global setting.

platformio.ini contents
src_dir = $PROJECT_DIR/examples
lib_dir = $PROJECT_DIR

platform = atmelavr
framework = arduino
board = uno

src_filter = +<blinkingLeds/>

src_filter = +<GettingStarted/>

src_filter = +<timeouts/>

src_filter = +<timingComparison/>

Edit: Just linking this topic, as it looks to be another approach to the problem, but if the OP can get it working again, looks to be neater / more automated.

So, using this extrascript …

env['PROJECT_SRC_DIR'] = env['PROJECT_DIR'] + "\\examples\\" + env["PIOENV"]
print("Setting the project directory to: {}".format(env['PROJECT_SRC_DIR']))

… with this platformio.ini

lib_dir = $PROJECT_DIR

extra_scripts =
platform = atmelavr
framework = arduino
board = uno





with the elapsedMillis library (once I move the header file into /src) works just fine… I can compile all of the examples at once, or compile any individual one at will.

However, when I try to do the same for the esp8266-weather-station library, with this platformio.ini it spits the dummy … dependency graph is all wonky (although it is a bit wonky for the elapsedMillis examples also), and it can’t find the libraries, even though they were installed :frowning:

lib_dir = $PROJECT_DIR

extra_scripts =
platform = espressif8266
board = d1_mini
framework = arduino
upload_speed = 921600
board_build.f_cpu = 160000000L
lib_deps =
    DHT sensor library
    Adafruit Unified Sensor


Processing oneDayForecaster (platform: espressif8266; board: d1_mini; framework: arduino)
Verbose mode can be enabled via `-v, --verbose` option
Setting the project directory to: e:\repos\GitHub\esp8266-weather-station\examples\oneDayForecaster
PLATFORM: Espressif 8266 2.2.3 > WeMos D1 R2 and mini
HARDWARE: ESP8266 160MHz, 80KB RAM, 4MB Flash
PACKAGES: toolchain-xtensa 2.40802.190218 (4.8.2), tool-esptool 1.413.0 (4.13), tool-esptoolpy 1.20600.0 (2.6.0), framework-arduinoespressif8266 2.20502.0 (2.5.2)
Converting oneDayForecaster.ino
LDF: Library Dependency Finder ->
LDF Modes: Finder ~ chain, Compatibility ~ soft
Looking for JsonStreamingParser library in registry
LibraryManager: Installing id=561
Using cache: C:\Users\Peter\.platformio\.cache\88\f8d1709798831a95c4e40862a1906088
JsonStreamingParser @ 1.0.5 has been successfully installed!
Looking for ESP8266_SSD1306 library in registry
LibraryManager: Installing id=562
Using cache: C:\Users\Peter\.platformio\.cache\d0\5934d6d51cda3c4bcc0818eb30dc49d0
Unpacking  [####################################]  100%
ESP8266_SSD1306 @ 4.1.0 has been successfully installed!
Looking for simpleDSTadjust library in registry
LibraryManager: Installing id=1276
Using cache: C:\Users\Peter\.platformio\.cache\be\e2ad0113c989ed3d1d3a3d631d6149be
simpleDSTadjust @ 1.2.0 has been successfully installed!
Looking for DHT sensor library library in registry
Found: sensor library
LibraryManager: Installing id=19
Using cache: C:\Users\Peter\.platformio\.cache\c4\c71b8c48a4a013bd3cff76e14fc53bc4
DHT sensor library @ 1.3.8 has been successfully installed!
Looking for Adafruit Unified Sensor library in registry
Found: Unified Sensor
LibraryManager: Installing id=31
Using cache: C:\Users\Peter\.platformio\.cache\d3\d18a768c13d410d94032887a7f4d50d3
Adafruit Unified Sensor @ 1.0.3 has been successfully installed!
Found 41 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <.pio>
|-- <SD(esp8266)> 2.0.0
|   |-- <SDFS> 0.1.0
|   |   |-- <SPI> 1.0
|   |   |-- <ESP8266SdFat> 1.0.16
|   |   |   |-- <SPI> 1.0
|-- <ESP8266mDNS> 1.2
|   |-- <ESP8266WiFi> 1.0
|-- <src>
|   |-- <ESP8266WiFi> 1.0
|   |-- <.pio>
|   |-- <ESP8266HTTPClient> 1.2
|   |   |-- <ESP8266WiFi> 1.0
|-- <ArduinoOTA> 1.0
|   |-- <ESP8266mDNS> 1.2
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266WiFi> 1.0
Building in release mode
Compiling .pio\build\oneDayForecaster\src\oneDayForecaster.ino.cpp.o
Generating LD script .pio\build\oneDayForecaster\ld\
Archiving .pio\build\oneDayForecaster\lib3f7\lib.pio
Compiling .pio\build\oneDayForecaster\lib3b2\SPI\SPI.cpp.o
Indexing .pio\build\oneDayForecaster\lib3f7\lib.pio
Compiling .pio\build\oneDayForecaster\lib631\ESP8266SdFat\FatLib\FatFile.cpp.o
Compiling .pio\build\oneDayForecaster\lib631\ESP8266SdFat\FatLib\FatFileLFN.cpp.o
E:/repos/GitHub/esp8266-weather-station/examples/oneDayForecaster/oneDayForecaster.ino:42:26: fatal error: Adafruit_GFX.h: No such file or directory

* Looking for Adafruit_GFX.h dependency? Check our library registry!
* CLI  > platformio lib search "header:Adafruit_GFX.h"
* Web  >

#include <Adafruit_GFX.h>
compilation terminated.
*** [.pio\build\oneDayForecaster\src\oneDayForecaster.ino.cpp.o] Error 1
==================================================== [FAILED] Took 19.48 seconds ====================================================

Environment         Status    Duration
------------------  --------  ------------
WeatherStationDemo  IGNORED
oneDayForecaster    FAILED    00:00:19.476
=============================================== 1 failed, 0 succeeded in 00:00:19.476 ===============================================

What is your goal? How are you going to compile a project with src where there is no main file with loop/setup?

I’m not sure I understand the question.

Don’t worry about issues with MetOfficeDemo and oneDayForecaster. They’re excluded from the Travis build as well for some reason :frowning:

However, I too am seeing the same behavior with other examples e.g. WeatherStationDemo. Platform IO doesn’t find the lib dependencies it had just installed seconds ago.

@ivankravets If you’re replying to me, I’m doing two things out of the ‘ordinary’ … By using the, PROJECT_SRC_DIR is changed to a directory with a *.ino file, so that condition is satisfied. Also, since the project revolves around the library examples, and the library is located in the \src directory, I set lib_dir = $PROJECT_DIR so that the library is found. It’s just that doing it this way seems to completely mess of the LDF and also means PIO doesn’t find libraries that have been downloaded. It would be nice if this could be made to work, or some variation of it… otherwise reverting to pio ci in a script looks to be the only viable option, just not so user friendly.

@marcelstoer :laughing: Now you tell me I picked one of the ones that didn’t work? :laughing:

@pfeerick great work so far!

I don’t know. Just noticed they’re not included in the CI build. Since I didn’t setup this project initially I wouldn’t know why that is…

P.S. for platform-independency I had to do something about \examples vs /examples in the script (os.path.join() or os.sep).

1 Like

Yeah, I noticed when compiling them for some reason they use ESPWiFi.h, not ESP8266WiFi.h … so that’s the first clue something ain’t quite right there! More importantly, is it getting anywhere with the other examples? Or falling flat on it’s face still? :frowning: I mainly stuck to the WeatherStationDemo, and it didn’t seem to get past finding the libraries, so more poking around there is needed.

It’s driving me crazy. None of the lib_dir/src_dir combinations I tested yield a successful build.

This rather minimal platformio.ini is very similar to the Travis CI definition. For now I stopped fiddling with the extra script.

lib_dir = "."

platform = espressif8266
board = d1_mini
framework = arduino
upload_speed = 921600
board_build.board_f_cpu = 160000000L
lib_deps =
    DHT sensor library
    Adafruit Unified Sensor

src_dir = examples/WeatherStationDemo

; more envs here

Compilation is fine but the linker fails with the errors reported in my first comment (undefined reference tosetup’`). Why would this work with CI but not if run locally.

Because you’re ignoring the warning at the top of the build log :stuck_out_tongue:

Warning! Ignore unknown configuration option src_dir in section [env:WeatherStationDemo]

src_dir is only valid for the global [platformio] block, as it’s meant to specify the src_dir for the entire project.

The ci command works completely differently to a normal run… where you pass the directory path to the source files, specify a board and optionally directory with library files or install the library if needed… and it goes out and runs completely independent.

The nearest I can get to that locally so far is to… reprodice the ci run locally… ie.

pio ci -b d1_mini -l . --project-option="lib_deps=JsonStreamingParser, ESP8266_SSD1306, simpleDSTadjust, DHT sensor library, Adafruit Unified Sensor" examples/WeatherStationDemo

It has the downside of installing the libraries every time, (the alternative of installing the libraries globally has too many other project breaking implications that it’s not worth doing), although at the same time, the upside being it’s a 100% clean build every time, since it’s in a temp folder.

Thank you for the great feedback, much appreciated.

I could certainly put this into a script; loop over all examples and run the CI build locally. However, it’s hard to accept that this is really the best solution. I thought that building an Arduino library with examples must be a pretty standard use case.

@ivankravets can you confirm that we are not missing something obvious?

You can’t use src_dir here. Do you see warnings in CLI? See Redirecting...

I just created an account just to say thank you, you really saved my day! :slight_smile: