Missing Arduino.h when building `native` environment

Hello, I loaded calculator example into PlatformIO IDE(VSCode). I switched to native profile
image

Build fails:

Similar behavior happens in CLion(with plugin).

Is there a way to fix it, and how to run tests from IDE?

Hello @sith

What you trying to do is to build the arduino project on native environment (i.e. your PC). That can’t work, your OS cannot comprehend arduino and can’t create an executable of it, because the code is made for embedded devices, not for your computer OS.

In calculator example, native environment should be used for testing only (because the library of the project can be comprehended by the OS, as opposed to the main.cpp in the src folder).

See here for more information, especially the note about gcc (if you are a wWindows user at least).

About running through IDE, I don’t know about VSCode, but for CION you have to add “PlatformIO Test” profile, then select it, choose “native”, and run it:

image

It does not work for me. Here is noop project - GitHub - sith/HelloWorld_Arduino. Clicking run as you suggested prints error message.

Compiling .pio/build/native/src/main.o
src/main.cpp:1:10: fatal error: 'Arduino.h' file not found
#include <Arduino.h>
         ^~~~~~~~~~~
1 error generated.
*** [.pio/build/native/src/main.o] Error 1
 [FAILED] Took 0.70 seconds 

It looks like platformio tries to compile src folder and of course it fails.
It only works from command line - that is not a good option. The same situation happens in VSCode.

To run test, it needs to be build, so I suspect CLI environment understands what needs to be compiled. If this understanding is correct, IDE implementations are not that smart.

Most of the components in the code won’t depend on board components. For example if I am implementing PID controller, I can de-couple it with hardware stuff and have tests specifically for the logic. I want to write this tests and run locally. With usage of templates or inheritance I abstract out implementation details and can supply my test stubs for sensors, displays, motors etc. In that case I can make sure my core logic is correct. Next I can run those unit tests on the board to ensure my core code works there.

As of now, I cannot do it unless I use command line command.

Bigger integration test with real things(sensors, motors etc), Is much harder and probably subject for other tools.

The calculator example on the native platform isn’t supposed to build but to test. See original repo: platformio-examples/unit-testing/calculator at develop · platformio/platformio-examples · GitHub

And there’s no difference between IDE and CLI usage. Building also fails on the CLI, of course.

C:\Users\Maxi\Desktop\platformio-examples\unit-testing\calculator>pio run -e native
Processing native (platform: native)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 1 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <calculator>
Building in release mode
Compiling .pio\build\native\src\main.o
Compiling .pio\build\native\lib46a\calculator\calculator.o
src\main.cpp:17:10: fatal error: Arduino.h: No such file or directory

*****************************************************************
* Looking for Arduino.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:Arduino.h"
* Web  > https://platformio.org/lib/search?query=header:Arduino.h
*
*****************************************************************

 #include <Arduino.h>
          ^~~~~~~~~~~
compilation terminated.
*** [.pio\build\native\src\main.o] Error 1
======================================================================================================== [FAILED] Took 3.05 seconds ========================================================================================================

Environment    Status    Duration
-------------  --------  ------------
native         FAILED    00:00:03.050
=================================================================================================== 1 failed, 0 succeeded in 00:00:03.050 ===================================================================================================

Testing works as expected.


C:\Users\Maxi\Desktop\platformio-examples\unit-testing\calculator>pio test -e native
Verbose mode can be enabled via `-v, --verbose` option
Collected 3 items

Processing test_common in native environment
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Building...
Testing...
test\test_common\test_calculator.cpp:48:test_function_calculator_addition       [PASSED]
test\test_common\test_calculator.cpp:49:test_function_calculator_subtraction    [PASSED]
test\test_common\test_calculator.cpp:50:test_function_calculator_multiplication [PASSED]
test\test_common\test_calculator.cpp:51:test_function_calculator_division       [PASSED]

-----------------------
4 Tests 0 Failures 0 Ignored
OK
======================================================================================================== [PASSED] Took 2.73 seconds ========================================================================================================

Processing test_desktop in native environment
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Building...
Testing...
test\test_desktop\test_calculator.cpp:48:test_function_calculator_addition      [PASSED]
test\test_desktop\test_calculator.cpp:49:test_function_calculator_subtraction   [PASSED]
test\test_desktop\test_calculator.cpp:50:test_function_calculator_multiplication        [PASSED]
test\test_desktop\test_calculator.cpp:43:test_function_calculator_division:FAIL: Expected 32 Was 33     [FAILED]

Okay a caveat in CLion is that you must remove the “Before launch: Build” action from the configuration so that it doesn’t attempt to compile normally and just execute the test (which will in turn do the compilation).

Works fine when pressing the play button then

(One test failure is expected since that’s deliberate.)

1 Like

That works because calculator library does not depend on any Arduino libs. Here is my playground project - HelloWorld_Arduino/main.cpp at master · sith/HelloWorld_Arduino · GitHub. If I uncomment this line of code, native tests are failing.

I was thinking more in a concept of local/remote testing - it primarily comes from desire to not couple software to board specifics. In this case I can port core logic across boards without a problem.

With current approach it is not clear to me what is the point in native env. None of the libraries for specific boards will work in native env.

My knowledge here is very limited but I assume that envs must share the same framework otherwise it is not clear who the whole thing will compile.

If you write buisiness logic in a purely platform-independent way, you’re able to thus test it without any depdencies nicely on desktop. Also, mocking exists, so with examples like GitHub - FabioBatSilva/ArduinoFake: Arduino mocking made easy you are well-able to mock the return value of functions and classes to still be able to test natively, without the need for the actual hardware.

Unable to reproduce. If I use your project code and setup the test target as shown above, I get

The way I solved it my project, which borrows alot from the calculator example, was to restrict native configuration to build only src/native directory which shouldn’t contain any Arduino specific code. In simplest case it should just contain a single C file with main function defined in it.

[env:native]
platform = native
build_type = debug
build_flags = -D DEBUG
build_src_filter = -<*> +<native> ;that's the way we exclude/include dirs
test_ignore = test_embedded

This setup allows to test classes under lib directory, again provided they are platform-agnostic.