|
| 1 | +.. _make_build_system: |
| 2 | + |
| 3 | +================= |
| 4 | +Make Build System |
| 5 | +================= |
| 6 | + |
| 7 | +Currently, NuttX supports both CMake and Make build systems. |
| 8 | +This guide explains the NuttX `make`-based build system. |
| 9 | + |
| 10 | +Due to *requirements, constraints, and the complexity of the build process*, NuttX divides |
| 11 | +this work into multiple files, each handling specific parts of the build process. |
| 12 | + |
| 13 | +As stated in :doc:`/introduction/inviolables`, multiple platforms should be supported: |
| 14 | + |
| 15 | +- :ref:`win_mk`: handles windows platform support. |
| 16 | +- :ref:`unix_mk`: handles unix-like platforms support. |
| 17 | + |
| 18 | +NuttX supports multiple build modes. See :doc:`protected_build`: |
| 19 | + |
| 20 | +- :ref:`flatlibs_mk`: Kernel and user-space built into a single `blob`. |
| 21 | +- :ref:`protectedlibs_mk`: Kernel and user-space built as two separate `blobs`. |
| 22 | +- :ref:`kernelibs_mk`: Kernel built into single `blob`. User apps must be loaded |
| 23 | + into memory for execution. |
| 24 | + |
| 25 | +NuttX targets multiple libs, or `silos`, each handling its own compilation: |
| 26 | + |
| 27 | +.. note:: |
| 28 | + |
| 29 | + Gregory Nutt has a nice presentation about |
| 30 | + `NuttX architecture <https://cwiki.apache.org/confluence/pages/viewpage.action? |
| 31 | + pageId=139629399&preview=/139629402/140774623/nuttx-3-archoverview.pdf>`_ |
| 32 | + |
| 33 | + There the `silo` concept is explained. Only the `silos` there are listed below as libs. |
| 34 | + The build mode influences the needed libs. |
| 35 | + |
| 36 | +.. code-block:: console |
| 37 | +
|
| 38 | + $ ls -l staging/ |
| 39 | + drwxr-xr-x 2 xxx xxx 4096 Oct 6 16:02 . |
| 40 | + drwxr-xr-x 27 xxx xxx 4096 Oct 6 16:02 .. |
| 41 | + -rw-r--r-- 1 xxx xxx 323640 Oct 6 16:02 libapps.a |
| 42 | + -rw-r--r-- 1 xxx xxx 384352 Oct 6 16:02 libarch.a |
| 43 | + -rw-r--r-- 1 xxx xxx 62182 Oct 6 16:02 libbinfmt.a |
| 44 | + -rw-r--r-- 1 xxx xxx 6468 Oct 6 16:01 libboards.a |
| 45 | + -rw-r--r-- 1 xxx xxx 2820054 Oct 6 16:02 libc.a |
| 46 | + -rw-r--r-- 1 xxx xxx 161486 Oct 6 16:01 libdrivers.a |
| 47 | + -rw-r--r-- 1 xxx xxx 981638 Oct 6 16:02 libfs.a |
| 48 | + -rw-r--r-- 1 xxx xxx 224446 Oct 6 16:02 libmm.a |
| 49 | + -rw-r--r-- 1 xxx xxx 2435746 Oct 6 16:01 libsched.a |
| 50 | + -rw-r--r-- 1 xxx xxx 51768 Oct 6 16:02 libxx.a |
| 51 | +
|
| 52 | +Verbosity |
| 53 | +--------- |
| 54 | + |
| 55 | +The ``V`` variable can be passed to ``make`` to control the build verbosity. |
| 56 | + |
| 57 | +- **Quiet (Default):** The build output is minimal. |
| 58 | +- **Verbose (`V=1 V=2`):** Shows the full compiler commands *(enables command echo)*. |
| 59 | +- **Verbose Tools (`V=2`):** Enables verbose output for tools and scripts. |
| 60 | + |
| 61 | +.. code-block:: console |
| 62 | +
|
| 63 | + # V=1,2: Enable echo of commands |
| 64 | + $ make V=1 |
| 65 | +
|
| 66 | + # V=2: Enable bug/verbose options in tools and scripts |
| 67 | + $ make V=2 |
| 68 | +
|
| 69 | +Build Flow |
| 70 | +---------- |
| 71 | + |
| 72 | +The root **Makefile** is the build process entrypoint. Its main job is |
| 73 | +to check for a ``.config`` file and include the appropriate **host-specific Makefile**. |
| 74 | + |
| 75 | +.. _win_mk: |
| 76 | + |
| 77 | +Win.mk |
| 78 | +------ |
| 79 | + |
| 80 | +Although targeting different platforms, both **Win.mk** and **Unix.mk** aim to produce |
| 81 | +the same output. The need for independent files is due to the differences in the |
| 82 | +platform's approaches. |
| 83 | + |
| 84 | +forward vs back slashes |
| 85 | +^^^^^^^^^^^^^^^^^^^^^^^ |
| 86 | + |
| 87 | +One of the main differences is the use of forward slashes |
| 88 | +(``/``) on unix-like platforms versus backslashes (``\``) on windows |
| 89 | + |
| 90 | +${HOSTEXEEXT} ${HOSTDYNEXT} |
| 91 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 92 | + |
| 93 | +These variables are used by the build system to configure the executable suffix required |
| 94 | +by the used platform. They are defined in :ref:`config_mk`. |
| 95 | + |
| 96 | +For windows platform: |
| 97 | + |
| 98 | +- ``${HOSTEXEEXT}`` is set to ``.exe``. |
| 99 | +- ``${HOSTDYNEXT}`` is set to ``.dll``. |
| 100 | + |
| 101 | +Symbolic Linking |
| 102 | +^^^^^^^^^^^^^^^^ |
| 103 | + |
| 104 | +For the windows platform, the build system handles symbolic links differently. |
| 105 | + |
| 106 | +The differences and drawbacks of the windows platform are explained in |
| 107 | +:ref:`build_system_linking`. |
| 108 | + |
| 109 | +.. _unix_mk: |
| 110 | + |
| 111 | +Unix.mk |
| 112 | +------- |
| 113 | + |
| 114 | +Versioning |
| 115 | +^^^^^^^^^^ |
| 116 | + |
| 117 | +The build system will impact versioning if NuttX is cloned as a repo. See :ref:`versioning`. |
| 118 | + |
| 119 | +config.h .config mkconfig |
| 120 | +^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 121 | + |
| 122 | +NuttX's build system defers the ``config.h`` generation to a separate tool called |
| 123 | +``mkconfig``. See :ref:`makefile_host`. |
| 124 | + |
| 125 | +.. code-block:: makefile |
| 126 | +
|
| 127 | + tools/mkconfig$(HOSTEXEEXT): prebuild |
| 128 | + $(Q) $(MAKE) -C tools -f Makefile.host mkconfig$(HOSTEXEEXT) |
| 129 | +
|
| 130 | +The ``include/nuttx/config.h`` recipe calls the ``mkconfig`` executable generated by the |
| 131 | +rule above to create the ``config.h`` file from the current ``.config`` file. |
| 132 | + |
| 133 | +Symlinks & dirlinks |
| 134 | +^^^^^^^^^^^^^^^^^^^ |
| 135 | + |
| 136 | +Dirlinks are symbolic links that allow the build system to use generic paths while pointing |
| 137 | +to architecture-specific, chip-specific, or board-specific directories. This enables a single |
| 138 | +build system workflow across many different hardware configurations. |
| 139 | + |
| 140 | +- Symlink ``arch/<arch-name>/include`` to ``include/arch`` |
| 141 | +- Symlink ``boards/<arch>/<chip>/<board>/include`` to ``include/arch/board`` |
| 142 | +- Symlink ``arch/<arch-name>/include/<chip-name>`` to ``include/arch/chip`` |
| 143 | +- Symlink ``boards/<arch>/<chip>/<board>`` to ``arch/<arch-name>/src/board/<board>`` |
| 144 | + |
| 145 | +.. note:: |
| 146 | + |
| 147 | + Some boards make use of a ``common`` directory. In that case: |
| 148 | + |
| 149 | + - ``boards/<arch>/<chip>/common`` is symlinked to ``arch/<arch-name>/src/bb oard`` |
| 150 | + - ``boards/<arch>/<chip>/<board>`` is symlinked to ``arch/<arch-name>/src/board/<board>`` |
| 151 | + |
| 152 | +- Symlink ``arch/<arch-name>/src/<chip-name>`` to ``arch/<arch-name>/src/chip`` |
| 153 | + |
| 154 | +The ``.dirlinks`` file itself is just a timestamp marker that indicates all dirlinks have been |
| 155 | +created. |
| 156 | + |
| 157 | +Dummies |
| 158 | +^^^^^^^ |
| 159 | + |
| 160 | +The main reason for the use of dummies is to handle some specific scenarios, such as external |
| 161 | +code bases, custom chips and boards or to overcome tooling limitations. If any of the features below |
| 162 | +are not used, the build system will fallback to a dummy. |
| 163 | + |
| 164 | +- **${EXTERNALDIR}** |
| 165 | + |
| 166 | + Possible values for ``$(EXTERNALDIR)`` are ``external`` or ``dummy``. |
| 167 | + |
| 168 | + NuttX code base can be extended by using ``$(TOPDIR)/external/`` directory. |
| 169 | + The build system searches for a ``Kconfig`` file in that directory. If found, |
| 170 | + the build system defines the ``EXTERNALDIR`` variable to ``external`` and also |
| 171 | + appends another lib (``libexternal``) to the build process. |
| 172 | + |
| 173 | + .. code-block:: makefile |
| 174 | +
|
| 175 | + # External code support |
| 176 | + # If external/ contains a Kconfig, we define the EXTERNALDIR variable to 'external' |
| 177 | + # so that main Kconfig can find it. Otherwise, we redirect it to a dummy Kconfig |
| 178 | + # This is due to kconfig inability to do conditional inclusion. |
| 179 | +
|
| 180 | + EXTERNALDIR := $(shell if [ -r $(TOPDIR)/external/Kconfig ]; then echo 'external'; else echo 'dummy'; fi) |
| 181 | +
|
| 182 | +- **dummy/Kconfig** |
| 183 | + |
| 184 | + The ``dummy/Kconfig`` is used to handle custom chips and boards. |
| 185 | + |
| 186 | + If in-tree chip/board is used, the build system will resolve to dummy_kconfig files. |
| 187 | + - ``$(CHIP_KCONFIG)`` is set to ``$(TOPDIR)$(DELIM)arch$(DELIM)dummy$(DELIM)dummy_kconfig`` |
| 188 | + - ``$(BOARD_KCONFIG)`` is set to ``$(TOPDIR)$(DELIM)boards$(DELIM)dummy$(DELIM)dummy_kconfig`` |
| 189 | + |
| 190 | + If custom chip/board is used, the build system will resolve to their custom paths. |
| 191 | + |
| 192 | + .. code-block:: makefile |
| 193 | +
|
| 194 | + # Copy $(CHIP_KCONFIG) to arch/dummy/Kconfig |
| 195 | +
|
| 196 | + arch/dummy/Kconfig: |
| 197 | + @echo "CP: $@ to $(CHIP_KCONFIG)" |
| 198 | + $(Q) cp -f $(CHIP_KCONFIG) $@ |
| 199 | +
|
| 200 | + # Copy $(BOARD_KCONFIG) to boards/dummy/Kconfig |
| 201 | +
|
| 202 | + boards/dummy/Kconfig: |
| 203 | + @echo "CP: $@ to $(BOARD_KCONFIG)" |
| 204 | + $(Q) cp -f $(BOARD_KCONFIG) $@ |
| 205 | +
|
| 206 | +- **boards/dummy.c** |
| 207 | + |
| 208 | + A special ``boards/dummy.c`` file is used by the build system to generate a useless object. |
| 209 | + The purpose of the useless object is to assure that libboards.a/lib is created. Some archivers |
| 210 | + (ZDS-II, SDCC) require a non-empty library or they will generate errors. |
| 211 | + |
| 212 | +.. _build_modes: |
| 213 | + |
| 214 | +Build Modes |
| 215 | +^^^^^^^^^^^ |
| 216 | + |
| 217 | +As specified above, NuttX supports multiple build modes. The build mode is selected |
| 218 | +based on specific ``Kconfig`` options. |
| 219 | + |
| 220 | +.. code-block:: makefile |
| 221 | +
|
| 222 | + # Library build selections |
| 223 | + # |
| 224 | + # NUTTXLIBS is the list of NuttX libraries that is passed to the |
| 225 | + # processor-specific Makefile to build the final NuttX target. |
| 226 | + # USERLIBS is the list of libraries used to build the final user-space |
| 227 | + # application |
| 228 | + # EXPORTLIBS is the list of libraries that should be exported by |
| 229 | + # 'make export' is |
| 230 | +
|
| 231 | + ifeq ($(CONFIG_BUILD_PROTECTED),y) |
| 232 | + include tools/ProtectedLibs.mk |
| 233 | + else ifeq ($(CONFIG_BUILD_KERNEL),y) |
| 234 | + include tools/KernelLibs.mk |
| 235 | + else |
| 236 | + include tools/FlatLibs.mk |
| 237 | + endif |
| 238 | +
|
| 239 | +The content of each file referenced above is documented in its own section. |
| 240 | + |
| 241 | +- tools/ProtectedLibs.mk :ref:`protectedlibs_mk` |
| 242 | +- tools/FlatLibs.mk :ref:`flatlibs_mk` |
| 243 | +- tools/KernelLibs.mk :ref:`kernelibs_mk` |
| 244 | + |
| 245 | +Final target, pass1 & pass2 |
| 246 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 247 | + |
| 248 | +The final NuttX binary is always generated by running both ``pass1`` and ``pass2`` targets, although |
| 249 | +the actual dependencies of the mentioned targets may vary depending on the build mode. |
| 250 | + |
| 251 | +The different NuttX build modes will not influence the "execution" of the ``pass1`` and ``pass2`` targets, |
| 252 | +but rather will influence the dependencies pulled by those targets. |
| 253 | + |
| 254 | +- ``pass1`` target depends on the ``$(USERLIBS)``. |
| 255 | +- ``pass2`` target depends on the ``$(NUTTXLIBS)``. |
| 256 | + |
| 257 | +.. code-block:: |
| 258 | +
|
| 259 | + all: pass1 pass2 |
| 260 | +
|
| 261 | + pass1: $(USERLIBS) |
| 262 | + pass2: $(NUTTXLIBS) |
| 263 | +
|
| 264 | +The content of the ``$(USERLIBS)`` and ``$(NUTTXLIBS)`` variables is defined in each build mode makefile. |
| 265 | +See :ref:`build_modes` above. |
| 266 | + |
| 267 | +.. _flatlibs_mk: |
| 268 | + |
| 269 | +FlatLibs.mk |
| 270 | +----------- |
| 271 | + |
| 272 | +placeholder |
| 273 | + |
| 274 | +.. _protectedlibs_mk: |
| 275 | + |
| 276 | +ProtectedLibs.mk |
| 277 | +---------------- |
| 278 | + |
| 279 | +placeholder |
| 280 | + |
| 281 | +.. _kernelibs_mk: |
| 282 | + |
| 283 | +KernelLibs.mk |
| 284 | +------------- |
| 285 | + |
| 286 | +placeholder |
| 287 | + |
| 288 | +.. _directories_mk: |
| 289 | + |
| 290 | +Directories.mk |
| 291 | +-------------- |
| 292 | + |
| 293 | +placeholder |
| 294 | + |
| 295 | +.. _libtargets_mk: |
| 296 | + |
| 297 | +LibTargets.mk |
| 298 | +------------- |
| 299 | + |
| 300 | +placeholder |
| 301 | + |
| 302 | +.. _config_mk: |
| 303 | + |
| 304 | +Config.mk |
| 305 | +--------- |
0 commit comments