Component Building Guide
Introduction
This section will take you through creating a Sming Component from start to finish, based on a real example from Pull Request #1992.
The aim here is to make an existing library, https://github.com/nomis/ModbusMaster, available for applications to use within the framework.
Various options and settings are only mentioned here, but are linked through to Sming build system where you can find full details of what they are and how they work.
You will need to be familiar with GIT and the use of submodules.
Structure
You should carefully consider how to incorporate third-party code. The choices are:
Add an existing third-party library directly as a Component, patching if required;
Add the a submodule as a sub-directory within a Component;
Copy code from an existing library (honouring any license agreement conditions) and modify/rewrite as necessary;
Start from scratch. If drawing on ideas from other implementations those should be attributed.
We could use (a), but that is appropriate only for very simple libraries, or those written for Sming but stored in an external repository (e.g. FlashString). You can find more details on this process in Adding External Sources.
Note
Bear in mind that the asynchronous architecture of Sming can be at odds with code written for Arduino.
In this example, the main ModbusMasterTransaction
code incorporates a loop which
effectively halts program execution until a timeout occurs or a response is received.
Fixing that could require extensive patching, so option (c) or (d) may be more appropriate.
For now we are using option (b), so we’ll start by creating the Component directory:
cd $SMING_HOME/Libraries
mkdir ModbusMaster
cd ModbusMaster
Note
Do not use $SMING_HOME/Components
. This is reserved for framework libraries.
Now add the submodule:
git submodule add --name Libraries.ModbusMaster https://github.com/nomis/ModbusMaster
This does three things:
Clones the external repository to the
ModbusMaster
sub-directory;Adds an entry to the
.gitmodules
file with the URL, local path and specified name;Stages both changes, with a link indicating which commit should be used.
Note
The dotted name format is a Sming convention.
Before committing, we need to edit the .gitmodules
file. Open in a text editor and
follow the instructions therein.
You should now re-stage and commit the changes before proceeding.
Patching
Where minor changes are required to third-party code then these can be applied automatically as patches. See Adding External Sources and GIT Submodules for details.
For ModbusMaster, we want to make a slight change to how the timeout is configured,
so this is provided in a file called ModbusMaster.patch
.
Supported architectures
Unless there are specific reasons not to do so, Components should work on all supported architectures. In particular, it should build and run under the Host Emulator.
In order to do this, you should remove any low-level code from the library by:
Using Sming support classes or drivers (see Esp8266 Drivers); or
Placing low-level code into separate code modules or header files.
If a Component is intended only to work with specific hardware then ensure appropriate checks are incorporated so that building fails gracefully on un-supported architectures. You can do this in the component.mk file:
ifneq ($(SMING_ARCH),Esp8266)
$(error MyComponent currently only supports the ESP8266 architecture)
endif
Component configuration
For very simple Components the default settings are adequate:
Source code must be in the base directory or a sub-directory called
src
Public header files must be in a sub-directory called
include
The source files will be compiled into a library, in this case clib-ModbusMaster.a
.
To change the defaults, provide a component.mk
file and set entries as required:
- Submodules
We need to tell Sming about the submodules:
COMPONENT_SUBMODULES := ModbusMaster
- Source code
Put the source code into a separate directory (or directories) and add those to
COMPONENT_SRCDIRS
.You can also use
COMPONENT_SRCFILES
.For ModbusMaster, all the source code is in the submodule so we set this to
COMPONENT_SRCDIRS := ModbusMaster/src
.- Header files
Keep public and private
.h
or.hpp
files in separate directories.Add the public ones to
COMPONENT_INCDIRS
.Any private headers can be set in
EXTRA_INCDIR
.For ModbusMaster, we set this to
COMPONENT_INCDIRS := ModbusMaster/src
- Configuration options
ModbusMaster provides the
MB_RESPONSE_TIMEOUT
variable.This is mapped onto a
#define
value with the same name usingCOMPONENT_CXXFLAGS
.Note: Don’t confuse this with
COMPONENT_CFLAGS
which is only used when building.c
source files.If the value changes we want Sming to rebuild both the library and any code which uses it, so we assign it to the
COMPONENT_VARS
variable list. Users can check the value by runningmake list-config
.- Dependencies
If your library depends on other libraries to build, these must be declared in the
component.mk
file by settingCOMPONENT_DEPENDS
variable.ModbusMaster doesn’t have any so this entry is not required.
Documentation
A Component MUST have a README.md
(markdown) or README.rst
(reStructuredText) file
with a level 1 heading and brief introduction at an absolute minimum.
Note
You may not be familiar with .rst
files but they are a considerably improvement on markdown
and well worth investing a little time to learn.
See Contributing for further details.