-
Notifications
You must be signed in to change notification settings - Fork 108
Compiling Soletta™ Framework for Zephyr
In order to help you quickly deploy a Soletta application as a final Zephyr OS image, place the following scripts in a directory of your choice1. We tested this with Zephyr's latest SDK.
check_vars := $(and $(SOLETTA_BASE_DIR),$(ZEPHYR_BASE),$(ZEPHYR_GCC_VARIANT),$(ZEPHYR_SDK_INSTALL_DIR))
vars_missing := $(if $(check_vars),"","yes")
define NL
endef
ifeq ("yes",$(vars_missing))
$(error $(NL) Missing environment variables.$(NL) The Zephyr build requires the following variables to be set:$(NL)$(NL) ZEPHYR_BASE: Should point to the top Zephyr source directories.$(NL) ZEPHYR_GCC_VARIANT: The toolchain to use to build Zephyr.$(NL) ZEPHYR_SDK_INSTALL_DIR: The path where the Zephyr SDK is installed.$(NL) SOLETTA_BASE_DIR: The path to source of Soletta.$(NL))
endif
KERNEL_TYPE ?= micro
BOARD ?= qemu_x86
MDEF_FILE := prj.mdef
ifneq (,$(realpath $(PWD)/prj_$(BOARD).conf))
CONF_FILE := prj_$(BOARD).conf
else
ifneq (,$(realpath $(PWD)/prj.conf))
CONF_FILE := prj.conf
endif
endif
SOLETTA_CONF = $(realpath $(PWD)/sol_$(BOARD).conf)
ifeq (,$(SOLETTA_CONF))
SOLETTA_CONF = $(realpath $(PWD)/sol.conf)
endif
ifneq (,$(wildcard $(SOLETTA_CONF)))
export SOLETTA_CONF
endif
include $(ZEPHYR_BASE)/Makefile.inc
There's no need to set MDEF_FILE
when the kernel type is nano
.
Soletta application's prj.conf
file must have an entry like
CONFIG_NEWLIB_LIBC=y
, as it relies on a more complete libc. Don't
forget to set stack size (CONFIG_MAIN_STACK_SIZE=xxx
) and declare
nano timeouts (CONFIG_NANO_TIMEOUTS=y
) if you're under nanokernel,
not micro. For having Soletta's log on the output, don't forget to
declare CONFIG_STDOUT_CONSOLE=y
there as well.
This will make sure all routinely required Zephyr environment
variables are defined, plus a new one: SOLETTA_BASE_DIR
. Point it
to your Soletta repository, naturally. The scripts we assembled here
are very simple in terms of dependency tracking so, for each build,
make sure to have Soletta's repository clean again (in case you add
changes there).
The only things you may edit on this file are Zephyr's
KERNEL_TYPE
, BOARD
(which you may as well pass via command
line) and MDEF_FILE
. Remember to have your actual mdef
file
placed in your build directories as well, naturally. The
SOLETTA_CONF
part will be addressed later.
Now for Zephyr's expected Makefile.app
.
SOLETTA_INST_PATH := $(SOLETTA_BASE_DIR)/build/soletta_sysroot
SOLETTA_INCLUDE_PATH := $(SOLETTA_INST_PATH)/usr/include/soletta
SOLETTA_LIB_PATH := $(SOLETTA_INST_PATH)/usr/lib/libsoletta.a
SOLETTA_NODE_DESCRIPTIONS ?= $(SOLETTA_INST_PATH)/usr/share/soletta/flow/descriptions
# This is to force Soletta to be built before the application, so we ensure
# all the header files are somewhere the app will find them.
force_soletta_dep = $(SOLETTA_LIB_PATH)
scripts_basic: $(force_soletta_dep)
libs-y += lib/soletta/lib.a
SOLETTA_CFLAGS = $(KBUILD_CFLAGS) $(KBUILD_CPPFLAGS) $(ZEPHYRINCLUDE)
SOLETTA_LDFLAGS = $(LDFLAGS) $(LIB_INCLUDE_DIR)
# To keep the compiler from whining about .../sysgen not being there
SOLETTA_CFLAGS += -Wno-missing-include-dirs
export SOLETTA_CFLAGS SOLETTA_LDFLAGS
ZEPHYRINCLUDE += -I$(SOLETTA_INCLUDE_PATH)
$(SOLETTA_LIB_PATH):
$(Q)$(MAKE) -f $(PWD)/Makefile.soletta
$(Q)mkdir -p $(O)/lib/soletta
$(Q)cp $(SOLETTA_LIB_PATH) $(O)/lib/soletta/lib.a
The trick (hack) here is to hook on Zephyr's scripts_basic
rule,
so that in the process Soletta is built before the application on
top of it, and the latter is able to find Soletta's built headers and
stuff already assembled and available. No edition to this file is
needed, just place it under your build dir.
export TARGETCC = $(strip $(CC))
export TARGETLD = $(strip $(LD))
export TARGETAR = $(strip $(AR))
export PYTHON=python3
export PKG_CONFIG_LIBDIR=
override MAKEFLAGS=""
.PHONY: all
all:
$(MAKE) -C $(SOLETTA_BASE_DIR) CFLAGS="$(SOLETTA_CFLAGS)" LDFLAGS="$(SOLETTA_LDFLAGS)" alldefconfig
$(if $(SOLETTA_CONF), (cd $(SOLETTA_BASE_DIR); tools/kconfig/merge_config.sh .config $(SOLETTA_CONF)))
$(MAKE) -C $(SOLETTA_BASE_DIR) CFLAGS="$(SOLETTA_CFLAGS)" LDFLAGS="$(SOLETTA_LDFLAGS)"
This one also does not need any edition, and is responsible for
compiling Soletta itself under Zephyr's toolchain. Note that we zero
out PKG_CONFIG_DIR
, so that Soletta's dependency tracking phase
will not dive into the host-provided dependencies and use just what it
finds in Zephyr's environment.
Now there's a trick/facility here: if you provide a sol.conf
or
sol_$(BOARD).conf
file in your build dir, you'll be able to have
this pristine dependencies detection overridden by anything you want.
For example, if you have in it
FLOW_NODE_TYPE_GROVE=n
FLOW_NODE_TYPE_GYROSCOPE=n
FLOW_NODE_TYPE_JSON=n
FLOW_NODE_TYPE_LED_7SEG=n
FLOW_NODE_TYPE_LED_STRIP=n
FLOW_NODE_TYPE_MAGNETOMETER=n
regardless if the dependency checking decided to have those node types
built or not, you will tell the build system not to include them. That
is naturally true for Zephyr's build options too with regard to the
expected prj.conf
file as well: place it in your build directories
if you want it to happen.
For Zephyr, you might want to have the final image as small as possible.
Consider, then, using CFLAGS=-Os
, thus removing any unused functions
of the output and optimizing for size. You may also want to consider
tweaking Soletta's LOG_FILES
and LOG_FUNCTIONS
build options:
they control weather file/function names of log lines get in the image
or not, when logging is enabled.
Finally, this build infrastructure will expect a src
directory,
where you should place all the Soletta application source files, a
makefile with Zephyr's expected syntax for building each of them and
eventually their required CFLAGS
and such, e.g.:
obj-y := main.o
After all those are set up, just hit make and you should get two
output directories: one named after this build dir itself, with the
built objects under that src
directory of yours, and an outdir
one, with all Zephyr-generated resources (your final image will be
there). The former directory comes from Zephyr's build infrastructure
as well and they make it so that those objects end up in a different
place than outdir
.
Under this repository you'll find a similar but more worked out build solution/infrastructure which will also generate images for the RIOT OS, if one wishes, as well as generate them from FBP files as well. We'll update the ones here to contemplate FBP files as well soon.
1: You'd better have this directory side-by-side Zephyr OS's own repository one, because there's a known bug on Zephyr's build system where it will mess up with object paths if the two directoriess in question are too far away from each other in the file system.