Skip to content
Ruslan V. Uss edited this page Feb 22, 2017 · 9 revisions

About the esp-open-rtos build process.

esp-open-rtos has a modular, parallelisable, build process based around GNU Make.

Per-program Makefile

Each individual esp-open-rtos program has its own Makefile. Each example subdirectory under the 'examples' directory is an example program with its own Makefile.

Most program Makefiles are very simple:

PROGRAM=my_program
include path/to/common.mk
  • PROGRAM is the name that will be used for the build output
  • include ...common.mk pulls in the top-level common.mk makefile that handles the rest of the build. This has to include the path to the top level esp-open-rtos directory.

common.mk can be at an absolute or relative path. The program does not have to be in the same directory as esp-open-rtos, it can be totally external.

The default for a simple program like this is to build all .c files in the same directory as the Makefile (the "program directory"). See below for details on how to add additional directories.

Make programs

Run make help in any program directory for a summary of Makefile programs.

Source directories

By default, all C files in the program directory are built along with the library "components" specified in common.mk (see below). To build C files in subdirectories, there are two approaches.

Specify the list of source directories via the Makefile variable PROGRAM_SRC_DIR. PROGRAM_SRC_DIR is a list of all directories to search, like this:

PROGRAM=my_program
PROGRAM_SRC_DIR=. ./subdir
include path/to/common.mk

... in the above example, all .c files in both the program directory and the subdirectory subdir will be built.

If you want to add extra source files, without adding all the files in a directory:

PROGRAM=my_program
PROGRAM_EXTRA_SRC_FILES=./subdir/subfile.c
include path/to/common.mk

... you can combine PROGRAM_SRC_DIR and PROGRAM_EXTRA_SRC_FILES in order to search some directories for all .c files, but include some specific source files from other directories.

Finally, as a third option, you can explicitly specify a list of source files:

PROGRAM=my_program
PROGRAM_SRC_FILES=./main.c ./subdir/subfile.c
include path/to/common.mk

... no directories are searched for .c files, only the files specified in the Makefile will be built.

Important: At the moment all files listed should be in subdirectories of the program directory (ie the directory with the Makefile). Otherwise build paths may end up long. If you want to build source files in totally unrelated directories, the best way is probably to make these into separate 'components' (see below). If there is a particular configuration that is hard to build, please open an issue here and we'll figure out together how to support it.

You can also specify headers search path using variable PROGRAM_INC_DIR:

PROGRAM=my_program
PROGRAM_SRC_DIR=. ./subdir
PROGRAM_INC_DIR=. ./subdir
include path/to/common.mk

Overriding Variables

Dozens of variables in common.mk are assigned with ?= and can be overridden per-program or per-local-system by adding definitions in the program Makefile or a local.mk file.

Overriding per-program

For example, to override the build directory:

PROGRAM=myprogram
BUILD_DIR=/tmp/custombuild
include ../esp-open-rtos/common.mk

Overriding per-local-system

If you want to override a variable for all programs on your local computer, without editing common.mk, you can do this by creating a file local.mk in the same directory as common.mk.

For example, to override the default esptool.py serial port, create this local.mk:

ESPPORT=COM3

If you want more granularity then you can create a second local.mk file in the program directory. This gets included after the top-level one.

Source Components

The libraries which are built from source in esp-open-rtos are called "components". common.mk defines a list of components to build:

# Source components to compile and link. Each of these are subdirectories
# of the root, with a 'component.mk' file.
COMPONENTS     ?= $(EXTRA_COMPONENTS) FreeRTOS lwip axtls core

You can use EXTRA_COMPONENTS in your Makefile to add more components, for example libraries found in the 'extras' directory. Or you can override the COMPONENTS variable entirely in your Makefile, if you don't want to build all of the default components.

Each item in the COMPONENTS variable is the path to a directory containing a component.mk file. The path is resolved relative to the esp-open-rtos root directory, but it can also be an absolute path to another directory (for out-of-tree components).

Each component is built from source along with the program. The component.mk file specifies the source file directories, include directories, and directories to be added to the global include path.

Under the hood, the "program" is really treated as a special component called PROGRAM.

Adding a new component

When adding a new modular component to esp-open-rtos (like a library or a driver), start by creating a component.mk file with the build details for that component.

Here's a sample component.mk, from extras/rboot-ota/component.mk:

# Component makefile for extras/rboot-ota

INC_DIRS += $(rboot-ota_ROOT)

# args for passing into compile rule generation
rboot-ota_SRC_DIR =  $(rboot-ota_ROOT)

$(eval $(call component_compile_rules,rboot-ota))

This component has the name rboot-ota, which is used for the name of the subdirectory where the component will be built and also the name of the interim library (rboot-ota.a) that the object files will be linked to. You can use any (unique) name for the component, but for consistency's sake try to use the name of the directory.

The build system automatically assigns a variable <componentname>_ROOT which points to the directory that component.mk is located in. In this case, rboot-ota_ROOT will be the path to extras/rboot-ota.

INC_DIRS += $(rboot-ota_ROOT)

This line appends extras/rboot-ota to the global header search path for the esp-open-rtos program. This allows your program (and/or other components) to include header files located in these directories.

# args for passing into compile rule generation
rboot-ota_SRC_DIR =  $(rboot-ota_ROOT)

<componentname>_SRC_DIR is a list of directories to search for source files (.c, .cpp, .S) to build into the component. In this case, we just search in the extras/rboot-ota directory. Some components will have a long list of directories here (see lwip/component.mk for an example).

If you'd rather specify individual source files instead of directories, replace <componentname>_SRC_DIR with <componentname>_SRC_FILES.

If you'd like to specify both directories plus some additional source files,use <componentname>_SRC_DIR plus <componentname>_EXTRA_SRC_FILES.

Try to reference files and directories relative to $(<componentname>_ROOT) where possible, so the component is not hard-coded to its position in the overall source tree.

$(eval $(call component_compile_rules,rboot-ota))

This should be the last line in component.mk, and it invokes the component_compile_rules macro (defined in common.mk) to generate the compiler rules for the component.

The argument to component_compile_rules must be the component name for this component, as described above.

Private header directories

You can optionally add a variable like this to component.mk:

rboot-ota_INC_DIR =  $(rboot-ota_ROOT)/include/private

<componentname>_INC_DIR is a list of directories to add to the include path, only when building the source files for this component. These directories are not added to the global include path for the rest of esp-open-rtos. This lets you have private header directories that don't "spill over" into the rest of the system.

In many cases <componentname>_INC_DIR is left unset, as all of the component's header directories are already added to the global INC_DIRS list.

Per-component CFLAGS

You can optionally add a line like this to component.mk:

rboot-ota_CFLAGS = $(CFLAGS) -Wno-address

This allows you to override CFLAGS used when compiling that component's source files, only.

This can be useful if you're compiling third party code that expects certain macros set, or where there are warnings that would otherwise stop the build.

Binary libraries

Default binary libraries to link in are specified in common.mk:

# binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking.
SDK_LIBS                ?= main net80211 phy pp wpa

# open source libraries linked in
LIBS ?= gcc hal

Libraries listed in SDK_LIBS are preprocessed by the build system to prefix sdk_ onto each symbol name. Libraries listed in LIBS are linked directly.

You can override either of these lists in your program's Makefile, if required.

Build Output

Build output goes to a build subdirectory of the program directory. The ELF binary (for use with gdb or objdump) is build/<PROGRAM>.out.

Raw binaries for flashing with esptool.py are output to the firmware subdirectory. make help describes the make flash and make test targets, which are useful for flashing the build output.