Skip to content

Commit e84a534

Browse files
authored
Merge pull request #73 from bxparks/develop
merge 1.5.0 into master
2 parents a344895 + c649408 commit e84a534

File tree

15 files changed

+186
-56
lines changed

15 files changed

+186
-56
lines changed

.github/workflows/aunit_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ on: [push]
1818
jobs:
1919
build:
2020

21-
runs-on: ubuntu-20.04
21+
runs-on: ubuntu-latest
2222

2323
steps:
24-
- uses: actions/checkout@v2
24+
- uses: actions/checkout@v3
2525

2626
- name: Setup
2727
run: |

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
# Changelog
22

33
* Unreleased
4+
* 1.5.0 (2022-12-08)
5+
* Support compiling plain `*.c` files in libraries and in the application.
6+
* The C files are assumed to be written in C11.
7+
* Define the `-D ARDUINO=100` macro.
8+
* Some 3rd party libraries test for `ARDUINO >= 100` to check if it's
9+
being compiled under Arduino.
10+
* Many will compile under EpoxyDuino with this macro set.
11+
* Add `make run` target which runs the binary generated by `make all`.
12+
* Useful in the `vim` editor where `:make run` will invoke the quickfix
13+
feature so that the editor will jump directly to the file and line
14+
where the AUnit assertion failure occurred.
15+
* Update the example `for` loops to invoke `make -C {dir} run` instead
16+
of running the binary directly. The `vim` editor can parse the output
17+
caused by the `-C` flag, and automatically generate the correct path
18+
to the files in the subdirectories.
419
* 1.4.0 (2022-11-06)
520
* Add `memcmp_P()` by @dawidchyrzynski in
621
[PR#71](https://github.com/bxparks/EpoxyDuino/pull/71).

EpoxyDuino.mk

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,19 @@ EPOXY_DUINO_PARENT_DIR := $(abspath $(EPOXY_DUINO_DIR)/..)
6868
# directory.
6969
ARDUINO_LIB_DIRS ?=
7070

71-
# C macro to select a specific core. Valid options are:
72-
# EPOXY_CORE_AVR (default), EPOXY_CORE_ESP8266.
71+
# CPP macro to select a specific core. Valid options are:
72+
# EPOXY_CORE_AVR (default), and EPOXY_CORE_ESP8266.
7373
EPOXY_CORE ?= EPOXY_CORE_AVR
7474

7575
# Define the directory where the <Arduino.h> and other core API files are
7676
# located. The default is $(EPOXY_DUINO_DIR)/cores/epoxy.
7777
EPOXY_CORE_PATH ?= $(EPOXY_DUINO_DIR)/cores/epoxy
7878

7979
# Find the directory paths of the libraries listed in ARDUINO_LIBS by looking
80-
# under directory given by EPOXY_DUINO_LIB_DIR, the directory given by
81-
# EPOXY_DUINO_PARENT_DIR to look for siblings, and each directory listed in
82-
# ARDUINO_LIB_DIRS.
80+
# at the following:
81+
# 1) under the directory given by EPOXY_DUINO_LIB_DIR,
82+
# 2) the sibling directories under EPOXY_DUINO_PARENT_DIR, and
83+
# 3) each directory listed in ARDUINO_LIB_DIRS.
8384
EPOXY_MODULES := $(foreach lib,$(ARDUINO_LIBS),${EPOXY_DUINO_LIB_DIR}/${lib})
8485
EPOXY_MODULES += $(foreach lib,$(ARDUINO_LIBS),${EPOXY_DUINO_PARENT_DIR}/${lib})
8586
EPOXY_MODULES += \
@@ -118,27 +119,37 @@ EPOXY_MODULES += \
118119
# like c++ on FreeBSD is actualy clang++. It's possible that FreeBSD has the
119120
# latest GNU version of libstdc++, but I'm not sure.
120121
#
121-
# I added EXTRA_CXXFLAGS to allow end-user Makefiles to specify additional
122-
# CXXFLAGs.
122+
# The CFLAGS assume that any C files are C11 files (not C99) because my
123+
# AceTimeC library requires C11. It may be possible to override that by passing
124+
# the `-std=c99` flag in the EXTRA_CFLAGS variable (which overrides the
125+
# `-std=c11` flag), but this has not been tested.
126+
#
127+
# I added EXTRA_CXXFLAGS and EXTRA_CFLAGS to allow end-user Makefiles to
128+
# specify additional flags to CXXFLAGS and CFLAGS.
123129
ifeq ($(UNAME), Linux)
124130
CXX ?= g++
125-
CXXFLAGS ?= -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -flto
131+
CXXFLAGS ?= -Wextra -Wall -std=gnu++11 -flto \
132+
-fno-exceptions -fno-threadsafe-statics
133+
CFLAGS ?= -Wextra -Wall -std=c11 -flto
126134
else ifeq ($(UNAME), Darwin)
127135
CXX ?= clang++
128136
CXXFLAGS ?= -Wextra -Wall -std=c++11 -stdlib=libc++
137+
CFLAGS ?= -Wextra -Wall -std=c11
129138
else ifeq ($(UNAME), FreeBSD)
130139
CXX ?= clang++
131140
CXXFLAGS ?= -Wextra -Wall -std=c++11 -stdlib=libc++
141+
CFLAGS ?= -Wextra -Wall -std=c11
132142
endif
133143
CXXFLAGS += $(EXTRA_CXXFLAGS)
144+
CFLAGS += $(EXTRA_CFLAGS)
134145

135146
# Pre-processor flags (-I, -D, etc), mostly for header files.
136147
CPPFLAGS += $(EXTRA_CPPFLAGS)
137148
# Define a macro to indicate that EpoxyDuino is being used. Defined here
138149
# instead of Arduino.h so that files like 'compat.h' can determine the
139150
# compile-time environment without having to include <Arduino.h>.
140151
# Also define UNIX_HOST_DUINO for backwards compatibility.
141-
CPPFLAGS += -D UNIX_HOST_DUINO -D EPOXY_DUINO -D $(EPOXY_CORE)
152+
CPPFLAGS += -D ARDUINO=100 -D UNIX_HOST_DUINO -D EPOXY_DUINO -D $(EPOXY_CORE)
142153
# Add the header files for the Core files.
143154
CPPFLAGS += -I$(EPOXY_CORE_PATH)
144155
# Add the header files for libraries. Old Arduino libraries place the header
@@ -150,52 +161,88 @@ CPPFLAGS += $(foreach module,$(EPOXY_MODULES),$(CPPFLAGS_EXPANSION))
150161
# Linker settings (e.g. -lm).
151162
LDFLAGS ?=
152163

153-
# Generate list of C++ srcs to compile.
164+
# Collect list of C and C++ srcs to compile.
154165
#
155-
# 1) Add the source files in the Core directory. Support subdirectory
166+
# 1) Collect the source files in the Epoxy Core directory. Support subdirectory
156167
# expansions up to 3 levels below the given target. (There might be a better
157168
# way to do this using GNU Make but I can't find a mechanism that doesn't barf
158169
# when the 'src/' directory doesn't exist.)
159170
EPOXY_SRCS := $(wildcard $(EPOXY_CORE_PATH)/*.cpp) \
160171
$(wildcard $(EPOXY_CORE_PATH)/*/*.cpp) \
161172
$(wildcard $(EPOXY_CORE_PATH)/*/*/*.cpp) \
162173
$(wildcard $(EPOXY_CORE_PATH)/*/*/*/*.cpp)
163-
# 2) Add the source files of the libraries. Old Arduino libraries place the
164-
# source files at the top level. Later Arduino libraries put the source files
165-
# under the src/ directory. Also support 3 levels of subdirectories.
166-
MODULE_EXPANSION = $(wildcard $(module)/*.cpp) \
174+
# 2) Collect the source files of the libraries referenced by the EPOXY_MODULES
175+
# parameter. Old Arduino libraries place the source files at the top level.
176+
# Later Arduino libraries put the source files under the src/ directory. Also
177+
# support 3 levels of subdirectories. Support both C and C++ libraries files.
178+
MODULE_EXPANSION_CPP = $(wildcard $(module)/*.cpp) \
167179
$(wildcard $(module)/src/*.cpp) \
168180
$(wildcard $(module)/src/*/*.cpp) \
169181
$(wildcard $(module)/src/*/*/*.cpp) \
170182
$(wildcard $(module)/src/*/*/*/*.cpp)
171-
EPOXY_SRCS += $(foreach module,$(EPOXY_MODULES),$(MODULE_EXPANSION))
172-
# 3) Add the source files in the application directory, also 3 levels down.
173-
EPOXY_SRCS += $(wildcard *.cpp) $(wildcard */*.cpp) $(wildcard */*/*.cpp) \
183+
MODULE_EXPANSION_C = $(wildcard $(module)/*.c) \
184+
$(wildcard $(module)/src/*.c) \
185+
$(wildcard $(module)/src/*/*.c) \
186+
$(wildcard $(module)/src/*/*/*.c) \
187+
$(wildcard $(module)/src/*/*/*/*.c)
188+
MODULE_SRCS_CPP += $(foreach module,$(EPOXY_MODULES),$(MODULE_EXPANSION_CPP))
189+
MODULE_SRCS_C += $(foreach module,$(EPOXY_MODULES),$(MODULE_EXPANSION_C))
190+
# 3) Collect the source files in the application directory, also 3 levels down.
191+
APP_SRCS_CPP += $(wildcard *.cpp) \
192+
$(wildcard */*.cpp) \
193+
$(wildcard */*/*.cpp) \
174194
$(wildcard */*/*/*.cpp)
175-
176-
# Objects including *.o from *.ino
177-
OBJS += $(EPOXY_SRCS:%.cpp=%.o) $(APP_NAME).o
178-
179-
# Finally, the rule to generate the binary for the application.
195+
APP_SRCS_C += $(wildcard *.c) \
196+
$(wildcard */*.c) \
197+
$(wildcard */*/*.c) \
198+
$(wildcard */*/*/*.c)
199+
200+
# Generate the list of object files from the *.cpp, *.c, and *.ino files.
201+
OBJS += $(EPOXY_SRCS:%.cpp=%.o)
202+
OBJS += $(MODULE_SRCS_CPP:%.cpp=%.o)
203+
OBJS += $(MODULE_SRCS_C:%.c=%.o)
204+
OBJS += $(APP_SRCS_CPP:%.cpp=%.o)
205+
OBJS += $(APP_SRCS_C:%.c=%.o)
206+
OBJS +=$(APP_NAME).o
207+
208+
# Finally the rule to generate the *.out binary file for the application.
180209
$(APP_NAME).out: $(OBJS)
181210
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
182211

183212
# We need to add a rule to treat .ino file as just a normal .cpp.
184213
$(APP_NAME).o: $(APP_NAME).ino $(DEPS)
185214
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -x c++ -c $<
186215

187-
%.o: %.cpp
188-
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
189-
190-
# This simple rule does not capture all header dependencies of a given cpp
191-
# file. Maybe it's better to make each cpp to depend on all headers of a given
192-
# module, and force a recompilation of all cpp files. As far as I understand,
193-
# this is what the Arduino IDE does upon each compile iteration.
216+
# We don't need this rule because the implicit GNU Make rules for converting
217+
# *.c and *.cpp into *.o files are sufficient.
218+
#
219+
# %.o: %.cpp
220+
# $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
221+
222+
# The following simple rules do not capture all header dependencies of a given
223+
# *.cpp or *.c file. It's probably better to make each *.cpp and *.c to depend
224+
# on all headers of a given module, and force a recompilation of all the files.
225+
# As far as I understand, this is what the Arduino IDE does upon each compile
226+
# iteration. But this is good enough for now, but has the disadvantage that we
227+
# have to run `make clean` more often than necessary to reset all the
228+
# dependencies.
194229
%.cpp: %.h
230+
%.c: %.h
195231

196-
.PHONY: all clean $(MORE_CLEAN)
232+
.PHONY: all clean run $(MORE_CLEAN)
197233

234+
# Use 'make all' or just 'make' to compile the binary.
198235
all: $(APP_NAME).out
199236

237+
# Use 'make run' to run the binary created by 'make all'. This is useful when
238+
# the (APP_NAME).out is an AUnit unit test. You can execute ': make run' inside
239+
# the vim editor. The error message of AUnit (as of v1.7) is compatible with
240+
# the quickfix errorformat of vim, so vim will automatically detect assertion
241+
# errors and jump directly to the line where the assertion failed.
242+
run:
243+
./$(APP_NAME).out
244+
245+
# Use 'make clean' to remove intermediate '*.o' files, the target '*.out' file,
246+
# and any generated files defined by $(GENERATED).
200247
clean: $(MORE_CLEAN)
201248
rm -f $(OBJS) $(APP_NAME).out $(GENERATED)

README.md

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ The disadvantages are:
7171
environments (e.g. 16-bit `int` versus 32-bit `int`, or 32-bit `long` versus
7272
64-bit `long`).
7373

74-
**Version**: 1.4.0 (2022-11-06)
74+
**Version**: 1.5.0 (2022-12-08)
7575

7676
**Changelog**: See [CHANGELOG.md](CHANGELOG.md)
7777

@@ -195,11 +195,20 @@ $ make clean
195195
$ make
196196
```
197197

198-
The executable will be created with a `.out` extension. To run it, just type:
198+
The executable will be created with a `.out` extension. To run it, type
199+
one of the following:
199200
```
200201
$ ./BlinkSOS.out
202+
$ make run
201203
```
202204

205+
If you run `:make run` command inside the `vim` editor, it knows how to parse
206+
the file and line number contained in the assertion messages generated by
207+
[AUnit](https://github.com/bxparks/AUnit). The `vim` editor will jump directly
208+
to the file and line where the assertion failure occurred. See
209+
https://vimhelp.org/quickfix.txt.html for information on the `quickfix` feature
210+
and the `errorformat` format that parses the GNU Make output.
211+
203212
The output that would normally be printed on the `Serial` on an Arduino
204213
board will be sent to the `STDOUT` of the Linux, MacOS, or FreeBSD terminal. The
205214
output should be identical to what would be shown on the serial port of the
@@ -233,6 +242,13 @@ for these additional libraries at the following locations:
233242
* under each of the additional directories listed in `ARDUINO_LIB_DIRS` (see
234243
below)
235244

245+
Version v1.5 supports compiling and linking plain C files in the third-party
246+
libraries (defined by `ARDUINO_LIBS`) or in the application directory itself.
247+
The C files are assumed to be written in C11 and are compiled using the `cc`
248+
compiler. It may be possible to override the compiler flags by adding `-std=c99`
249+
into the `EXTRA_CFLAGS` in the Makefile (which clobbers the default `-std=c11`)
250+
but this has not been tested.
251+
236252
<a name="AdditionalLibraryLocations"></a>
237253
### Additional Arduino Library Locations
238254

@@ -404,7 +420,7 @@ runtests:
404420
set -e; \
405421
for i in *Test/Makefile; do \
406422
echo '==== Running:' $$(dirname $$i); \
407-
$$(dirname $$i)/$$(dirname $$i).out; \
423+
$(MAKE) -C $$(dirname $$i) run; \
408424
done
409425

410426
clean:
@@ -426,7 +442,16 @@ $ make -C tests tests
426442
$ make -C tests runtests | grep failed
427443
```
428444

429-
These parent Makefiles can be used in Continuous Integration, as shown below.
445+
If you run `:make runtests` inside the `vim` editor, it knows how to parse the
446+
diagnostic outputs generated by GNU Make (as it changes directories through the
447+
`-C` flag), and it knows how to parse the file and line number contained in the
448+
assertion messages generated by [AUnit](https://github.com/bxparks/AUnit). The
449+
`vim` editor will jump directly to the file and line where the assertion failure
450+
occurred. See https://vimhelp.org/quickfix.txt.html for information on the
451+
`quickfix` feature and the `errorformat` format that parses the GNU Make output.
452+
453+
These parent Makefiles can also be used in Continuous Integration, as shown
454+
below.
430455

431456
<a name="ContinuousIntegration"></a>
432457
### Continuous Integration
@@ -461,8 +486,16 @@ you can use that instead by specifying the `CXX` makefile variable:
461486
```
462487
$ make CXX=clang++
463488
```
464-
(This tells `make` to set the `CXX` variable to `clang++` within the context of
465-
`EpoxyDuino.mk` which causes `clang++` to be used over the default `g++`.)
489+
490+
This tells `make` to set the `CXX` variable to `clang++` within the context of
491+
`EpoxyDuino.mk` which causes `clang++` to be used over the default `g++`.
492+
493+
If you have C files in your library or application, you can use to following to
494+
compile the C files using `clang` instead of `cc` (which is the same as `gcc` on
495+
Linux):
496+
```
497+
$ make CXX=clang++ CC=clang
498+
```
466499

467500
One reason to use `clang++` instead of `g++` is that the `clang++` compiler will
468501
sometimes catch a different set of programming errors.
@@ -487,6 +520,12 @@ variable, like this:
487520
$ make EXTRA_CXXFLAGS='-g'
488521
```
489522

523+
or
524+
525+
```
526+
$ make EXTRA_CXXFLAGS='-g' EXTRA_CFLAGS='-g'
527+
```
528+
490529
<a name="AdditionalCleanUp"></a>
491530
### Additional Clean Up
492531

@@ -822,6 +861,35 @@ The `pin` parameter should satisfy `0 <= pin < 32`. If `pin >= 32`, then
822861
<a name="SupportedArduinoFeatures"></a>
823862
## Supported Arduino Features
824863

864+
<a name="ArduinoMacros"></a>
865+
### Arduino Macros
866+
867+
The following C-preprocessor macros are defined:
868+
869+
* `ARDUINO=100`
870+
* Indicates compilation under Arduino.
871+
* `EPOXY_DUINO`
872+
* Indicates compilation under EpoxyDuino
873+
* `UNIX_HOST_DUINO`
874+
* For backwards compatibility with previous version of `EpoxyDuino`
875+
which was named `UnixHostDuino`.
876+
* `EPOXY_CORE_AVR`
877+
* Defined when the Makefile variable `EPOXY_CORE` is set to
878+
`ARDUINO_ARCH_AVR`.
879+
* This is the default.
880+
* `EPOXY_CORE_ESP8266`
881+
* Defined when the Makefile variable `EPOXY_CORE` is set to
882+
`ARDUINO_ARCH_ESP8266`.
883+
884+
The following are **not** defined. Many third party libraries tend to break with
885+
those defined because EpoxyDuino does not emulate those environments perfectly:
886+
887+
* `ARDUINO_ARCH_AVR`
888+
* `ARDUINO_ARCH_ESP8266`
889+
* `ARDUINO_ARCH_ESP32`
890+
* `ESP8266`
891+
* `ESP32`
892+
825893
<a name="ArduinoFunctions"></a>
826894
### Arduino Functions
827895

cores/epoxy/Arduino.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#define EPOXY_DUINO_EPOXY_ARDUINO_H
1515

1616
// xx.yy.zz => xxyyzz (without leading 0)
17-
#define EPOXY_DUINO_VERSION 10400
18-
#define EPOXY_DUINO_VERSION_STRING "1.4.0"
17+
#define EPOXY_DUINO_VERSION 10500
18+
#define EPOXY_DUINO_VERSION_STRING "1.5.0"
1919

2020
#include <algorithm> // min(), max()
2121
#include <cmath> // abs()

examples/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ all:
22
set -e; \
33
for i in */Makefile; do \
44
echo '==== Making:' $$(dirname $$i); \
5-
$(MAKE) -C $$(dirname $$i) -j; \
5+
$(MAKE) -C $$(dirname $$i); \
66
done
77

88
clean:

libraries/EpoxyEepromAvr/examples/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ all:
22
set -e; \
33
for i in */Makefile; do \
44
echo '==== Making:' $$(dirname $$i); \
5-
$(MAKE) -C $$(dirname $$i) -j; \
5+
$(MAKE) -C $$(dirname $$i); \
66
done
77

88
clean:

libraries/EpoxyEepromAvr/tests/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ tests:
22
set -e; \
33
for i in *Test/Makefile; do \
44
echo '==== Making:' $$(dirname $$i); \
5-
$(MAKE) -C $$(dirname $$i) -j; \
5+
$(MAKE) -C $$(dirname $$i); \
66
done
77

88
runtests:
99
set -e; \
1010
for i in *Test/Makefile; do \
1111
echo '==== Running:' $$(dirname $$i); \
12-
$$(dirname $$i)/$$(dirname $$i).out; \
12+
$(MAKE) -C $$(dirname $$i) run; \
1313
done
1414

1515
clean:

0 commit comments

Comments
 (0)