From 9ce4de634d7a74ae72dbe9b7037578c08bef8b4e Mon Sep 17 00:00:00 2001 From: Matias N Date: Mon, 14 Sep 2020 16:51:31 -0300 Subject: [PATCH] support building external code into the OS, similar to how "external" apps work This works by having the build system look for nuttx/external/Kconfig to determine whether this directory is present or not. nuttx/external is gitignored in order to be added by the final user but not to be commited into the repo. Tipically this will by a symbolic link, just like apps/external. Inside external/ a Makefile should be placed with the same structure than any nuttx/ subdirectory (eg: nuttx/drivers/). The nuttx/external/Kconfig will be sourced and any options defined there will appear at the bottom of menuconfig (unless options are conditioned on menus, in which case they will appear accordingly). The purpose is to allow arch/board independent code, which for any reason is not to be upstreamed (propietary, not relevant for mainline, testing, etc), to be built into the OS during OS building stage. This way the user does not need to fork the NuttX repo to do so. This feature complements well with external apps and custom board support. --- .external-dummy/Kconfig | 1 + .external-dummy/README.md | 2 ++ .gitignore | 1 + Kconfig | 12 ++++++++++++ tools/Directories.mk | 5 +++++ tools/FlatLibs.mk | 6 ++++++ tools/KernelLibs.mk | 6 ++++++ tools/LibTargets.mk | 6 ++++++ tools/Makefile.unix | 23 +++++++++++++++-------- tools/Makefile.win | 19 +++++++++++++------ tools/ProtectedLibs.mk | 6 ++++++ 11 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 .external-dummy/Kconfig create mode 100644 .external-dummy/README.md diff --git a/.external-dummy/Kconfig b/.external-dummy/Kconfig new file mode 100644 index 0000000000..8e28fe6a4b --- /dev/null +++ b/.external-dummy/Kconfig @@ -0,0 +1 @@ +# This is supposed to be empty diff --git a/.external-dummy/README.md b/.external-dummy/README.md new file mode 100644 index 0000000000..150147a124 --- /dev/null +++ b/.external-dummy/README.md @@ -0,0 +1,2 @@ +This directory exists to hold an empty Kconfig which is used +when no nuttx/external is present. diff --git a/.gitignore b/.gitignore index cdb922cf88..44615e658b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ core Make*.dep uImage +/external diff --git a/Kconfig b/Kconfig index 3a4bce3300..331e3bde4a 100644 --- a/Kconfig +++ b/Kconfig @@ -1826,3 +1826,15 @@ endmenu menu "Application Configuration" source "$APPSDIR/Kconfig" endmenu + +# Support optionally including external code +# into the OS build. EXTERNALDIR will be used +# to either point to 'nuttx/external' or +# 'nuttx/.external-dummy', if 'nuttx/external' +# does not contain a Kconfig file + +config EXTERNALDIR + string + option env="EXTERNALDIR" + +source "$EXTERNALDIR/Kconfig" diff --git a/tools/Directories.mk b/tools/Directories.mk index f6c0602947..a033dff587 100644 --- a/tools/Directories.mk +++ b/tools/Directories.mk @@ -72,6 +72,11 @@ endif KERNDEPDIRS += sched drivers boards $(ARCH_SRC) KERNDEPDIRS += fs binfmt + +ifeq ($(EXTERNALDIR),external) + KERNDEPDIRS += external +endif + CONTEXTDIRS = boards fs $(APPDIR) CLEANDIRS += pass1 diff --git a/tools/FlatLibs.mk b/tools/FlatLibs.mk index 657481fe2a..c7669a6936 100644 --- a/tools/FlatLibs.mk +++ b/tools/FlatLibs.mk @@ -48,6 +48,12 @@ USERLIBS = NUTTXLIBS += staging$(DELIM)libdrivers$(LIBEXT) +# External code support + +ifeq ($(EXTERNALDIR),external) + NUTTXLIBS += staging$(DELIM)libexternal$(LIBEXT) +endif + # Add libraries for board support NUTTXLIBS += staging$(DELIM)libboards$(LIBEXT) diff --git a/tools/KernelLibs.mk b/tools/KernelLibs.mk index e50da99f08..8dbb7151f2 100644 --- a/tools/KernelLibs.mk +++ b/tools/KernelLibs.mk @@ -47,6 +47,12 @@ USERLIBS = NUTTXLIBS += staging$(DELIM)libdrivers$(LIBEXT) +# External code support + +ifeq ($(EXTERNALDIR),external) + NUTTXLIBS += staging$(DELIM)libexternal$(LIBEXT) +endif + # Add libraries for board support NUTTXLIBS += staging$(DELIM)libboards$(LIBEXT) diff --git a/tools/LibTargets.mk b/tools/LibTargets.mk index b5c4e980f3..e04a6a62c6 100644 --- a/tools/LibTargets.mk +++ b/tools/LibTargets.mk @@ -106,6 +106,12 @@ drivers$(DELIM)libdrivers$(LIBEXT): pass2dep staging$(DELIM)libdrivers$(LIBEXT): drivers$(DELIM)libdrivers$(LIBEXT) $(Q) $(call INSTALL_LIB,$<,$@) +external$(DELIM)libexternal$(LIBEXT): pass2dep + $(Q) $(MAKE) -C external libexternal$(LIBEXT) EXTRAFLAGS="$(KDEFINE) $(EXTRAFLAGS)" + +staging$(DELIM)libexternal$(LIBEXT): external$(DELIM)libexternal$(LIBEXT) + $(Q) $(call INSTALL_LIB,$<,$@) + binfmt$(DELIM)libbinfmt$(LIBEXT): pass2dep $(Q) $(MAKE) -C binfmt libbinfmt$(LIBEXT) EXTRAFLAGS="$(KDEFINE) $(EXTRAFLAGS)" diff --git a/tools/Makefile.unix b/tools/Makefile.unix index 52ccd3ca05..27444850bf 100644 --- a/tools/Makefile.unix +++ b/tools/Makefile.unix @@ -63,6 +63,13 @@ CONFIG_APPS_DIR = ../apps endif APPDIR := $(realpath ${shell if [ -r $(CONFIG_APPS_DIR)/Makefile ]; then echo "$(CONFIG_APPS_DIR)"; fi}) +# External code support +# If external/ contains a Kconfig, we define the EXTERNALDIR variable to 'external' +# so that main Kconfig can find it. Otherwise, we redirect it to a dummy Kconfig +# This is due to kconfig inability to do conditional inclusion. + +EXTERNALDIR := $(shell if [ -r $(TOPDIR)/external/Kconfig ]; then echo 'external'; else echo '.external-dummy'; fi) + # CONTEXTDIRS include directories that have special, one-time pre-build # requirements. Normally this includes things like auto-generation of # configuration specific files or creation of configurable symbolic links @@ -455,28 +462,28 @@ pass2dep: context tools/mkdeps$(HOSTEXEEXT) tools/cnvwindeps$(HOSTEXEEXT) # file in the NuttX tools GIT repository for additional information. config: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-conf Kconfig oldconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --oldconfig Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-conf --oldconfig Kconfig olddefconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --olddefconfig Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-conf --olddefconfig Kconfig menuconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-mconf Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-mconf Kconfig nconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-nconf Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-nconf Kconfig qconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-qconf Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-qconf Kconfig gconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-gconf Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-gconf Kconfig savedefconfig: apps_preconfig - $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --savedefconfig defconfig.tmp Kconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} EXTERNALDIR=$(EXTERNALDIR) kconfig-conf --savedefconfig defconfig.tmp Kconfig $(Q) sed -i -e "/CONFIG_APPS_DIR=/d" defconfig.tmp $(Q) grep "CONFIG_ARCH=" .config >> defconfig.tmp $(Q) grep "^CONFIG_ARCH_CHIP_" .config >> defconfig.tmp; true diff --git a/tools/Makefile.win b/tools/Makefile.win index e6d793e914..bde2f73b07 100644 --- a/tools/Makefile.win +++ b/tools/Makefile.win @@ -48,6 +48,13 @@ CONFIG_APPS_DIR = ..\apps endif APPDIR := $(realpath ${shell if exist "$(CONFIG_APPS_DIR)\Makefile" echo $(CONFIG_APPS_DIR)}) +# External code support +# If external/ contains a Kconfig, we define the EXTERNALDIR variable to 'external' +# so that main Kconfig can find it. Otherwise, we redirect it to a dummy Kconfig +# This is due to kconfig inability to do conditional inclusion. + +EXTERNALDIR := $(shell if [ -r $(TOPDIR)\external\Kconfig ]; then echo 'external'; else echo '.external-dummy'; fi) + # CONTEXTDIRS include directories that have special, one-time pre-build # requirements. Normally this includes things like auto-generation of # configuration specific files or creation of configurable symbolic links @@ -411,22 +418,22 @@ pass2dep: context tools\mkdeps$(HOSTEXEEXT) # misc\tools\README.txt for additional information. config: apps_preconfig - $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf Kconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& set EXTERNALDIR=$(EXTERNALDIR)& kconfig-conf Kconfig oldconfig: apps_preconfig - $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --oldconfig Kconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& set EXTERNALDIR=$(EXTERNALDIR)& kconfig-conf --oldconfig Kconfig olddefconfig: apps_preconfig - $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --olddefconfig Kconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& set EXTERNALDIR=$(EXTERNALDIR)& kconfig-conf --olddefconfig Kconfig menuconfig: configenv apps_preconfig - $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-mconf Kconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& set EXTERNALDIR=$(EXTERNALDIR)& kconfig-mconf Kconfig nconfig: apps_preconfig - $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-nconf Kconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& set EXTERNALDIR=$(EXTERNALDIR)& kconfig-nconf Kconfig savedefconfig: apps_preconfig - $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --savedefconfig defconfig.tmp Kconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& set EXTERNALDIR=$(EXTERNALDIR)& kconfig-conf --savedefconfig defconfig.tmp Kconfig $(Q) sed -i -e "/CONFIG_APPS_DIR=/d" defconfig.tmp $(Q) grep "CONFIG_ARCH=" .config >> defconfig.tmp -$(Q) grep "^CONFIG_ARCH_CHIP_" .config >> defconfig.tmp diff --git a/tools/ProtectedLibs.mk b/tools/ProtectedLibs.mk index 306b53efe7..a978042059 100644 --- a/tools/ProtectedLibs.mk +++ b/tools/ProtectedLibs.mk @@ -48,6 +48,12 @@ USERLIBS = NUTTXLIBS += staging$(DELIM)libdrivers$(LIBEXT) +# External code support + +ifeq ($(EXTERNALDIR),external) + NUTTXLIBS += staging$(DELIM)libexternal$(LIBEXT) +endif + # Add libraries for board support NUTTXLIBS += staging$(DELIM)libboards$(LIBEXT)