Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

Compiling Soletta™ Framework for Zephyr

Bruno Bottazzini edited this page Jun 13, 2016 · 3 revisions

In order to help you quickly deploy a Soletta™ Framework 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.

Makefile

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.

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.

Makefile.soletta

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.

sol.conf

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.

Clone this wiki locally