Skip to content

Instantly share code, notes, and snippets.

@ladislas
Created August 18, 2017 12:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ladislas/5f17cdf5d6a0a648ebf5a86523e692ed to your computer and use it in GitHub Desktop.
Save ladislas/5f17cdf5d6a0a648ebf5a86523e692ed to your computer and use it in GitHub Desktop.
diff --git a/Arduino.mk b/Arduino.mk
index 50d60ee..c626697 100644
--- a/Arduino.mk
+++ b/Arduino.mk
@@ -825,6 +825,19 @@ else
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
@@ -936,7 +949,10 @@ get_library_files = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.pr
$(wildcard $(1)/*.$(2) $(1)/utility/*.$(2)))
# General arguments
-USER_LIBS := $(sort $(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.
@@ -1137,17 +1153,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,SKETCH_LIBS =)
+endif
+
+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,ARDUINO_LIBS =)
+ $(call show_config_info,SKETCH_LIBS_DEPS =)
endif
-ifneq (,$(strip $(USER_LIB_NAMES)))
- $(foreach lib,$(USER_LIB_NAMES),$(call show_config_info, $(lib),[USER]))
+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)))
$(foreach lib,$(SYS_LIB_NAMES),$(call show_config_info, $(lib),[SYSTEM]))
+ $(call arduino_output,-)
endif
ifneq (,$(strip $(PLATFORM_LIB_NAMES)))
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment