From e09c8e510e05f33f1426f7e3854cf42e59a1244f Mon Sep 17 00:00:00 2001 From: LuchianMihai Date: Mon, 6 Oct 2025 11:07:02 +0300 Subject: [PATCH] Documentation/Make: add implementation/make_build_system.rst 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 --- Documentation/components/tools/index.rst | 19 +- .../guides/versioning_and_task_names.rst | 2 + Documentation/implementation/index.rst | 1 + .../implementation/make_build_system.rst | 607 ++++++++++++++++++ 4 files changed, 616 insertions(+), 13 deletions(-) create mode 100644 Documentation/implementation/make_build_system.rst diff --git a/Documentation/components/tools/index.rst b/Documentation/components/tools/index.rst index 4f21d7f79c7..6b82fb1f1be 100644 --- a/Documentation/components/tools/index.rst +++ b/Documentation/components/tools/index.rst @@ -13,19 +13,6 @@ cmpconfig.c This C file can be used to build a utility for comparing two NuttX configuration files. -Config.mk ---------- - -Config.mk contains common definitions used by many configuration files. -This file (along with /.config) must be included at the top of -each configuration-specific Make.defs file like:: - - 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. - checkpatch.sh ------------- @@ -740,6 +727,8 @@ these problems:: - option env="APPSDIR" + default "../apps" +.. _build_system_linking: + link.sh, link.bat, copydir.sh, copydir.bat, unlink.sh, and unlink.bat --------------------------------------------------------------------- @@ -780,6 +769,8 @@ this case. link.bat will attempt to create a symbolic link using the NTFS mklink.exe command instead of copying files. That logic, however, has not been verified as of this writing. +.. _makefile_host: + Makefile.host ------------- @@ -801,6 +792,8 @@ may be mounted under /etc in the NuttX pseudo file system. TIP: Edit the resulting header file and mark the generated data values as 'const' so that they will be stored in FLASH. +.. _mkdeps: + mkdeps.c, cnvwindeps.c, mkwindeps.sh, and mknulldeps.sh ------------------------------------------------------- diff --git a/Documentation/guides/versioning_and_task_names.rst b/Documentation/guides/versioning_and_task_names.rst index cebcbe5f27e..62b80bd9e22 100644 --- a/Documentation/guides/versioning_and_task_names.rst +++ b/Documentation/guides/versioning_and_task_names.rst @@ -33,6 +33,8 @@ Answer This is probably normal behavior. There are two separate, unrelated issues here. +.. _versioning: + Versioning ---------- diff --git a/Documentation/implementation/index.rst b/Documentation/implementation/index.rst index 05a87949672..b22b452a9ab 100644 --- a/Documentation/implementation/index.rst +++ b/Documentation/implementation/index.rst @@ -6,6 +6,7 @@ Implementation Details :maxdepth: 2 :caption: Contents: + make_build_system.rst drivers_design.rst device_drivers.rst processes_vs_tasks.rst diff --git a/Documentation/implementation/make_build_system.rst b/Documentation/implementation/make_build_system.rst new file mode 100644 index 00000000000..09096618d11 --- /dev/null +++ b/Documentation/implementation/make_build_system.rst @@ -0,0 +1,607 @@ +================= +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 `_ + + 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//include`` to ``include/arch`` +- Symlink ``boards////include`` to ``include/arch/board`` +- Symlink ``arch//include/`` to ``include/arch/chip`` +- Symlink ``boards///`` to ``arch//src/board/`` + +.. note:: + + Some boards make use of a ``common`` directory. In that case: + + - ``boards///common`` is symlinked to ``arch//src/board`` + - ``boards///`` is symlinked to ``arch//src/board/`` + +- Symlink ``arch//src/`` to ``arch//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 **/.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.