mirror of
https://github.com/apache/nuttx.git
synced 2026-02-07 21:42:56 +08:00
Some checks failed
Build Documentation / build-html (push) Has been cancelled
This commit adds initial high level overview of the NuttX make-based build system. It documents: * Tools used during the build process * Mechanisms set in place during the build process Signed-off-by: Luchian Mihai <luchiann.mihai@gmail.com>
608 lines
23 KiB
ReStructuredText
608 lines
23 KiB
ReStructuredText
=================
|
|
Make Build System
|
|
=================
|
|
|
|
Currently, NuttX supports both CMake and Make build systems.
|
|
This guide explains the NuttX ``make``-based build system.
|
|
|
|
Due to *requirements, constraints, and the complexity of the build process*, NuttX divides
|
|
this work into multiple files, each handling specific parts of the build process.
|
|
|
|
As stated in :doc:`/introduction/inviolables`, multiple platforms should be supported:
|
|
|
|
- :ref:`win_mk`: handles windows platform support.
|
|
- :ref:`unix_mk`: handles unix-like platforms support.
|
|
|
|
NuttX supports multiple build modes. See :doc:`/guides/protected_build`:
|
|
|
|
- :ref:`flatlibs_mk`: Kernel and user-space built into a single ``blob``.
|
|
- :ref:`protectedlibs_mk`: Kernel and user-space built as two separate ``blobs``.
|
|
- :ref:`kernelibs_mk`: Kernel built into single ``blob``. User apps must be loaded
|
|
into memory for execution.
|
|
|
|
NuttX targets multiple libs, or ``silos``, each handling its own compilation:
|
|
|
|
.. note::
|
|
|
|
Gregory Nutt has a nice presentation about
|
|
`NuttX architecture <https://cwiki.apache.org/confluence/pages/viewpage.action?
|
|
pageId=139629399&preview=/139629402/140774623/nuttx-3-archoverview.pdf>`_
|
|
|
|
There the ``silo`` concept is explained. Only the ``silos`` there are listed below as libs.
|
|
The build mode influences the needed libs.
|
|
|
|
.. code-block:: console
|
|
|
|
$ ls -l staging/
|
|
drwxr-xr-x 2 xxx xxx 4096 Oct 6 16:02 .
|
|
drwxr-xr-x 27 xxx xxx 4096 Oct 6 16:02 ..
|
|
-rw-r--r-- 1 xxx xxx 323640 Oct 6 16:02 libapps.a
|
|
-rw-r--r-- 1 xxx xxx 384352 Oct 6 16:02 libarch.a
|
|
-rw-r--r-- 1 xxx xxx 62182 Oct 6 16:02 libbinfmt.a
|
|
-rw-r--r-- 1 xxx xxx 6468 Oct 6 16:01 libboards.a
|
|
-rw-r--r-- 1 xxx xxx 2820054 Oct 6 16:02 libc.a
|
|
-rw-r--r-- 1 xxx xxx 161486 Oct 6 16:01 libdrivers.a
|
|
-rw-r--r-- 1 xxx xxx 981638 Oct 6 16:02 libfs.a
|
|
-rw-r--r-- 1 xxx xxx 224446 Oct 6 16:02 libmm.a
|
|
-rw-r--r-- 1 xxx xxx 2435746 Oct 6 16:01 libsched.a
|
|
-rw-r--r-- 1 xxx xxx 51768 Oct 6 16:02 libxx.a
|
|
|
|
.. _verbosity:
|
|
|
|
Verbosity
|
|
---------
|
|
|
|
The ``V`` variable can be passed to ``make`` to control the build verbosity.
|
|
|
|
- **Quiet (Default):** The build output is minimal.
|
|
- **Verbose (`V=1 V=2`):** Shows the full compiler commands *(enables command echo)*.
|
|
- **Verbose Tools (`V=2`):** Enables verbose output for tools and scripts.
|
|
|
|
.. code-block:: console
|
|
|
|
# V=1,2: Enable echo of commands
|
|
$ make V=1
|
|
|
|
# V=2: Enable bug/verbose options in tools and scripts
|
|
$ make V=2
|
|
|
|
Build Process
|
|
-------------
|
|
|
|
.. note::
|
|
|
|
Keep the configuration step and board folder layout short.
|
|
Separate docs should be created.
|
|
|
|
The ``Make`` based build process starts with the NuttX tree configuration.
|
|
This is done by running ``tools/configure.sh`` script.
|
|
The configuration step, prepares the NuttX kernel tree, setting the board specific
|
|
arch, chip and board files.
|
|
|
|
The ``Make`` build system refers the needed subsystems using *generic* naming:
|
|
|
|
- The *current* architecture is refered as ``arch``
|
|
- The *current* chip is refered as ``chip``
|
|
- The *current* board is refered as ``board``
|
|
|
|
These *generic* names are mapped to the *actual* names by symlinks:
|
|
|
|
- The *current* chip directory gets symlinked to ``nutt/include/arch/chip``.
|
|
- The *current* board directory gets symlinked to ``nutt/include/arch/board``.
|
|
- The *current* arch directory gets symlinked to ``nutt/include/arch``.
|
|
|
|
The board config is stored as ``defconfig`` file, which is a minimal config,
|
|
storing only the configs that differs from default config values.
|
|
Due to NuttX's particularity of strict dependance to the ``app``
|
|
directory, the ``.config`` file is not generated by either ``kconfiglib`` or
|
|
``kconfig-frontends``, but rather by the an in-tree ``tools/process_config.sh``
|
|
script. This script takes a "base" input file (the boards ``defconfig`` file),
|
|
additional include paths (the most relevant being the ``apps`` top directory),
|
|
and generate an output file (the ``$(TOPDIR)/.config`` file).
|
|
|
|
.. code-block:: console
|
|
|
|
# part of configure.sh shell script, starting at line 240
|
|
#
|
|
# src_config=${configpath}/defconfig
|
|
# dest_config="${TOPDIR}/.config"
|
|
# original_config="${TOPDIR}/.config.orig"
|
|
# backup_config="${TOPDIR}/defconfig"
|
|
|
|
$ ln -sf ${src_makedefs} ${dest_makedefs} || \
|
|
{ echo "Failed to symlink ${src_makedefs}" ; exit 8 ; }
|
|
$ ${TOPDIR}/tools/process_config.sh -I ${configpath}/../../common/configs \
|
|
-I ${configpath}/../common \
|
|
-I ${configpath} -I ${TOPDIR}/../apps \
|
|
-I ${TOPDIR}/../nuttx-apps \
|
|
-o ${dest_config} ${src_config}
|
|
|
|
Starting the Build
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
The root **Makefile** is the build process entrypoint. Its main job is
|
|
to check for a ``.config`` file and include the appropriate **host-specific Makefile**.
|
|
The "actual" first steps of the build process are handled by the host-specific
|
|
**Makefile** (either ``Win.mk`` or ``Unix.mk``).
|
|
|
|
Early on, during parsing, both host-specific **Makefile** will also include
|
|
|
|
- board's ``Make.defs`` file mentioned above. This will include also
|
|
|
|
- the main ``.config`` file.
|
|
- the tools ``config.mk`` file.
|
|
- the arch ``toolchain.defs`` file.
|
|
|
|
- based on the build mode, one of the following files:
|
|
|
|
- :ref:`flatlibs_mk`
|
|
- :ref:`protectedlibs_mk`
|
|
- :ref:`kernelibs_mk`
|
|
|
|
- :ref:`directories_mk`
|
|
|
|
Built-in dependency mechanism
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
.. note::
|
|
|
|
The documentation for :ref:`mkdeps` should be extended. Lots of details
|
|
are missing. Part of the documentation here should be moved.
|
|
|
|
NuttX implements a built-in dependency mechanism. See :ref:`mkdeps`.
|
|
This mechanism uses ``gcc`` to generate a ``*.d`` like dependency files that can be
|
|
included by the **Makefile** to track file dependencies.
|
|
This mechanism is kick-started by the ``depend`` target, and targets specific
|
|
directories in the NuttX tree based on the build mode. It is *required* by both
|
|
``pass1dep`` and ``pass2dep``.
|
|
|
|
.. code-block:: makefile
|
|
|
|
pass1dep: context tools/mkdeps$(HOSTEXEEXT) tools/cnvwindeps$(HOSTEXEEXT)
|
|
$(Q) for dir in $(USERDEPDIRS) ; do \
|
|
$(MAKE) -C $$dir depend || exit; \
|
|
done
|
|
pass2dep: context tools/mkdeps$(HOSTEXEEXT) tools/cnvwindeps$(HOSTEXEEXT)
|
|
$(Q) for dir in $(KERNDEPDIRS) ; do \
|
|
$(MAKE) -C $$dir EXTRAFLAGS="$(KDEFINE) $(EXTRAFLAGS)" depend || exit; \
|
|
done
|
|
|
|
Both ``pass1dep`` and ``pass2dep`` sets different directories and orders
|
|
in which the ``depend`` target is ran. See :ref:`directories_mk`.
|
|
|
|
Building NuttX libs
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
The host-specific **Makefile** will not build the required NuttX libs.
|
|
It will defer work by "recursively" calling make in each of the directories
|
|
listed in the ``$(USERLIBS)`` and ``$(NUTTXLIBS)`` variables.
|
|
|
|
pass1 & pass2
|
|
^^^^^^^^^^^^^
|
|
|
|
The NuttX binary is always generated by running both ``pass1`` and ``pass2`` targets.
|
|
The actual dependencies of the mentioned targets may vary depending on the build mode.
|
|
|
|
Different NuttX build modes will not influence the "execution" of the ``pass1`` and ``pass2`` targets,
|
|
but rather will influence the dependencies pulled by those targets.
|
|
|
|
- ``pass1`` target depends on the ``$(USERLIBS)``.
|
|
- ``pass2`` target depends on the ``$(NUTTXLIBS)``.
|
|
|
|
.. code-block:: makefile
|
|
|
|
all: pass1 pass2
|
|
|
|
pass1: $(USERLIBS)
|
|
pass2: $(NUTTXLIBS)
|
|
|
|
The content of the ``$(USERLIBS)`` and ``$(NUTTXLIBS)`` variables is defined in each build mode makefile.
|
|
See :ref:`build_modes` above.
|
|
|
|
Staging the libs
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
After compiling libraries defined by the ``$(USERLIBS)`` and ``$(NUTTXLIBS)`` at the previous step,
|
|
the ``make`` build system will ``install`` them at a special ``staging/`` directory, residing at the
|
|
root of the NuttX tree.
|
|
|
|
These libraries are passed to the the final target rule (``$(BIN)``).
|
|
|
|
.. code-block:: makefile
|
|
|
|
# Unix.mk : line 536
|
|
$(BIN): pass1 pass2
|
|
# ...
|
|
$(Q) $(MAKE) -C $(ARCH_SRC) EXTRA_OBJS="$(EXTRA_OBJS)" LINKLIBS="$(LINKLIBS)" APPDIR="$(APPDIR)" EXTRAFLAGS="$(KDEFINE) $(EXTRAFLAGS)" $(BIN)
|
|
# ...
|
|
|
|
.. _win_mk:
|
|
|
|
Win.mk
|
|
------
|
|
|
|
Although targeting different platforms, both **Win.mk** and **Unix.mk** aim to produce
|
|
the same output. The need for independent files is due to the differences in the
|
|
platform's approaches.
|
|
|
|
Forward vs Back slashes
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
One of the main differences is the use of forward slashes
|
|
(``/``) on unix-like platforms versus backslashes (``\``) on windows
|
|
|
|
${HOSTEXEEXT} ${HOSTDYNEXT}
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
These variables are used by the build system to configure the executable suffix required
|
|
by the used platform. They are defined in :ref:`config_mk`.
|
|
|
|
For windows platform:
|
|
|
|
- ``${HOSTEXEEXT}`` is set to ``.exe``.
|
|
- ``${HOSTDYNEXT}`` is set to ``.dll``.
|
|
|
|
Symbolic Linking
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
For the windows platform, the build system handles symbolic links differently.
|
|
|
|
.. _unix_mk:
|
|
|
|
Unix.mk
|
|
-------
|
|
|
|
Versioning
|
|
^^^^^^^^^^
|
|
|
|
The build system will impact versioning if NuttX is cloned as a repo. See :ref:`versioning`.
|
|
|
|
config.h, .config, mkconfig
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
NuttX's build system defers the ``config.h`` generation to a separate tool called
|
|
``mkconfig``. See :ref:`makefile_host`.
|
|
|
|
.. code-block:: makefile
|
|
|
|
tools/mkconfig$(HOSTEXEEXT): prebuild
|
|
$(Q) $(MAKE) -C tools -f Makefile.host mkconfig$(HOSTEXEEXT)
|
|
|
|
The ``include/nuttx/config.h`` recipe calls the ``mkconfig`` executable generated by the
|
|
rule above to create the ``config.h`` file from the current ``.config`` file.
|
|
|
|
Symlinks & dirlinks
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
Dirlinks are symbolic links that allow the build system to use generic paths while pointing
|
|
to architecture-specific, chip-specific, or board-specific directories. This enables a single
|
|
build system workflow across many different hardware configurations.
|
|
|
|
- Symlink ``arch/<arch-name>/include`` to ``include/arch``
|
|
- Symlink ``boards/<arch>/<chip>/<board>/include`` to ``include/arch/board``
|
|
- Symlink ``arch/<arch-name>/include/<chip-name>`` to ``include/arch/chip``
|
|
- Symlink ``boards/<arch>/<chip>/<board>`` to ``arch/<arch-name>/src/board/<board>``
|
|
|
|
.. note::
|
|
|
|
Some boards make use of a ``common`` directory. In that case:
|
|
|
|
- ``boards/<arch>/<chip>/common`` is symlinked to ``arch/<arch-name>/src/board``
|
|
- ``boards/<arch>/<chip>/<board>`` is symlinked to ``arch/<arch-name>/src/board/<board>``
|
|
|
|
- Symlink ``arch/<arch-name>/src/<chip-name>`` to ``arch/<arch-name>/src/chip``
|
|
|
|
The ``.dirlinks`` file itself is just a timestamp marker that indicates all dirlinks have been
|
|
created.
|
|
|
|
Dummies
|
|
^^^^^^^
|
|
|
|
The main reason for the use of dummies is to handle some specific scenarios, such as external
|
|
code bases, custom chips and boards or to overcome tooling limitations. If any of the features below
|
|
are not used, the build system will fallback to a dummy.
|
|
|
|
- **${EXTERNALDIR}**
|
|
|
|
Possible values for ``$(EXTERNALDIR)`` are ``external`` or ``dummy``.
|
|
|
|
NuttX code base can be extended by using ``$(TOPDIR)/external/`` directory.
|
|
The build system searches for a ``Kconfig`` file in that directory. If found,
|
|
the build system defines the ``EXTERNALDIR`` variable to ``external`` and also
|
|
appends another lib (``libexternal``) to the build process.
|
|
|
|
.. code-block:: makefile
|
|
|
|
# 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 'dummy'; fi)
|
|
|
|
- **dummy/Kconfig**
|
|
|
|
The ``dummy/Kconfig`` is used to handle custom chips and boards.
|
|
|
|
If in-tree chip/board is used, the build system will resolve to dummy_kconfig files.
|
|
- ``$(CHIP_KCONFIG)`` is set to ``$(TOPDIR)$(DELIM)arch$(DELIM)dummy$(DELIM)dummy_kconfig``
|
|
- ``$(BOARD_KCONFIG)`` is set to ``$(TOPDIR)$(DELIM)boards$(DELIM)dummy$(DELIM)dummy_kconfig``
|
|
|
|
If custom chip/board is used, the build system will resolve to their custom paths.
|
|
|
|
.. code-block:: makefile
|
|
|
|
# Copy $(CHIP_KCONFIG) to arch/dummy/Kconfig
|
|
|
|
arch/dummy/Kconfig:
|
|
@echo "CP: $@ to $(CHIP_KCONFIG)"
|
|
$(Q) cp -f $(CHIP_KCONFIG) $@
|
|
|
|
# Copy $(BOARD_KCONFIG) to boards/dummy/Kconfig
|
|
|
|
boards/dummy/Kconfig:
|
|
@echo "CP: $@ to $(BOARD_KCONFIG)"
|
|
$(Q) cp -f $(BOARD_KCONFIG) $@
|
|
|
|
- **boards/dummy.c**
|
|
|
|
A special ``boards/dummy.c`` file is used by the build system to generate a useless object.
|
|
The purpose of the useless object is to assure that libboards.a/lib is created. Some archivers
|
|
(ZDS-II, SDCC) require a non-empty library or they will generate errors.
|
|
|
|
.. _build_modes:
|
|
|
|
Build Modes
|
|
^^^^^^^^^^^
|
|
|
|
As specified above, NuttX supports multiple build modes. The build mode is selected
|
|
based on specific ``Kconfig`` options.
|
|
|
|
.. code-block:: makefile
|
|
|
|
# Library build selections
|
|
#
|
|
# NUTTXLIBS is the list of NuttX libraries that is passed to the
|
|
# processor-specific Makefile to build the final NuttX target.
|
|
# USERLIBS is the list of libraries used to build the final user-space
|
|
# application
|
|
# EXPORTLIBS is the list of libraries that should be exported by
|
|
# 'make export' is
|
|
|
|
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
|
include tools/ProtectedLibs.mk
|
|
else ifeq ($(CONFIG_BUILD_KERNEL),y)
|
|
include tools/KernelLibs.mk
|
|
else
|
|
include tools/FlatLibs.mk
|
|
endif
|
|
|
|
The content of each file referenced above is documented in its own section.
|
|
|
|
- tools/ProtectedLibs.mk :ref:`protectedlibs_mk`
|
|
- tools/FlatLibs.mk :ref:`flatlibs_mk`
|
|
- tools/KernelLibs.mk :ref:`kernelibs_mk`
|
|
|
|
.. _config_mk:
|
|
|
|
Config.mk
|
|
---------
|
|
|
|
``Config.mk`` contains common definitions used by many configuration files.
|
|
|
|
* It defines the logic behind the :ref:`verbosity`
|
|
* It resolves the platform specific particularities, such as
|
|
|
|
* build *tools* ``e.g. mkdeps, cnvwindeps, link.sh/.bat, unlink.sh/.bat``
|
|
* file extensions ``e.g. .exe, .dll for windows, .o, .a for unix``
|
|
* delim based on the host platform. ``e.g. \ for windows, / for unix``
|
|
|
|
* Resolve custom bard/chip/arch
|
|
* Defines the rules for the dependency mechanism
|
|
|
|
.. code-block:: makefile
|
|
|
|
OBJPATH ?= .
|
|
|
|
%.dds: %.S
|
|
$(Q) $(MKDEP) --obj-path $(OBJPATH) --obj-suffix $(OBJEXT) $(DEPPATH) "$(CC)" -- $(CFLAGS) -- $< > $@
|
|
|
|
%.ddc: %.c
|
|
$(Q) $(MKDEP) --obj-path $(OBJPATH) --obj-suffix $(OBJEXT) $(DEPPATH) "$(CC)" -- $(CFLAGS) -- $< > $@
|
|
|
|
%.ddp: %.cpp
|
|
$(Q) $(MKDEP) --obj-path $(OBJPATH) --obj-suffix $(OBJEXT) $(DEPPATH) "$(CXX)" -- $(CXXFLAGS) -- $< > $@
|
|
|
|
%.ddx: %.cxx
|
|
$(Q) $(MKDEP) --obj-path $(OBJPATH) --obj-suffix $(OBJEXT) $(DEPPATH) "$(CXX)" -- $(CXXFLAGS) -- $< > $@
|
|
|
|
%.ddh: %.c
|
|
$(Q) $(MKDEP) --obj-path $(OBJPATH) --obj-suffix $(OBJEXT) $(DEPPATH) "$(CC)" -- $(HOSTCFLAGS) -- $< > $@
|
|
|
|
* Defines the include flag prefix based on compiler
|
|
* Defines the common functions used to compile, assemble, archive files, etc.
|
|
|
|
This file (along with *<nuttx>*/.config) must be included at the top of
|
|
each configuration-specific Make.defs file like
|
|
|
|
.. code-block:: makefile
|
|
|
|
include $(TOPDIR)/.config
|
|
include $(TOPDIR)/tools/Config.mk
|
|
|
|
Subsequent logic within the configuration-specific Make.defs file may then
|
|
override these default definitions as necessary.
|
|
|
|
|
|
.. _flatlibs_mk:
|
|
|
|
FlatLibs.mk
|
|
-----------
|
|
|
|
This file defines the library sets for the **flat build mode**. In this mode,
|
|
the NuttX kernel and all user-space applications are compiled and linked into a
|
|
single, monolithic binary.
|
|
|
|
Its primary responsibilities are:
|
|
|
|
- **Populating ``NUTTXLIBS``:** The file systematically appends all required
|
|
libraries to the ``NUTTXLIBS`` variable. This includes core OS libraries
|
|
(``libsched``, ``libmm``, ``libc``), architecture and board support libraries,
|
|
and device drivers.
|
|
|
|
- **Conditional Library Inclusion:** It uses ``ifeq ($(CONFIG_XXX),y)`` checks
|
|
to conditionally include libraries for optional features based on the
|
|
system's Kconfig. For example, ``staging/libnet.a`` is added only if
|
|
``CONFIG_NET=y``, and ``staging/libcrypto.a`` is added if ``CONFIG_CRYPTO=y``.
|
|
|
|
- **Defining ``USERLIBS``:** In the flat build, there is no separate user-space
|
|
binary, so the ``USERLIBS`` variable is initialized but remains empty.
|
|
|
|
- **Setting ``EXPORTLIBS``:** It assigns the complete list of ``NUTTXLIBS`` to
|
|
the ``EXPORTLIBS`` variable. This ensures that the ``make export`` command
|
|
packages all the compiled libraries required to link the final binary.
|
|
|
|
.. _protectedlibs_mk:
|
|
|
|
ProtectedLibs.mk
|
|
----------------
|
|
|
|
This file defines the library sets for the **protected build mode**. In this mode,
|
|
the NuttX kernel and user-space applications are built as two distinct binaries,
|
|
enabling memory protection and a more robust system architecture.
|
|
|
|
Its primary responsibilities are:
|
|
|
|
- **Separate Library Lists:** Unlike the flat build, this file populates both
|
|
the ``NUTTXLIBS`` variable (for the kernel binary) and the ``USERLIBS`` variable
|
|
(for user-space applications).
|
|
|
|
- **Kernel vs. User Library Variants:** It explicitly differentiates between
|
|
kernel and user variants of core libraries. For instance:
|
|
|
|
- Kernel-specific libraries (e.g., ``libkc.a``, ``libkmm.a``, ``libkarch.a``)
|
|
are added to ``NUTTXLIBS``.
|
|
- User-space counterparts (e.g., ``libc.a``, ``libmm.a``, ``libarch.a``)
|
|
are added to ``USERLIBS``.
|
|
|
|
- **System Call Mechanism:** It includes essential components for the system
|
|
call interface:
|
|
|
|
- ``staging/libstubs.a`` (system call stubs) is added to ``NUTTXLIBS``.
|
|
- ``staging/libproxies.a`` (system call proxies) is added to ``USERLIBS``.
|
|
These facilitate safe communication between user applications and the kernel.
|
|
|
|
- **Conditional Library Inclusion:** Similar to other build modes, it uses
|
|
``ifeq ($(CONFIG_XXX),y)`` checks to conditionally include libraries for
|
|
optional features in both kernel and user-space, based on the Kconfig settings.
|
|
|
|
- **Exporting User Libraries:** A key distinction is that ``EXPORTLIBS`` is set
|
|
to ``$(USERLIBS)``. This means that the ``make export`` command will primarily
|
|
package the user-space libraries, which are then used by external build
|
|
systems or for linking user applications.
|
|
|
|
.. _kernelibs_mk:
|
|
|
|
KernelLibs.mk
|
|
-------------
|
|
|
|
This file defines the library sets for the **kernel build mode**. In this mode,
|
|
only the NuttX kernel is compiled and linked into a single binary. User
|
|
applications are expected to be loaded and executed separately, typically in a
|
|
protected user-space environment.
|
|
|
|
Its primary responsibilities are:
|
|
|
|
- **Kernel-Only ``NUTTXLIBS``:** The file populates the ``NUTTXLIBS`` variable
|
|
with all the necessary kernel-space libraries. This includes core OS
|
|
components (e.g., ``libsched``, ``libdrivers``), kernel variants of common
|
|
libraries (e.g., ``libkc.a``, ``libkmm.a``, ``libkarch.a``), and board support.
|
|
|
|
- **Empty ``USERLIBS``:** The ``USERLIBS`` variable is explicitly initialized
|
|
but remains empty, as this build mode does not produce a user-space binary.
|
|
|
|
- **System Call Stubs:** It includes ``staging/libstubs.a`` in ``NUTTXLIBS``,
|
|
providing the kernel-side implementation for system calls. User-space system
|
|
call proxies (``libproxies.a``) are not included, consistent with the absence
|
|
of a user-space build.
|
|
|
|
- **Conditional Library Inclusion:** It uses ``ifeq ($(CONFIG_XXX),y)`` checks
|
|
to conditionally include kernel-specific libraries for optional features
|
|
based on the system's Kconfig.
|
|
|
|
- **Exporting User Libraries (Empty):** ``EXPORTLIBS`` is set to ``$(USERLIBS)``.
|
|
Consequently, in this kernel-only build mode, ``EXPORTLIBS`` will be empty,
|
|
reflecting that no user-space libraries are produced for external packaging.
|
|
|
|
.. _directories_mk:
|
|
|
|
Directories.mk
|
|
--------------
|
|
|
|
This file defines the directories used throughout the NuttX build process.
|
|
These directory lists are not static but are **dynamically constructed**
|
|
based on the active Kconfig configuration.
|
|
|
|
The file begins by defining a ``BASEDIRS`` variable, which includes core directories
|
|
that are always part of the build. Subsequently, it uses conditional logic
|
|
(``ifeq ($(CONFIG_XXX),y)``) to append additional directories to various master lists,
|
|
such as ``ALLDIRS`` and ``CLEANDIRS``, only if their corresponding Kconfig options are
|
|
enabled.
|
|
|
|
For example:
|
|
|
|
- The ``net/`` directory is added to the build lists only if ``CONFIG_NET=y``.
|
|
- The ``graphics/`` directory is included if ``CONFIG_GRAPHICS=y``.
|
|
- The ``crypto/`` directory is included if ``CONFIG_CRYPTO=y``.
|
|
|
|
The file defines key variables that hold these dynamically generated directory lists:
|
|
|
|
- ``KERNDEPDIRS``: Directories containing kernel files for dependency generation.
|
|
- ``USERDEPDIRS``: Directories containing user-space files for dependency generation.
|
|
- ``CCLEANDIRS``: Directories where the ``clean_context`` target will execute.
|
|
- ``CLEANDIRS``: All known directories where the ``clean`` target will execute.
|
|
- ``CONTEXTDIRS``: Directories with special pre-build requirements, such as auto-generation of files or symbolic link creation.
|
|
|
|
.. _libtargets_mk:
|
|
|
|
LibTargets.mk
|
|
-------------
|
|
|
|
The ``LibTargets.mk`` file defines all the targets needed to build the NuttX
|
|
libraries from their respective source directories and then install the
|
|
resulting library file into the ``staging/`` directory.
|
|
|
|
For many core libraries (e.g., ``libc``, ``libm``, ``libmm``, ``libbuiltin``, ``libnx``, ``libarch``),
|
|
``LibTargets.mk`` defines distinct targets for **kernel** and **user** variants.
|
|
|
|
- **Kernel libraries** are typically prefixed with ``libk`` (e.g., ``libkc.a`` for kernel C library,
|
|
``libkmm.a`` for kernel memory management). These are compiled with specific
|
|
``EXTRAFLAGS`` that include ``$(KDEFINE)``, which sets kernel-specific preprocessor
|
|
definitions (e.g., ``-D__KERNEL__``). This ensures they are built with the necessary
|
|
context and APIs for the kernel environment.
|
|
|
|
- **User libraries** retain their standard names (e.g., ``libc.a``, ``libmm.a``).
|
|
These are compiled without the ``$(KDEFINE)`` flag, making them suitable for user-space
|
|
applications. The build process for user-mode libraries often depends on ``pass1dep``,
|
|
while kernel-mode libraries depend on ``pass2dep``, reflecting the two-pass build
|
|
strategy in protected and kernel build modes.
|
|
|
|
For each variant of a library, two main targets are defined:
|
|
|
|
1. **A build target:** This target recursively calls ``make`` within the library's
|
|
source directory (e.g., ``libs/libc/``, ``mm/``) to compile the sources and create
|
|
the library archive (``.a``) file. It passes the appropriate ``EXTRAFLAGS``
|
|
depending on whether it's a kernel-mode or user-mode build. The dependency for
|
|
these targets is either ``pass1dep`` or ``pass2dep``, ensuring dependencies are
|
|
checked before building.
|
|
|
|
2. **A staging target:** This target depends on the successful creation of the
|
|
library archive from the previous step. Its recipe calls the ``INSTALL_LIB``
|
|
macro (defined in ``Unix.mk`` or ``Win.mk``) to copy the newly created
|
|
library to the top-level ``staging/`` directory.
|
|
|
|
The file contains conditional logic, primarily based on ``CONFIG_BUILD_FLAT``,
|
|
to adjust dependencies (``pass1dep`` vs. ``pass2dep``) for libraries that can
|
|
be part of either the user or kernel space, ensuring they are built in the
|
|
correct pass according to the selected build mode.
|