diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ee70f9..c96d3b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ # Changelog * Unreleased +* 1.3.0 (2022-03-28) + * Add support for `EXTRA_CPPFLAGS`, similar to `EXTRA_CXXFLAGS`. + * Add `digitalReadValue(pin, val)` to control the return value of + `digitalRead(pin)`. + * May be useful for testing purposes. + * The `pin` parameter must satisfy `0 <= pin < 32`, otherwise + `digitalReadValue()` is a no-op. + * See [PR#61](https://github.com/bxparks/EpoxyDuino/pull/61). + * Add an empty `EpoxyDuino.h` at the top level to stop warning messages from + the Arduino IDE. + * Fixes [Issue#62](https://github.com/bxparks/EpoxyDuino/issues/62). + * Add [libraries/EpoxyMockSTM32RTC](libraries/EpoxyMockSTM32RTC) + * A mock of the [STM32RTC](https://github.com/stm32duino/STM32RTC) + library. * 1.2.3 (2022-02-24) * Rename `unixhostduino_main()` to `epoxyduino_main()`, and make it static. No need to expose it publicly. diff --git a/EpoxyDuino.h b/EpoxyDuino.h new file mode 100644 index 0000000..4019046 --- /dev/null +++ b/EpoxyDuino.h @@ -0,0 +1,14 @@ +// This header file is empty. Its sole purpose is to disable warnings in the +// Arduino IDE which identifies EpoxyDuino as an invalid Arduino library when it +// is installed inside the Arduino sketchbook libraries directory. The warning +// message looks like this: +// +// "Invalid library found in /home/brian/src/arduino/libraries/EpoxyDuino: no +// headers files (.h) found in /home/brian/src/arduino/libraries/EpoxyDuino" +// +// EpoxyDuino is *not* an Arduino library. But it is very convenient to install +// it along side the other Arduino libraries so that it can search for those +// libraries as siblings to its own location when they are referenced in the +// `ARDUINO_LIBS` Makefile variable. It can be installed somewhere else, but you +// then have to define the `ARDUINO_LIB_DIRS` variable in all your Makefiles to +// tell EpoxyDuino where to look for those libraries. diff --git a/EpoxyDuino.mk b/EpoxyDuino.mk index aba4e3f..4537753 100644 --- a/EpoxyDuino.mk +++ b/EpoxyDuino.mk @@ -133,7 +133,7 @@ endif CXXFLAGS += $(EXTRA_CXXFLAGS) # Pre-processor flags (-I, -D, etc), mostly for header files. -CPPFLAGS ?= +CPPFLAGS += $(EXTRA_CPPFLAGS) # Define a macro to indicate that EpoxyDuino is being used. Defined here # instead of Arduino.h so that files like 'compat.h' can determine the # compile-time environment without having to include . diff --git a/README.md b/README.md index f8a97f5..24c4d1c 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ also provided: TimerOne (https://github.com/PaulStoffregen/TimerOne) library * [EpoxyMockFastLED](libraries/EpoxyMockFastLED/): mock version of the FastLED (https://github.com/FastLED/FastLED) library +* [EpoxyMockSTM32RTC](libraries/EpoxyMockSTM32RTC/): mock version of the + STM32RTC (https://github.com/stm32duino/STM32RTC) library These mock libraries may be sufficient for a CI pipeline. @@ -41,9 +43,10 @@ For actual application development, I have started to build a set of libraries within EpoxyDuino which emulate the versions that run the actual hardware: -* EpoxyFS: emulation of the ESP8266 LittleFS or ESP32 LittleFS -* EpoxyEepromAvr: emulation of AVR-flavored `EEPROM` -* EpoxyEepromEsp: emulation of ESP-flavored `EEPROM` +* [EpoxyFS](libraries/EpoxyFS): emulation of the ESP8266 LittleFS or + ESP32 LittleFS filesystem +* [EpoxyEepromAvr](libraries/EpoxyEepromAvr): emulation of AVR-flavored `EEPROM` +* [EpoxyEepromEsp](libraries/EpoxyEepromEsp): emulation of ESP-flavored `EEPROM` If your program has limited hardware dependencies so that it is conceptually portable to a vanilla Unix environment, EpoxyDuino may work well for you. @@ -68,7 +71,7 @@ The disadvantages are: environments (e.g. 16-bit `int` versus 32-bit `int`, or 32-bit `long` versus 64-bit `long`). -**Version**: 1.2.3 (2022-02-24) +**Version**: 1.3.0 (2022-03.28) **Changelog**: See [CHANGELOG.md](CHANGELOG.md) @@ -85,14 +88,17 @@ The disadvantages are: * [Continuous Integration](#ContinuousIntegration) * [Advanced Usage](#AdvancedUsage) * [Alternate C++ Compiler](#AlternateCompiler) - * [Generated Source Code](#GeneratedSourceCode) + * [Additional Cpp Flags](#AdditionalCppFlags) + * [Additional Compiler Flags](#AdditionalCompilerFlags) * [Additional Clean Up](#AdditionalCleanUp) * [Additional Dependencies](#AdditionalDependencies) + * [Generated Source Code](#GeneratedSourceCode) * [Alternate Arduino Core](#AlternateArduinoCore) * [PlatformIO](#PlatformIO) * [Command Line Flags and Arguments](#CommandLineFlagsAndArguments) * [Debugging](#Debugging) * [Valgrind](#Valgrind) + * [Controlling digitalRead()](#DigitalReadValue) * [Supported Arduino Features](#SupportedArduinoFeatures) * [Arduino Functions](#ArduinoFunctions) * [Serial Port Emulation](#SerialPortEmulation) @@ -449,52 +455,35 @@ Take a look at some of my GitHub Actions YAML config files: ### Alternate C++ Compiler Normally the C++ compiler on Linux is `g++`. If you have `clang++` installed -you can use that instead by specifying the `CXX` environment variable: +you can use that instead by specifying the `CXX` makefile variable: ``` -$ CXX=clang++ make +$ make CXX=clang++ ``` -(This sets the `CXX` shell environment variable temporarily, for the duration of -the `make` command, which causes `make` to set its internal `CXX` variable, -which causes `EpoxyDuino.mk` to use `clang++` over the default `g++`.) +(This tells `make` to set the `CXX` variable to `clang++` within the context of +`EpoxyDuino.mk` which causes `clang++` to be used over the default `g++`.) -The `clang++` compiler will sometimes catch a different set of programming -errors. +One reason to use `clang++` instead of `g++` is that the `clang++` compiler will +sometimes catch a different set of programming errors. - -### Generated Source Code + +### Additional Cpp Flags -If a source file is generated dynamically through a code generation script, -and the source file is *not* checked into the repository because it is too -dynamic, then you can include the generated files using the `GENERATED` -and the `OBJS` variables. - -First add the list of generated files `*.cpp` or `*.c` to the `GENERATED` -variable. Then add the corresponding `*.o` files to the `OBJS` variable, like -this: +You can pass additional flags to the C preprocessor through the `EXTRA_CPPFLAGS` +variable, like this: ``` -GENERATED := foo.cpp bar.cpp -OBJS := foo.o bar.o -APP_NAME := {name of project} -ARDUINO_LIBS := {list of dependent Arduino libraries} -include {path/to/EpoxyDuino.mk} +$ make EXTRA_CPPFLAGS='-D DEBUG=2' +``` -foo.cpp: foo.h generate_foo.sh - ./generate_foo.sh # creates 'foo.cpp' + +### Additional Compiler Flags -bar.cpp: bar.h generate_bar.sh - ./generate_bar.sh # creates 'bar.cpp' +You can pass additional flags to the C++ compiler through the `EXTRA_CXXFLAGS` +variable, like this: -... ``` - -The `*.o` files in `OJBS` are passed to the linker when the `app.out` binary -file is created. - -The `GENERATED` is not strictly required, since the default rules already know -how to compile the `*.o` files from the `*.cpp` or `*.c` files. The primary -effect of `GENERATED` currently is to cause the generated files to be removed -when `make clean` is called. +$ make EXTRA_CXXFLAGS='-g' +``` ### Additional Clean Up @@ -535,6 +524,42 @@ DEPS := header1.h header2.h include {path/to/EpoxyDuino.mk} ``` + +### Generated Source Code + +If a source file is generated dynamically through a code generation script, +and the source file is *not* checked into the repository because it is too +dynamic, then you can include the generated files using the `GENERATED` +and the `OBJS` variables. + +First add the list of generated files `*.cpp` or `*.c` to the `GENERATED` +variable. Then add the corresponding `*.o` files to the `OBJS` variable, like +this: + +``` +GENERATED := foo.cpp bar.cpp +OBJS := foo.o bar.o +APP_NAME := {name of project} +ARDUINO_LIBS := {list of dependent Arduino libraries} +include {path/to/EpoxyDuino.mk} + +foo.cpp: foo.h generate_foo.sh + ./generate_foo.sh # creates 'foo.cpp' + +bar.cpp: bar.h generate_bar.sh + ./generate_bar.sh # creates 'bar.cpp' + +... +``` + +The `*.o` files in `OJBS` are passed to the linker when the `app.out` binary +file is created. + +The `GENERATED` is not strictly required, since the default rules already know +how to compile the `*.o` files from the `*.cpp` or `*.c` files. The primary +effect of `GENERATED` currently is to cause the generated files to be removed +when `make clean` is called. + ### Alternate Arduino Core @@ -694,6 +719,45 @@ start: When the program crashes because of a `nullptr` dereference, Valgrind will show exactly where that happened in the source code. + +### Controlling digitalRead() + +By default, the `digitalRead(pin)` function simply returns a 0, because +EpoxyDuino does not actually have any hardware pins. For testing purposes, it +can be useful to control the value that will be returned by a `digitalRead()`. + +The `digitalReadValue(pin, val)` function sets the value that will be returned +by the corresponding `digitalRead(pin)`. Here is an example of how this can be +used: + +```C++ +#include + +... +const uint8_t PIN = 8; + +void something() { + uint8_t val = digitalRead(PIN); // val == 0 + +#if defined(EPOXY_DUINO) + digitalReadValue(PIN, 1); +#endif + val = digitalRead(PIN); // val == 1 + +#if defined(EPOXY_DUINO) + digitalReadValue(PIN, 0); +#endif + val = digitalRead(PIN); // val == 0 +} +``` + +The `#if defined(EPOXY_DUINO)` is recommended because `digitalReadValue()` is +not a standard Arduino function. It is defined only in EpoxyDuino. + +The `pin` parameter should satisfy `0 <= pin < 32`. If `pin >= 32`, then +`digitalReadValue()` is a no-op and the corresponding `digitalRead(pin)` will +always return 0. + ## Supported Arduino Features @@ -799,8 +863,6 @@ worth the trade-off. #### Unix Line Mode -(Added in v1.2.0) - The `Print` class in the Arduino API implements the `Print::println()` function by printing the DOS line terminator characters `\r\n`. This decision make sense when the serial port of the microcontroller is connected to a serial terminal, @@ -873,8 +935,6 @@ test(myTest) { #### Enable Terminal Echno -(Added in v1.2.3) - By default, the `stdin` of the terminal is set to `NOECHO` mode for consistency with the actual serial port of an Arduino microcontroller. However when running a command line utility on a Unix terminal emulator using EpoxyDuino, it is often @@ -1004,6 +1064,9 @@ intended. This limitation may be sufficient for Continuous Integration purposes. library. * [EpoxyMockFastLED](libraries/EpoxyMockFastLED/) * Mock version of the FastLED (https://github.com/FastLED/FastLED) library. +* [EpoxyMockSTM32RTC](libraries/EpoxyMockSTM32RTC/) + * Mock version of the STM32RTC (https://github.com/stm32duino/STM32RTC) + library. * EspMock (https://github.com/hsaturn/EspMock) * This is a separate project that provides various mocks for functions and libraries included with the ESP8266 and the ESP32 processors. @@ -1015,18 +1078,18 @@ intended. This limitation may be sufficient for Continuous Integration purposes. This library has Tier 1 support on: -* Ubuntu 18.04 - * g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 - * clang++ 8.0.0-3~ubuntu18.04.2 - * clang++ 6.0.0-1ubuntu2 - * GNU Make 4.1 -* Ubuntu 20.04 - * g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0 +* Ubuntu 20.04.4 LTS + * g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 * clang++ version 10.0.0-4ubuntu1 * GNU Make 4.2.1 The following environments are Tier 2 because I do not test them often enough: +* Ubuntu 18.04 LTS + * g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 + * clang++ 8.0.0-3~ubuntu18.04.2 + * clang++ 6.0.0-1ubuntu2 + * GNU Make 4.1 * Raspbian GNU/Linux 10 (buster) * On Raspberry Pi Model 3B * g++ (Raspbian 8.3.0-6+rpi1) 8.3.0 @@ -1136,3 +1199,6 @@ people ask similar questions later. see [PR#32](https://github.com/bxparks/EpoxyDuino/pull/32). * Simplify `StdioSerial` by Bernhard (@felias-fogg), [Issue#43](https://github.com/bxparks/EpoxyDuino/issues/43). +* Add `digitalReadValue(pin, val)` to control the return value of + `digitalRead(pin)` by @CaioPellicani. See + [PR#61](https://github.com/bxparks/EpoxyDuino/pull/61). diff --git a/cores/epoxy/Arduino.cpp b/cores/epoxy/Arduino.cpp index 1f196da..ce537fe 100644 --- a/cores/epoxy/Arduino.cpp +++ b/cores/epoxy/Arduino.cpp @@ -21,6 +21,8 @@ // Arduino methods emulated in Unix // ----------------------------------------------------------------------- +static uint32_t digitalPinValues = 0; + void yield() { usleep(1000); // prevents program from consuming 100% CPU } @@ -29,7 +31,21 @@ void pinMode(uint8_t /*pin*/, uint8_t /*mode*/) {} void digitalWrite(uint8_t /*pin*/, uint8_t /*val*/) {} -int digitalRead(uint8_t /*pin*/) { return 0; } +int digitalRead(uint8_t pin) { + if (pin >= 32) return 0; + + return (digitalPinValues & (((uint32_t)0x1) << pin)) != 0; +} + +void digitalReadValue(uint8_t pin, uint8_t val) { + if (pin >= 32) return; + + if (val == 0) { + digitalPinValues &= ~(((uint32_t)0x1) << pin); + } else { + digitalPinValues |= ((uint32_t)0x1) << pin; + } +} int analogRead(uint8_t /*pin*/) { return 0; } diff --git a/cores/epoxy/Arduino.h b/cores/epoxy/Arduino.h index dfa38b5..cdc18db 100644 --- a/cores/epoxy/Arduino.h +++ b/cores/epoxy/Arduino.h @@ -14,8 +14,8 @@ #define EPOXY_DUINO_EPOXY_ARDUINO_H // xx.yy.zz => xxyyzz (without leading 0) -#define EPOXY_DUINO_VERSION 10203 -#define EPOXY_DUINO_VERSION_STRING "1.2.3" +#define EPOXY_DUINO_VERSION 10300 +#define EPOXY_DUINO_VERSION_STRING "1.3.0" #include // min(), max() #include // abs() @@ -223,6 +223,18 @@ void analogWrite(uint8_t pin, int val); void analogWriteRange(uint32_t range); #endif +/** + * Control the value that will be returned by `digitalRead(pin)` by setting it + * to `val`, where `val` is either 0 or 1. This may be useful for testing + * purposes. This works only if `pin < 32` because the underlying implementation + * uses a `uint32_t` for storage. If the `pin` is greater than or equal to 32, + * this function does nothing and `digitalRead(pin)` will return 0. + * + * This function is available only on EpoxyDuino. It is not a standard Arduino + * function, so it is not available when compiling on actual hardware. + */ +void digitalReadValue(uint8_t pin, uint8_t val); + unsigned long millis(); unsigned long micros(); void delay(unsigned long ms); diff --git a/libraries/EpoxyMockSTM32RTC/EpoxyMockSTM32RTC.h b/libraries/EpoxyMockSTM32RTC/EpoxyMockSTM32RTC.h new file mode 100644 index 0000000..de88363 --- /dev/null +++ b/libraries/EpoxyMockSTM32RTC/EpoxyMockSTM32RTC.h @@ -0,0 +1,151 @@ +#ifndef EPOXY_MOCK_STM32RTC_H +#define EPOXY_MOCK_STM32RTC_H + +#include // uint8_t + +//----------------------------------------------------------------------------- +// Typedefs from STM32RTC/rtc.h +//----------------------------------------------------------------------------- + +typedef enum { + HOUR_FORMAT_12, + HOUR_FORMAT_24 +} hourFormat_t; + +typedef enum { + HOUR_AM, + HOUR_PM +} hourAM_PM_t; + +//----------------------------------------------------------------------------- +// Typedefs from cores/arduino/stm32/clock.h +//----------------------------------------------------------------------------- + +typedef enum { + LSI_CLOCK, + HSI_CLOCK, + LSE_CLOCK, + HSE_CLOCK +} sourceClock_t; + +//----------------------------------------------------------------------------- + +/** + * A mock version of the STM32RTC class in the + * https://github.com/stm32duino/STM32RTC library. Only the clock-related + * functions are mocked. The alarm-related functions are ignored. + */ +class STM32RTC { + public: + + enum Hour_Format : uint8_t { + HOUR_12 = HOUR_FORMAT_12, + HOUR_24 = HOUR_FORMAT_24 + }; + + enum AM_PM : uint8_t { + AM = HOUR_AM, + PM = HOUR_PM + }; + + enum Source_Clock : uint8_t { + LSI_CLOCK = ::LSI_CLOCK, + LSE_CLOCK = ::LSE_CLOCK, + HSE_CLOCK = ::HSE_CLOCK + }; + + static STM32RTC &getInstance() { + static STM32RTC instance; // Guaranteed to be destroyed. + // Instantiated on first use. + return instance; + } + + STM32RTC(STM32RTC const &) = delete; + void operator=(STM32RTC const &) = delete; + + void begin(bool resetTime, Hour_Format format = HOUR_24) { + (void) resetTime; + (void) format; + } + void begin(Hour_Format format = HOUR_24) { + (void) format; + } + + void end(void) {} + + Source_Clock getClockSource(void) { return _clockSource; } + void setClockSource(Source_Clock source) { _clockSource = source; } + + /* Get Functions */ + + uint32_t getSubSeconds(void) { return 0; } + uint8_t getSeconds(void) { return 0; } + uint8_t getMinutes(void) { return 0; } + uint8_t getHours(AM_PM *period = nullptr) { + (void) period; + return 0; + } + void getTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, + uint32_t *subSeconds, AM_PM *period = nullptr) { + (void) hours; + (void) minutes; + (void) seconds; + (void) subSeconds; + (void) period; + } + + uint8_t getWeekDay(void) { return 1; } + uint8_t getDay(void) { return 1; } + uint8_t getMonth(void) { return 1; } + uint8_t getYear(void) { return 0; } + void getDate( + uint8_t *weekDay, uint8_t *day, uint8_t *month, uint8_t *year) { + (void) weekDay; + (void) day; + (void) month; + (void) year; + } + + /* Set Functions */ + + void setSubSeconds(uint32_t subSeconds) { (void) subSeconds; } + void setSeconds(uint8_t seconds) { (void) seconds; } + void setMinutes(uint8_t minutes) { (void) minutes; } + void setHours(uint8_t hours, AM_PM period = AM) { + (void) hours; + (void) period; + } + void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds, + uint32_t subSeconds = 1000, AM_PM period = AM) { + (void) hours; + (void) minutes; + (void) seconds; + (void) subSeconds; + (void) period; + } + + void setWeekDay(uint8_t weekDay) { (void) weekDay; } + void setDay(uint8_t day) { (void) day; } + void setMonth(uint8_t month) { (void) month; } + void setYear(uint8_t year) { (void) year; } + void setDate(uint8_t day, uint8_t month, uint8_t year) { + (void) day; + (void) month; + (void) year; + } + void setDate(uint8_t weekDay, uint8_t day, uint8_t month, uint8_t year) { + (void) weekDay; + (void) day; + (void) month; + (void) year; + } + + bool isTimeSet(void) { return true; } + + private: + STM32RTC(void): _clockSource(LSI_CLOCK) {} + + Source_Clock _clockSource; +}; + +#endif diff --git a/libraries/EpoxyMockSTM32RTC/README.md b/libraries/EpoxyMockSTM32RTC/README.md new file mode 100644 index 0000000..bf32bec --- /dev/null +++ b/libraries/EpoxyMockSTM32RTC/README.md @@ -0,0 +1,35 @@ +# EpoxyMockSTM32RTC Library + +This library provides a mock implementation of the `STM32RTC` class from the +[STM32RTC](https://github.com/stm32duino/STM32RTC) library. It provides just +enough functionality to run unit tests and a small demo. Only the date and time +functions are provided. The alarm functions are missing because AceTime does not +support alarms. + +## Usage + +Add `EpoxyMockSTM32RTC` to the `ARDUINO_LIBS` in the EpoxyDuino `Makefile` of +the application: + +```make +APP_NAME := MyApp +ARDUINO_LIBS := AceCommon AceSorting AceTime AceTimeClock EpoxyMockSTM32RTC ... +include ../../../../EpoxyDuino.mk +``` + +In the code where `#include ` appears, use the following instead: + +```C++ +#if defined(EPOXY_DUINO) + #include +#else + #include +#endif +``` + +The `EpoxyMockSTM32RTC.h` could have been named `STM32RTC.h` to avoid the `#if +defined()`, but I wanted to make it clear that `EpoxyMockSTM32RTC.h` does not +provide an *emulation* of the `STM32RTC.h` functionality. If the +`` implementation was hooked up to the Unix `time_t +time(nullptr)` function, then I think it would be appropriate to rename it to +just ``. diff --git a/library.json b/library.json index 9a16bfc..0d44d7e 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "EpoxyDuino", - "version": "1.2.3", + "version": "1.3.0", "description": "Compile and run Arduino programs natively on Linux, MacOS and FreeBSD.", "keywords": [ "unit-test", diff --git a/tests/DigitalReadTest/DigitalReadTest.ino b/tests/DigitalReadTest/DigitalReadTest.ino new file mode 100644 index 0000000..b364cde --- /dev/null +++ b/tests/DigitalReadTest/DigitalReadTest.ino @@ -0,0 +1,50 @@ +#line 2 "DigitalReadTest" + +#include +#include + +using aunit::TestRunner; + +//--------------------------------------------------------------------------- + +test(DigitalReadTest, digitalReadValue_valid) { + // Verify that pins return 0 initially. + assertEqual(digitalRead(0), 0); + assertEqual(digitalRead(31), 0); + assertEqual(digitalRead(32), 0); + + // Set the values of those pins to 1. Pin 32 should be a no-op. + digitalReadValue(0, 1); + digitalReadValue(31, 1); + digitalReadValue(32, 1); + + // Check that those pins return 1. Pin 32 continues to return 0. + assertEqual(digitalRead(0), 1); + assertEqual(digitalRead(31), 1); + assertEqual(digitalRead(32), 0); + + // Set the values of those pins to 0. Pin 32 should be a no-op. + digitalReadValue(0, 0); + digitalReadValue(31, 0); + digitalReadValue(32, 0); + + // Check that those pins return 0. + assertEqual(digitalRead(0), 0); + assertEqual(digitalRead(31), 0); + assertEqual(digitalRead(32), 0); +} + +//--------------------------------------------------------------------------- + +void setup() { +#if ! defined(EPOXY_DUINO) + delay(1000); // wait to prevent garbage on SERIAL_PORT_MONITOR +#endif + + SERIAL_PORT_MONITOR.begin(115200); + while (!SERIAL_PORT_MONITOR); // needed for Leonardo/Micro +} + +void loop() { + TestRunner::run(); +} diff --git a/tests/DigitalReadTest/Makefile b/tests/DigitalReadTest/Makefile new file mode 100644 index 0000000..d4b2244 --- /dev/null +++ b/tests/DigitalReadTest/Makefile @@ -0,0 +1,6 @@ +# See https://github.com/bxparks/EpoxyDuino for documentation about this +# Makefile to compile and run Arduino programs natively on Linux or MacOS. + +APP_NAME := DigitalReadTest +ARDUINO_LIBS := AUnit +include ../../EpoxyDuino.mk diff --git a/tests/Makefile b/tests/Makefile index 5529273..3cd6316 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,7 +1,16 @@ +# Tests in this directory require different EPOXY_CORE_xxx global macros to be +# defined. When the EPOXY_CORE macro is changed, we must perform a `make clean` +# to recompile various source files. Unfortunately, that means we have to +# inserting a 'make clean' between tests. +# +# **WARNING**: If you copy this Makefile, consider removing the `make clean` +# between each iteration of the `for` loop. Most applications do NOT need to do +# that. tests: set -e; \ for i in *Test/Makefile; do \ echo '==== Making:' $$(dirname $$i); \ + $(MAKE) -C $$(dirname $$i) clean; \ $(MAKE) -C $$(dirname $$i) -j; \ done @@ -9,6 +18,8 @@ runtests: set -e; \ for i in *Test/Makefile; do \ echo '==== Running:' $$(dirname $$i); \ + $(MAKE) -C $$(dirname $$i) clean; \ + $(MAKE) -C $$(dirname $$i) -j all; \ $$(dirname $$i)/$$(dirname $$i).out; \ done