diff --git a/Arduino.h b/Arduino.h index eb87df2..4148045 100644 --- a/Arduino.h +++ b/Arduino.h @@ -13,8 +13,8 @@ #include "StdioSerial.h" // xx.yy.zz => xxyyzz (without leading 0) -#define UNIX_HOST_DUINO_VERSION 103 -#define UNIX_HOST_DUINO_VERSION_STRING "0.1.3" +#define UNIX_HOST_DUINO_VERSION 200 +#define UNIX_HOST_DUINO_VERSION_STRING "0.2" // Used by digitalRead() and digitalWrite() #define HIGH 0x1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 94499db..1a669a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog * Unreleased +* 0.2 (2020-03-21) + * Mark `main()` as a weak reference (supported by g++ and clang++) so that + UniHostDuino can be used as a library in programs that already provide a + `main()` function. (Thanks to Max Prokhorov mcspr@). + * Replace `ARDUINO_LIB_DIR` with `ARDUINO_LIB_DIRS` which supports + multiple external library locations, in addition to siblings of the + UnixHostDuino directory. The `ARDUINO_LIB_DIR` is no longer supported. * 0.1.3 (2019-11-21) * Add 'Installation' section to the README.md. * Add `UNIX_HOST_DUINO` macro symbol to the CPPFLAGS to allow conditional diff --git a/README.md b/README.md index 2d8518e..9fc5247 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,11 @@ sketch is `SampleTest/SampleTest.ino`, then the makefile should be `SampleTest/Makefile`. The sketch is compiled with just a `make` command. It produces an executable with a `.out` extension, for example, `SampleTest.out`. -Running an Arduino program natively on Linux or MacOS has some advantages: +To be clear, most Arduino programs have hardware dependencies which will *not* +be supported by UnixHostDuino. However, if your program has limited hardware +dependencies so that it is conceptually portable to a vanilla Unix environment, +UnixHostDuino may work. Running an Arduino program natively on Linux or MacOS +has some advantages: * The development cycle can be lot faster because the compilers on the the desktop machines are a lot faster, and we also avoid the upload and flash @@ -28,7 +32,7 @@ The disadvantages are: * There may be compiler differences between the desktop and the embedded environments (e.g. 16-bit `int` versus 64-bit `int`). -Version: 0.1.3 (2019-11-21) +Version: 0.2 (2020-03-21) ## Installation @@ -93,9 +97,48 @@ $ CXX=clang++ make the `make` command, which causes `make` to set its internal `CXX` variable, which causes `UnixHostDuino.mk` to use `clang++` over the default `g++`.) +### Additional Arduino Libraries + +If the Arduino program depends on additional Arduino libraries, they must be +specified in the `Makefile` using the `ARDUINO_LIBS` parameter. For example, +this includes the [AUnit](https://github.com/bxparks/AUnit) library if it is at +the same level as UnixHostDuino: + +``` +APP_NAME := SampleTest +ARDUINO_LIBS := AUnit AceButton AceTime +include ../../UnixHostDuino/UnixHostDuino.mk +``` + +The libraries are referred to by their base directory name (e.g. `AceButton`, +or `AceTime`) not the full path. The `UnixHostDuino.mk` file will look for +these additional libraries at the same level as the `UnixHostDuino` directory +itself. + +### Additional Arduino Library Locations + +By default, UnixHostDuino assumes that the additional libraries are siblings to +the`UnixHostDuino/` library. Unfortunately, Arduino libraries tend to be +scattered among many locations. These additional locations can be specified +using the `ARDUINO_LIB_DIRS` variable. For example, + +``` +APP_NAME := SampleTest +ARDUINO := ../../arduino-1.8.9 +ARDUINO_LIBS := AUnit AceButton AceTime +ARDUINO_LIB_DIRS := \ + $(ARDUINO)/portable/packages/arduino/hardware/avr/1.8.2/libraries \ + $(ARDUINO)/libraries \ + $(ARDUINO)/hardware/arduino/avr/libraries +include ../../UnixHostDuino/UnixHostDuino.mk +``` + +Each of the `AUnit`, `AceButton` and `AceTime` libraries will be searched in +each of the 3 directories given in the `ARDUINO_LIB_DIRS`. + ### Difference from Arduino IDE -There are a number of small differences compared to the programming environment +There are a number of differences compared to the programming environment provided by the Arduino IDE: * The `*.ino` file is treated like a normal `*.cpp` file. So it must have @@ -114,6 +157,16 @@ Fortunately, the changes required to make an `ino` file compatible with UnixHostDuino are backwards compatible with the Arduino IDE. In other words, a program that compiles with UnixHostDuino will also compile under Ardunio IDE. +There are other substantial differences. The Arduino IDE supports multiple +microcontroller board types, each using its own set of compiler tools and +library locations. There is a complicated set of files and rules that determine +how to find and use those tools and libraries. The UnixHostDuino tool does *not* +use any of the configuration files used by the Arduino IDE. Sometimes, you can +use the `ARDUINO_LIB_DIRS` to get around this limitations. However, when you +start using `ARDUINO_LIB_DIRS`, you will often run into third party libraries +using features which are not supported by the UnixHostDuino framework emulation +layer. + ### Conditional Code If you want to add code that takes effect only on UnixHostDuino, you can use @@ -138,28 +191,6 @@ and the following works for MacOS: #endif ``` -### Additional Arduino Libraries - -If the Arduino program depends on additional Arduino libraries, they must be -specified in the `Makefile` using the `ARDUINO_LIBS` parameter. For example, -this includes the [AUnit](https://github.com/bxparks/AUnit) library if it is at -the same level as UnixHostDuino: - -``` -APP_NAME := SampleTest -ARDUINO_LIBS := AUnit -include .../UnixHostDuino/UnixHostDuino.mk -``` - -The libraries are referred -to by their base directory name (e.g. `AceButton`, or `AceRoutine`) not the full -path. The `UnixHostDuino.mk` file will look for these additional libraries at -the same level as the `UnixHostDuino` directory itself. (We assume that the -additional libraries are siblings to the`UnixHostDuino/` library). This search -location can be changed by the user using the `ARDUINO_LIB_DIR` environment -variable. If this is set, then `make` will use this directory to look for the -additional libraries, instead of sibling directories of `UnixHostDuino`. - ## Supported Arduino Features The following functions and features of the Arduino framework are implemented: @@ -234,7 +265,10 @@ worth the trade-off. This library has been tested on: * Ubuntu 18.04 + * g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 * g++ 7.4.0 + * clang++ 8.0.0-3~ubuntu18.04.2 + * clang++ 6.0.0-1ubuntu2 * GNU Make 4.1 * MacOS 10.14.5 * clang++ Apple LLVM version 10.0.1 @@ -275,4 +309,6 @@ incorporate everything, but I will give your ideas serious consideration. ## Authors -Created by Brian T. Park (brian@xparks.net). +* Created by Brian T. Park (brian@xparks.net). +* Support for using as library, by making `main()` a weak reference, added + by Max Prokhorov (prokhorov.max@outlook.com). diff --git a/UnixHostDuino.mk b/UnixHostDuino.mk index 74089c8..7a78888 100644 --- a/UnixHostDuino.mk +++ b/UnixHostDuino.mk @@ -18,6 +18,10 @@ # # Optional parameters are: # +# * ARDUINO_LIB_DIRS: List of additional locations of Arduino libs, for +# example, $(ARDUINO)/libraries, $(ARDUINO)/hardware/arduino/avr/libraries, +# $(ARDUINO)/portable/packages/arduino/hardware/avr/1.8.2/libraries, where +# $(ARDUINO) is the install location of the Arduino IDE. # * OBJS: Additional object (*.o) files needed by the binary # * GENERATED: A list of files which are generated by a script, and therefore # can be deleted by 'make clean' @@ -28,22 +32,31 @@ # # Type 'make clean' to remove intermediate files. - # Detect Linux or MacOS UNAME := $(shell uname) # UnixHostDuino module directory. UNIX_HOST_DUINO_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) +# Assume that there are other libs are siblings to UnixHostDuino +UNIX_HOST_DUINO_LIB_DIR := $(realpath $(UNIX_HOST_DUINO_DIR)/..) -# If ARDUINO_LIB_DIR is not defined, assume that it's 1 level -# above the UnixHostDuino/ directory. -ARDUINO_LIB_DIR ?= $(realpath $(UNIX_HOST_DUINO_DIR)/..) +# List of Arduino IDE library folders, both built-in to the Arduino IDE +# and those downloaded later, e.g. in the portable/ directory or .arduino15/ +# directory. +ARDUINO_LIB_DIRS ?= # Default modules which are automatically linked in: UnixHostDuino/ DEFAULT_MODULES := $(UNIX_HOST_DUINO_DIR) -# Application Modules as specified by the application's ARDUINO_LIBS variable. -APP_MODULES := $(foreach lib,$(ARDUINO_LIBS),${ARDUINO_LIB_DIR}/${lib}) +# Look for the ARDUINO_LIBS modules under each of the ARDUINO_LIB_DIRS and +# UNIX_HOST_DUINO_LIB_DIR. +APP_MODULES := $(foreach lib,$(ARDUINO_LIBS),${UNIX_HOST_DUINO_LIB_DIR}/${lib}) +APP_MODULES += \ + $(foreach lib_dir,$(ARDUINO_LIB_DIRS),\ + $(foreach lib,$(ARDUINO_LIBS),\ + ${lib_dir}/${lib}\ + )\ + ) # All dependent modules. ALL_MODULES := $(DEFAULT_MODULES) $(APP_MODULES)