Strange issue with compiling: under Linux fine, fails badly in Windows

Hi,

I’m trying to figure out why compiling of the project fails under Windows (Win7 and Win10 - latter was completely fresh install of VS Code + PlatformIO) where as the same project compiles fine under Linux.

Platform: Arduino MEGA 2560 pro
Additional libraries: HeliOS, Adafruit GFX, ModbusRTUMaster, Arduino_ST7789_FastMaster (not via libdeb but just added to lib folder beause this is not available via PlatformIO). Some basic libraries from Arduino such as SPI.

Problems started when I had to change from FreeRTOS to HeliOS (FreeRTOS caused severe issues in SPI communication with display due task switchin - disabling interrupts “solved” the problem but this is not a solution I can use). There was initially a problem with HeliOS.h file which have a small piece of code at the end. For some reason this got included many times despite the #ifdef guard. Moved this to own cpp-file and problem gone (wasn’t able to link it before this change).

Under Linux there’s no more errors and project compiles and links and also works in the target fine.

When I try to compile the same code under windows it produces 68 errors. All related to HeliOS files. Errors like:

previous definition of 'struct TaskNotification_s'
previous definition of 'struct TaskRunTimeStats_s'
previous definition of 'struct MemoryRegionStats_s'
previous definition of 'struct TaskInfo_s'
previous definition of 'struct QueueMessage_s'
previous definition of 'struct SystemInfo_s'

Actually 7 header files are producing errors and I find this pretty much impossible for a released library. So, something is wrong with the building but just cannot figure out what.

HeliOS is c-code, Arduino libs are c++ code and my code is c inside cpp-files. This has not been an issues previously in many other projects. I usually develop under Linux and then move to laptop to download to the target (target after testing is physically far away from Linux machine).

I have removed .vscode (rebuilt this after deletion) and framework-arduino-avr but no difference.

platformio.ini:

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
monitor_speed = 115200
lib_deps = 
	heliosproj/HeliOS@^0.4.1
	adafruit/Adafruit GFX Library@^1.11.3
	cmb27/ModbusRTUMaster@^1.0.5
lib_ldf_mode = chain
lib_compat_mode = soft

Any idea what could be the reason for this problem?

Dead giveaway that this is due to Windows’ filesystem, which is case-insensitive, as opposed to Linux, which is usually (ext4 etc.) case sensitive.

So, if e.g. the Helios project has some header file called stream.h while Arduino has Stream.h, and some code tries to #include <stream.h>, on Windows, since upper and lowercasing doens’t matter, it can’t correctly know which header file was meant.

If you look closely at an error message, exactly that is revealed:

In file included from .pio\libdeps\megaatmega2560\HeliOS\src/device.h:24:0,
                 from .pio\libdeps\megaatmega2560\HeliOS\src/port.h:23,
                 from .pio\libdeps\megaatmega2560\HeliOS\src/Stream.h:23,
                 from C:\Users\Max\.platformio\packages\framework-arduino-avr\libraries\Wire\src/Wire.h:27,
                 from .pio\libdeps\megaatmega2560\Adafruit BusIO/Adafruit_I2CDevice.h:5,
                 from .pio\libdeps\megaatmega2560\Adafruit GFX Library/Adafruit_GFX.h:12,
                 from src\main.cpp:4:
.pio\libdeps\megaatmega2560\HeliOS\src/mem.h:35:12: error: conflicting declaration of C function 'Return_t xMemFree(const volatile Addr_t*)'

It should immediately stand out that Wire.h includes the Stream.h from HelIOS, although the Arduino layer should not directly include HeliOS at all. And, when you look in the files

It’s immeidately visible that stream.h in HeliOS conflicts with Stream.hof the Arduino core.

To resolve this conflict, the library can be forked and the filenames and references can be changed to not conflict anymore. See e.g. here.

So,

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
monitor_speed = 115200
lib_deps = 
	https://github.com/maxgerhardt/HeliOS/archive/refs/heads/master.zip
	adafruit/Adafruit GFX Library@^1.11.3
	cmb27/ModbusRTUMaster@^1.0.5
lib_ldf_mode = chain
lib_compat_mode = soft

together with code


#include <Arduino.h>
#include <HeliOS.h>
#include <Adafruit_GFX.h>
#include <ModbusRTUMaster.h>

void setup() {
  if(ERROR(xSystemInit())) {
    xSystemHalt();
  }
  if(ERROR(xTaskStartScheduler())) {
    xSystemHalt();
  }
  xSystemHalt();
}

void loop() {}

compiles fine on Windows.

Linking .pio\build\megaatmega2560\firmware.elf
Checking size .pio\build\megaatmega2560\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]  13.0% (used 1061 bytes from 8192 bytes)
Flash: [          ]   0.4% (used 1054 bytes from 253952 bytes)
Building .pio\build\megaatmega2560\firmware.hex
===================[SUCCESS] Took 33.56 seconds ===================
3 Likes

WOW!! Thank you a lot for the solution! I would have not figured this out any day/week/month soon.

There is one more issue with the HeliOS.h (which I have reported to the developers). At the end of file there’s a piece of code that gets multiple times included despite the whole HeliOS.h is guarded at the beginning. I took it out and moved to cpp-file to get rid of the problem. This only occurs if HeliOS.h is included multiple times like it is done in my project.

1 Like

I know that this is super old, but I just wanted to chime in here and tell you that after several days of banging my head against this exact issue (originally compiled on Linux, but refused to compile on Windows) this comment made it click. I had foolishly named a file wifi.cpp and wifi.h, both of which called on WiFi.h - which was no issue on my Linux box.

Anyway - thank you very much, @maxgerhardt !

2 Likes