diff --git a/.gitignore b/.gitignore index 06cff06..2fa5764 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o build-cli /.project +build-* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f97a4ea --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: c +compiler: + - gcc +script: tests/script/runtests.sh +before_install: tests/script/bootstrap.sh diff --git a/Arduino.mk b/Arduino.mk index 64678b9..c1c61ff 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -1036,6 +1036,14 @@ else $(call show_config_variable,BOOTLOADER_PARENT,[USER]) endif +######################################################################## +# Tools version info +ARDMK_VERSION = 1.3.4 +$(call show_config_variable,ARDMK_VERSION,[COMPUTED]) + +CC_VERSION = $(shell $(CC) -dumpversion) +$(call show_config_variable,CC_VERSION,[COMPUTED],($(CC_NAME))) + # end of config output $(call show_separator) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76576b3..ff63b49 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,6 +24,7 @@ Submit a ticket for your issue, assuming one does not already exist. - When committing, reference your issue (if present) and include a note about the fix - If possible (and if makes sense) do atomic commits - Try to follow [this guideline](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) while choosing the git commit message + - If it makes sense then add a unit test case for the changes that you are making - Push the changes to your fork and submit a pull request to the 'master' branch of the this repository At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary. diff --git a/Common.mk b/Common.mk index 9aa36b8..f425b96 100644 --- a/Common.mk +++ b/Common.mk @@ -44,3 +44,20 @@ else endif endif $(call show_config_variable,CURRENT_OS,[AUTODETECTED]) + +######################################################################## +# +# Travis-CI +ifneq ($(TEST),) + DEPENDENCIES_DIR = /var/tmp/Arduino-Makefile-testing-dependencies + + DEPENDENCIES_MPIDE_DIR = $(DEPENDENCIES_DIR)/mpide-0023-linux64-20130817-test + ifeq ($(MPIDE_DIR),) + MPIDE_DIR = $(DEPENDENCIES_MPIDE_DIR) + endif + + DEPENDENCIES_ARDUINO_DIR = $(DEPENDENCIES_DIR)/arduino-1.0.5 + ifeq ($(ARDUINO_DIR),) + ARDUINO_DIR = $(DEPENDENCIES_ARDUINO_DIR) + endif +endif diff --git a/HISTORY.md b/HISTORY.md index bef7176..fedb006 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,19 +5,24 @@ The following is the rough list of changes that went into different versions. I tried to give credit whenever possible. If I have missed anyone, kindly add it to the list. ### In development -- Tweak: Allow remove of any OBJDIR with `$(REMOVE) $(OBJDIR)`. (https://github.com/ladislas) -- Fix: Change "tinyladi" username to "ladislas" in HISTORY.md. (https://github.com/ladislas) -- Add: Add information about `Bare-Arduino–Project` in README. (https://github.com/ladislas) -- Fix: Make avr-g++ use CXXFLAGS instead of CFLAGS. (https://github.com/sej7278) -- Add: Add information about reporting bugs to the correct project (Issue #231). (https://github.com/sej7278) -- Fix: Allow the use of CFLAGS_STD and CXXFLAGS_STD and set defaults (Issue #234) (https://github.com/ladislas) +- New: Added test suite and integration with travis CI. (https://github.com/peplin) +- New: Add information about `Bare-Arduino–Project` in README. (https://github.com/ladislas) +- New: Add information about reporting bugs to the correct project (Issue #231). (https://github.com/sej7278) +- New: Add documentation about CFLAGS_STD and CXXFLAGS_STD (Issue #234) (https://github.com/ladislas) +- New: Allow "make clean" target to be extended (Issue #239). (https://github.com/sej7278) +- New: Add makefile and gcc version info to config output. (https://github.com/sej7278) + - Tweak: Remove $(EXTRA_XXX) variables (Issue #234) (https://github.com/ladislas) -- Add: Add documentation about CFLAGS_STD and CXXFLAGS_STD (Issue #234) (https://github.com/ladislas) - Tweak: Update Malefile-example.mk with STD flags (https://github.com/ladislas) -- Add: Allow "make clean" target to be extended (Issue #239). (https://github.com/sej7278) +- Tweak: Allow remove of any OBJDIR with `$(REMOVE) $(OBJDIR)`. (https://github.com/ladislas) +- Tweak: Add cpp to extensions supported by "make generate_assembly". (https://github.com/sej7278) + +- Fix: Change "tinyladi" username to "ladislas" in HISTORY.md. (https://github.com/ladislas) +- Fix: Make avr-g++ use CXXFLAGS instead of CFLAGS. (https://github.com/sej7278) +- Fix: Allow the use of CFLAGS_STD and CXXFLAGS_STD and set defaults (Issue #234) (https://github.com/ladislas) - Fix: Update "make show_boards" regex to work with the Due in 1.5. (https://github.com/sej7278) - Fix: Allow user libaries/sketches to have the same name as system libs. (Issue #244, #229). (https://github.com/sej7278) -- Tweak: Add cpp to extensions supported by "make generate_assembly". (https://github.com/sej7278) +- Fix: Remove impact of travis-ci from regular users. (Issue #258). (https://github.com/sej7278) ### 1.3.4 (2014-07-12) - Tweak: Allow spaces in "Serial.begin (....)". (Issue #190) (https://github.com/pdav) diff --git a/README.md b/README.md index 50785b0..a5f1cff 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# A Makefile for Arduino Sketches +# A Makefile for Arduino Sketches [![Build Status](https://travis-ci.org/sudar/Arduino-Makefile.svg)](https://travis-ci.org/sudar/Arduino-Makefile) This is a very simple Makefile which knows how to build Arduino sketches. It defines entire workflows for compiling code, flashing it to Arduino and even communicating through Serial monitor. You don't need to change anything in the Arduino sketches. @@ -212,6 +212,16 @@ Then, the following line must be added to the project Makefile : $(CXX_NAME) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) ``` +## Test Suite + +This project includes a suite of example Makefiles and small Arduino and chipKIT +programs to assist the maintainers of the Makefile. Run +`tests/script/bootstrap.sh` to attempt to automatically install the dependencies +(Arduino IDE, MPIDE, etc.). Run `tests/script/runtests.sh` to attempt to compile +all of the examples. The bootstrap script is primarily intended for use by a +continuous integration server, specifically Travis CI. It is not intended for +normal users. + ### Bare-Arduino–Project If you are planning on using this makefile in a larger/professional project, you might want to take a look at the [Bare-Arduino–Project](https://github.com/WeAreLeka/Bare-Arduino-Project) framework. diff --git a/arduino-mk-vars.md b/arduino-mk-vars.md index 54608d6..1e8de64 100644 --- a/arduino-mk-vars.md +++ b/arduino-mk-vars.md @@ -852,6 +852,82 @@ CXXFLAGS_STD = = -std=gnu++98 ---- +### CFLAGS + +**Description:** + +Flags passed to compiler for files compiled as C. Add more flags to this +variable using `+=`. + +Defaults to all flags required for a typical build. + +**Example:** + +```Makefile +CFLAGS += -my-c-only-flag +``` + +**Requirement:** *Optional* + +---- + +### CXXFLAGS + +**Description:** + +Flags passed to the compiler for files compiled as C++. Add more flags to this +variable using `+=`. + +Defaults to all flags required for a typical build. + +**Example:** + +```Makefile +CXXFLAGS += -my-c++-onlyflag +``` + +**Requirement:** *Optional* + +---- + +### ASFLAGS + +**Description:** + +Flags passed to compiler for files compiled as assembly (e.g. `.S` files). Add +more flags to this variable using `+=`. + +Defaults to all flags required for a typical build. + +**Example:** + +```Makefile +ASFLAGS += -my-as-only-flag +``` + +**Requirement:** *Optional* + +---- + +### CPPFLAGS + +**Description:** + +Flags passed to the C pre-processor (for C, C++ and assembly source flies). Add +more flags to this variable using `+=`. + +Defaults to all flags required for a typical build. + +**Example:** + +```Makefile +CPPFLAGS += -DMY_DEFINE_FOR_ALL_SOURCE_TYPES +``` + +**Requirement:** *Optional* + +---- + ### OVERRIDE_EXECUTABLES **Description:** diff --git a/examples/ATtinyBlink/Makefile b/examples/ATtinyBlink/Makefile index a89de1c..b4e49be 100644 --- a/examples/ATtinyBlink/Makefile +++ b/examples/ATtinyBlink/Makefile @@ -1,6 +1,6 @@ # Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile -# if you have placed the alternate core in your sketchbook directory, then you can just mention the core name alone. +# if you have placed the alternate core in your sketchbook directory, then you can just mention the core name alone. ALTERNATE_CORE = attiny # If not, you might have to include the full path. #ALTERNATE_CORE_PATH = /home/sudar/Dropbox/code/arduino-sketches/hardware/attiny/ diff --git a/examples/BlinkInAVRC/Makefile b/examples/BlinkInAVRC/Makefile index 04049bb..a4cd2e4 100644 --- a/examples/BlinkInAVRC/Makefile +++ b/examples/BlinkInAVRC/Makefile @@ -11,6 +11,6 @@ F_CPU = 8000000L ISP_PROG = stk500v1 AVRDUDE_ISP_BAUDRATE = 19200 -include $(ARDMK_DIR)/Arduino.mk +include ../../Arduino.mk # !!! Important. You have to use make ispload to upload when using ISP programmer diff --git a/examples/README.md b/examples/README.md index b170cdc..39425b3 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,7 +1,11 @@ -This folder contains the list of example Arduino sketches and makefile showing the different usage patterns +This folder contains the list of example Arduino sketches and makefile showing +the different usage patterns + +- BlinkInAVRC - Shows how to use plain AVR C code +- ATtinyBlink - Shows how to use different cores like ATtiny + +These three examples are a step back, in the "tests" directory. - Blink - Shows normal usage - HelloWorld - Shows how to include Arduino libraries -- BlinkInAVRC - Shows how to use plain AVR C code - BlinkChipKIT - Shows how to use ChipKIT -- ATtinyBlink - Shows how to use different cores like ATtiny diff --git a/tests/script/bootstrap.sh b/tests/script/bootstrap.sh new file mode 100755 index 0000000..083bf5d --- /dev/null +++ b/tests/script/bootstrap.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +pushd $SCRIPTS_DIR/.. + +source $SCRIPTS_DIR/bootstrap/chipkit.sh +source $SCRIPTS_DIR/bootstrap/arduino.sh diff --git a/tests/script/bootstrap/arduino.sh b/tests/script/bootstrap/arduino.sh new file mode 100644 index 0000000..3c7e9d7 --- /dev/null +++ b/tests/script/bootstrap/arduino.sh @@ -0,0 +1,44 @@ +set -e +BOOTSTRAP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source $BOOTSTRAP_DIR/common.sh + +echo "Installing dependencies for building for the Arduino" + +if [ -z "$ARDUINO_DIR" ] || ! test -e $ARDUINO_DIR || [ $OS == "cygwin" ]; then + + echo "Installing Arduino..." + + ARDUINO_BASENAME="arduino-1.0.5" + if [ $OS == "cygwin" ]; then + ARDUINO_FILE="$ARDUINO_BASENAME-r2-windows".zip + EXTRACT_COMMAND="unzip -q" + elif [ $OS == "mac" ]; then + ARDUINO_FILE="$ARDUINO_BASENAME-macosx".zip + EXTRACT_COMMAND="unzip -q" + else + ARDUINO_FILE="$ARDUINO_BASENAME-linux64".tgz + EXTRACT_COMMAND="tar -xzf" + fi + + ARDUINO_URL=http://arduino.googlecode.com/files/$ARDUINO_FILE + + _pushd $DEPENDENCIES_FOLDER + if ! test -e $ARDUINO_FILE + then + echo "Downloading Arduino IDE..." + download $ARDUINO_URL $ARDUINO_FILE + fi + + if ! test -d $ARDUINO_BASENAME + then + echo "Installing Arduino to local folder..." + $EXTRACT_COMMAND $ARDUINO_FILE + echo "Arduino installed" + fi + + _popd + +fi + +echo +echo "${bldgreen}Arduino dependencies installed.$txtrst" diff --git a/tests/script/bootstrap/chipkit.sh b/tests/script/bootstrap/chipkit.sh new file mode 100644 index 0000000..efe9615 --- /dev/null +++ b/tests/script/bootstrap/chipkit.sh @@ -0,0 +1,61 @@ +set -e +BOOTSTRAP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source $BOOTSTRAP_DIR/common.sh + +echo "Installing dependencies for building for the chipKIT" + + +if [ -z "$MPIDE_DIR" ] || ! test -e $MPIDE_DIR || [ $OS == "cygwin" ]; then + + echo "Installing MPIDE..." + + if [ $OS == "cygwin" ]; then + MPIDE_BASENAME="mpide-0023-windows-20130715" + MPIDE_FILE="$MPIDE_BASENAME".zip + EXTRACT_COMMAND="unzip -q" + if ! command -v unzip >/dev/null 2>&1; then + _cygwin_error "unzip" + fi + elif [ $OS == "mac" ]; then + MPIDE_BASENAME=mpide-0023-macosx-20130715 + MPIDE_FILE="$MPIDE_BASENAME".dmg + else + MPIDE_BASENAME=mpide-0023-linux64-20130817-test + MPIDE_FILE="$MPIDE_BASENAME".tgz + EXTRACT_COMMAND="tar -xzf" + fi + + MPIDE_URL=http://chipkit.s3.amazonaws.com/builds/$MPIDE_FILE + + _pushd $DEPENDENCIES_FOLDER + if ! test -e $MPIDE_FILE + then + echo "Downloading MPIDE..." + download $MPIDE_URL $MPIDE_FILE + fi + + if ! test -d $MPIDE_BASENAME + then + echo "Installing MPIDE to local folder..." + if [ $OS == "mac" ]; then + hdiutil attach $MPIDE_FILE + cp -R /Volumes/Mpide/Mpide.app/Contents/Resources/Java $MPIDE_BASENAME + hdiutil detach /Volumes/Mpide + else + $EXTRACT_COMMAND $MPIDE_FILE + fi + echo "MPIDE installed" + fi + + if [ $OS == "cygwin" ]; then + chmod a+x mpide/hardware/pic32/compiler/pic32-tools/bin/* + chmod a+x -R mpide/hardware/pic32/compiler/pic32-tools/pic32mx/ + chmod a+x mpide/*.dll + chmod a+x mpide/hardware/tools/avr/bin/* + fi + _popd + +fi + +echo +echo "${bldgreen}chipKIT dependencies installed.$txtrst" diff --git a/tests/script/bootstrap/common.sh b/tests/script/bootstrap/common.sh new file mode 100644 index 0000000..a6b6415 --- /dev/null +++ b/tests/script/bootstrap/common.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash + +set -e +BOOTSTRAP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +if [ -z $COMMON_SOURCED ]; then + + # TODO this is kind of a hacky way of determining if root is required - + # ideally we wouuld set up a little virtualenv in the dependencies folder + SUDO_CMD= + if command -v sudo >/dev/null 2>&1; then + SUDO_CMD="sudo -E" + + if [ -z $CI ] && [ -z $VAGRANT ]; then + echo "The bootstrap script needs to install a few packages to your system as an admin, and we will use the 'sudo' command - enter your password to continue" + $SUDO_CMD ls > /dev/null + fi + fi + + KERNEL=`uname` + ARCH=`uname -m` + if [ ${KERNEL:0:7} == "MINGW32" ]; then + OS="windows" + elif [ ${KERNEL:0:6} == "CYGWIN" ]; then + OS="cygwin" + elif [ $KERNEL == "Darwin" ]; then + OS="mac" + else + OS="linux" + if ! command -v lsb_release >/dev/null 2>&1; then + # Arch Linux + if command -v pacman>/dev/null 2>&1; then + $SUDO_CMD pacman -S lsb-release + fi + fi + + DISTRO=`lsb_release -si` + fi + + + die() { + echo >&2 "${bldred}$@${txtrst}" + exit 1 + } + + _cygwin_error() { + echo + echo "${bldred}Missing \"$1\"${txtrst} - run the Cygwin installer again and select the base package set:" + echo " $CYGWIN_PACKAGES" + echo "After installing the packages, re-run this bootstrap script." + die + } + + if ! command -v tput >/dev/null 2>&1; then + if [ $OS == "cygwin" ]; then + echo "OPTIONAL: Install the \"ncurses\" package in Cygwin to get colored shell output" + fi + else + set +e + # These exit with 1 when provisioning in a Vagrant box...? + txtrst=$(tput sgr0) # reset + bldred=${txtbld}$(tput setaf 1) + bldgreen=${txtbld}$(tput setaf 2) + set -e + fi + + + _pushd() { + pushd $1 > /dev/null + } + + _popd() { + popd > /dev/null + } + + _wait() { + if [ -z $CI ] && [ -z $VAGRANT ]; then + echo "Press Enter when done" + read + fi + } + + _install() { + if [ $OS == "cygwin" ]; then + _cygwin_error $1 + elif [ $OS == "mac" ]; then + # brew exists with 1 if it's already installed + set +e + brew install $1 + set -e + else + if [ -z $DISTRO ]; then + echo + echo "Missing $1 - install it using your distro's package manager or build from source" + _wait + else + if [ $DISTRO == "arch" ]; then + $SUDO_CMD pacman -S $1 + elif [ $DISTRO == "Ubuntu" ]; then + $SUDO_CMD apt-get update -qq + $SUDO_CMD apt-get install $1 -y + else + echo + echo "Missing $1 - install it using your distro's package manager or build from source" + _wait + fi + fi + fi + } + + download() { + url=$1 + filename=$2 + curl $url -L -o $filename + } + + if [ `id -u` == 0 ]; then + die "Error: running as root - don't use 'sudo' with this script" + fi + + if ! command -v unzip >/dev/null 2>&1; then + _install "unzip" + fi + + if ! command -v curl >/dev/null 2>&1; then + if [ $OS == "cygwin" ]; then + _cygwin_error "curl" + else + _install curl + fi + fi + + echo "Storing all downloaded dependencies in the \"dependencies\" folder" + + DEPENDENCIES_FOLDER="/var/tmp/Arduino-Makefile-testing-dependencies" + mkdir -p $DEPENDENCIES_FOLDER + + if ! command -v make >/dev/null 2>&1; then + if [ $OS == "cygwin" ]; then + _cygwin_error "make" + elif [ $OS == "mac" ]; then + die "Missing 'make' - install the Xcode CLI tools" + else + if [ $DISTRO == "arch" ]; then + _install "base-devel" + elif [ $DISTRO == "Ubuntu" ]; then + _install "build-essential" + fi + fi + fi + + if [ $DISTRO == "Ubuntu" ] && [ $ARCH == "x86_64" ]; then + _install "libc6-i386" + _install "lib32gcc1" + fi + + if ! command -v g++ >/dev/null 2>&1; then + if [ $DISTRO == "Ubuntu" ]; then + _install "g++" + fi + fi + + if ! command -v python >/dev/null 2>&1; then + echo "Installing Python..." + _install "python" + fi + + if ! command -v pip >/dev/null 2>&1; then + echo "Installing Pip..." + if ! command -v easy_install >/dev/null 2>&1; then + _install "python-setuptools" + fi + + if ! command -v easy_install >/dev/null 2>&1; then + die "easy_install not available, can't install pip" + fi + + $SUDO_CMD easy_install pip + fi + + PIP_SUDO_CMD= + if [ -z $VIRTUAL_ENV ]; then + # Only use sudo if the user doesn't have an active virtualenv + PIP_SUDO_CMD=$SUDO_CMD + fi + + $PIP_SUDO_CMD pip install --upgrade setuptools + $PIP_SUDO_CMD pip install --src dependencies --pre -Ur $BOOTSTRAP_DIR/pip-requirements.txt + + COMMON_SOURCED=1 +fi diff --git a/tests/script/bootstrap/pip-requirements.txt b/tests/script/bootstrap/pip-requirements.txt new file mode 100644 index 0000000..8313187 --- /dev/null +++ b/tests/script/bootstrap/pip-requirements.txt @@ -0,0 +1 @@ +pyserial==2.7 diff --git a/tests/script/runtests.sh b/tests/script/runtests.sh new file mode 100755 index 0000000..5313d0f --- /dev/null +++ b/tests/script/runtests.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +TESTS_DIR=examples + +failures=() + +# These examples cannot be tested easily at the moment as they require +# alternate cores. The MakefileExample doesn't actually contain any source code +# to compile. +NON_TESTABLE_EXAMPLES=(ATtinyBlink MakefileExample TinySoftWareSerial) + +for dir in $TESTS_DIR/*/ +do + dir=${dir%*/} + example=${dir##*/} + example_is_testable=true + for non_testable_example in "${NON_TESTABLE_EXAMPLES[@]}"; do + if [[ $example == $non_testable_example ]]; then + example_is_testable=false + break + fi + done + + if ! $example_is_testable; then + echo "Skipping non-testable example $example..." + continue + fi + + pushd $dir + echo "Compiling $example..." + make_output=`make clean TEST=1` + make_output=`make TEST=1` + if [[ $? -ne 0 ]]; then + failures+=("$example") + echo "Example $example failed" + fi + popd +done + +for failure in "${failures[@]}"; do + echo "Example $failure failed" +done + +if [[ ${#failures[@]} -eq 0 ]]; then + echo "All tests passed." +else + exit 1 +fi