diff --git a/Arduino.mk b/Arduino.mk index e90d9f0..ec3f345 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -736,7 +736,7 @@ ifeq ($(strip $(CHK_SOURCES)),) $(call show_config_info,No .pde or .ino files found. If you are compiling .c or .cpp files then you need to explicitly include Arduino header files) else #TODO: Support more than one file. https://github.com/sudar/Arduino-Makefile/issues/49 - $(error Need exactly one .pde or .ino file. This makefile doesn't support multiple .ino/.pde files yet) + $(error Need exactly one .pde or .ino file. This makefile doesn\'t support multiple .ino/.pde files yet) endif endif @@ -763,6 +763,19 @@ else $(call show_config_info,NO_CORE set so core library will not be built,[MANUAL]) endif +######################################################################## +# Automatically find the libraries needed to compile the sketch + +ifndef SKETCH_LIBS + SKETCH_LIBS := $(shell $(ARDMK_DIR)/bin/lib-detection $(USER_LIB_PATH) | \ + sed -ne 's/SKETCH_LIBS \(.*\) /\1/p') +endif + +ifndef SKETCH_LIBS_DEPS + SKETCH_LIBS_DEPS := $(shell $(ARDMK_DIR)/bin/lib-detection $(USER_LIB_PATH) | \ + sed -ne 's/SKETCH_LIBS_DEPS \(.*\) /\1/p') +endif + ######################################################################## # Determine ARDUINO_LIBS automatically @@ -772,8 +785,6 @@ ifndef ARDUINO_LIBS $(shell sed -ne "s/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p" $(LOCAL_SRCS))) ARDUINO_LIBS += $(filter $(notdir $(wildcard $(ARDUINO_SKETCHBOOK)/libraries/*)), \ $(shell sed -ne "s/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p" $(LOCAL_SRCS))) - ARDUINO_LIBS += $(filter $(notdir $(wildcard $(USER_LIB_PATH)/*)), \ - $(shell sed -ne "s/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p" $(LOCAL_SRCS))) endif ######################################################################## @@ -872,7 +883,10 @@ get_library_files = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.pr $(wildcard $(1)/*.$(2) $(1)/utility/*.$(2))) # General arguments -USER_LIBS := $(wildcard $(patsubst %,$(USER_LIB_PATH)/%,$(ARDUINO_LIBS))) +USER_LIBS := $(wildcard $(patsubst %,$(USER_LIB_PATH)/%,$(ARDUINO_LIBS))) \ + $(wildcard $(patsubst %,$(USER_LIB_PATH)/%,$(SKETCH_LIBS))) \ + $(wildcard $(patsubst %,$(USER_LIB_PATH)/%,$(SKETCH_LIBS_DEPS))) + USER_LIB_NAMES := $(patsubst $(USER_LIB_PATH)/%,%,$(USER_LIBS)) # Let user libraries override system ones. @@ -1032,17 +1046,32 @@ else $(call show_config_info,Size utility: Basic (not AVR-aware),[AUTODETECTED]) endif -ifneq (,$(strip $(ARDUINO_LIBS))) +ifneq (,$(strip $(SKETCH_LIBS))) $(call arduino_output,-) - $(call show_config_info,ARDUINO_LIBS =) + $(call show_config_info,SKETCH_LIBS =) endif -ifneq (,$(strip $(USER_LIB_NAMES))) - $(foreach lib,$(USER_LIB_NAMES),$(call show_config_info, $(lib),[USER])) +ifneq (,$(strip $(SKETCH_LIBS))) + $(foreach lib,$(SKETCH_LIBS),$(call show_config_info, $(lib),[USER])) +endif + +ifneq (,$(strip $(SKETCH_LIBS_DEPS))) + $(call arduino_output,-) + $(call show_config_info,SKETCH_LIBS_DEPS =) +endif + +ifneq (,$(strip $(SKETCH_LIBS_DEPS))) + $(foreach lib,$(SKETCH_LIBS_DEPS),$(call show_config_info, $(lib),[USER])) +endif + +ifneq (,$(strip $(SYS_LIB_NAMES) $(PLATFORM_LIB_NAMES))) + $(call arduino_output,-) + $(call show_config_info,SYSTEM_LIBS =) endif ifneq (,$(strip $(SYS_LIB_NAMES) $(PLATFORM_LIB_NAMES))) $(foreach lib,$(SYS_LIB_NAMES),$(call show_config_info, $(lib),[SYSTEM])) + $(call arduino_output,-) endif # either calculate parent dir from arduino dir, or user-defined path diff --git a/HISTORY.md b/HISTORY.md index c1229bf..4b142e3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -34,6 +34,7 @@ I tried to give credit whenever possible. If I have missed anyone, kindly add it - Fix: Changed IDE download URL *again* for Travis-CI. (https://github.com/sej7278) - Fix: Allow avrdude to erase the chip before programming during ispload (https://github.com/tchebb) - Fix: Fix speed regression. Thanks ladislas (Issue #280) (https://github.com/sej7278) +- New: Add automatic library detection when compiling a sketch. (http://github.com/ladislas) ### 1.3.4 (2014-07-12) - Tweak: Allow spaces in "Serial.begin (....)". (Issue #190) (https://github.com/pdav) diff --git a/bin/lib-detection b/bin/lib-detection new file mode 100755 index 0000000..8753ecd --- /dev/null +++ b/bin/lib-detection @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +import os +import re +import sys + + +# Set variables +USER_LIB_PATH = sys.argv[1] +USER_LIBS = [] + +includeRegex = re.compile("(?<=^\#include\s\")(.*)(?=\.h\")", re.DOTALL|re.M) + +SKETCH_SRCS = [] +SKETCH_LIBS = [] + +SKETCH_LIBS_DEPS = [] +SKETCH_LIBS_DEPS_STACK = [] + + +# Define functions +def outputLibs(libArray): + for lib in libArray: + print(lib), + print("") + + +# Find local sources .ino, .c or .cpp +FILE_END = (".c", ".cpp", ".ino") +SKETCH_SRCS = [f for f in os.listdir(os.curdir) if f.endswith(FILE_END)] + +# Find all USER_LIBS +for path, dirs, files in os.walk(USER_LIB_PATH): + for d in dirs: + USER_LIBS.append(d) + +# Find SKETCH_LIBS included in SKETCH_SRCS +for src in SKETCH_SRCS: + currentFile = open(src) + + for line in currentFile: + match = includeRegex.search(line) + if match is not None: + group = match.group(1) + if group in USER_LIBS: + SKETCH_LIBS.append(group) + +SKETCH_LIBS = sorted(set(SKETCH_LIBS)) + +# Find SKETCH_LIBS_DEPS includes in SKETCH_LIBS +for lib in SKETCH_LIBS: + if lib in USER_LIBS: + currentFile = open(os.path.join(USER_LIB_PATH, lib, lib + ".h")) + + for line in currentFile: + match = includeRegex.search(line) + if match is not None: + group = match.group(1) + if group in USER_LIBS and group not in SKETCH_LIBS: + SKETCH_LIBS_DEPS_STACK.append(group) + +SKETCH_LIBS_DEPS_STACK = list(set(SKETCH_LIBS_DEPS_STACK)) + +# Recursively find all dependencies of every libraries in USER_LIB_PATH +while len(SKETCH_LIBS_DEPS_STACK) > 0: + for lib in SKETCH_LIBS_DEPS_STACK: + if lib in USER_LIBS: + currentFile = open(os.path.join(USER_LIB_PATH, lib, lib + ".h")) + + for line in currentFile: + match = includeRegex.search(line) + if match is not None: + group = match.group(1) + if group in USER_LIBS and group not in SKETCH_LIBS_DEPS_STACK and group not in SKETCH_LIBS_DEPS and group not in SKETCH_LIBS: + SKETCH_LIBS_DEPS_STACK.append(group) + + else: + if lib not in SKETCH_LIBS_DEPS: + SKETCH_LIBS_DEPS.append(lib) + if lib in SKETCH_LIBS_DEPS_STACK: + SKETCH_LIBS_DEPS_STACK.remove(lib) + +SKETCH_LIBS_DEPS.sort() + +# Output libraries for the Makefile +print("SKETCH_LIBS"), +outputLibs(SKETCH_LIBS) + +print("SKETCH_LIBS_DEPS"), +outputLibs(SKETCH_LIBS_DEPS) \ No newline at end of file