xref: /dpdk/doc/guides/contributing/coding_style.rst (revision 3c4898ef762eeb2578b9ae3d7f6e3a0e5cbca8c8)
177c79de0SHemant Agrawal..  SPDX-License-Identifier: BSD-3-Clause
277c79de0SHemant Agrawal    Copyright 2018 The DPDK contributors
377c79de0SHemant Agrawal
46bdae907SThomas Monjalon.. _coding_style:
56bdae907SThomas Monjalon
66bdae907SThomas MonjalonDPDK Coding Style
76bdae907SThomas Monjalon=================
86bdae907SThomas Monjalon
96bdae907SThomas MonjalonDescription
106bdae907SThomas Monjalon-----------
116bdae907SThomas Monjalon
126bdae907SThomas MonjalonThis document specifies the preferred style for source files in the DPDK source tree.
136bdae907SThomas MonjalonIt is based on the Linux Kernel coding guidelines and the FreeBSD 7.2 Kernel Developer's Manual (see man style(9)), but was heavily modified for the needs of the DPDK.
146bdae907SThomas Monjalon
156bdae907SThomas MonjalonGeneral Guidelines
166bdae907SThomas Monjalon------------------
176bdae907SThomas Monjalon
186bdae907SThomas MonjalonThe rules and guidelines given in this document cannot cover every situation, so the following general guidelines should be used as a fallback:
196bdae907SThomas Monjalon
206bdae907SThomas Monjalon* The code style should be consistent within each individual file.
216bdae907SThomas Monjalon* In the case of creating new files, the style should be consistent within each file in a given directory or module.
226bdae907SThomas Monjalon* The primary reason for coding standards is to increase code readability and comprehensibility, therefore always use whatever option will make the code easiest to read.
236bdae907SThomas Monjalon
246bdae907SThomas MonjalonLine length is recommended to be not more than 80 characters, including comments.
256bdae907SThomas Monjalon[Tab stop size should be assumed to be 8-characters wide].
266bdae907SThomas Monjalon
276bdae907SThomas Monjalon.. note::
286bdae907SThomas Monjalon
296bdae907SThomas Monjalon	The above is recommendation, and not a hard limit.
308f86ffa6SBruce Richardson	Generally, line lengths up to 100 characters are acceptable in the code.
316bdae907SThomas Monjalon
326bdae907SThomas MonjalonC Comment Style
336bdae907SThomas Monjalon---------------
346bdae907SThomas Monjalon
356bdae907SThomas MonjalonUsual Comments
366bdae907SThomas Monjalon~~~~~~~~~~~~~~
376bdae907SThomas Monjalon
386bdae907SThomas MonjalonThese comments should be used in normal cases.
396bdae907SThomas MonjalonTo document a public API, a doxygen-like format must be used: refer to :ref:`doxygen_guidelines`.
406bdae907SThomas Monjalon
416bdae907SThomas Monjalon.. code-block:: c
426bdae907SThomas Monjalon
436bdae907SThomas Monjalon /*
446bdae907SThomas Monjalon  * VERY important single-line comments look like this.
456bdae907SThomas Monjalon  */
466bdae907SThomas Monjalon
476bdae907SThomas Monjalon /* Most single-line comments look like this. */
486bdae907SThomas Monjalon
496bdae907SThomas Monjalon /*
506bdae907SThomas Monjalon  * Multi-line comments look like this.  Make them real sentences. Fill
516bdae907SThomas Monjalon  * them so they look like real paragraphs.
526bdae907SThomas Monjalon  */
536bdae907SThomas Monjalon
546bdae907SThomas MonjalonLicense Header
556bdae907SThomas Monjalon~~~~~~~~~~~~~~
566bdae907SThomas Monjalon
57525d8031SStephen HemmingerEach file must begin with a special comment containing the
589c30a6f3SHenry Nadeau`Software Package Data Exchange (SPDX) License Identifier <https://spdx.org/using-spdx-license-identifier>`_.
59525d8031SStephen Hemminger
60525d8031SStephen HemmingerGenerally this is the BSD License, except for code granted special exceptions.
61525d8031SStephen HemmingerThe SPDX licences identifier is sufficient, a file should not contain
62525d8031SStephen Hemmingeran additional text version of the license (boilerplate).
63525d8031SStephen Hemminger
646bdae907SThomas MonjalonAfter any copyright header, a blank line should be left before any other contents, e.g. include statements in a C file.
656bdae907SThomas Monjalon
666bdae907SThomas MonjalonC Preprocessor Directives
676bdae907SThomas Monjalon-------------------------
686bdae907SThomas Monjalon
696bdae907SThomas MonjalonHeader Includes
706bdae907SThomas Monjalon~~~~~~~~~~~~~~~
716bdae907SThomas Monjalon
726bdae907SThomas MonjalonIn DPDK sources, the include files should be ordered as following:
736bdae907SThomas Monjalon
746bdae907SThomas Monjalon#. libc includes (system includes first)
756bdae907SThomas Monjalon#. DPDK EAL includes
766bdae907SThomas Monjalon#. DPDK misc libraries includes
776bdae907SThomas Monjalon#. application-specific includes
786bdae907SThomas Monjalon
796bdae907SThomas MonjalonInclude files from the local application directory are included using quotes, while includes from other paths are included using angle brackets: "<>".
806bdae907SThomas Monjalon
816bdae907SThomas MonjalonExample:
826bdae907SThomas Monjalon
836bdae907SThomas Monjalon.. code-block:: c
846bdae907SThomas Monjalon
856bdae907SThomas Monjalon #include <stdio.h>
866bdae907SThomas Monjalon #include <stdlib.h>
876bdae907SThomas Monjalon
886bdae907SThomas Monjalon #include <rte_eal.h>
896bdae907SThomas Monjalon
906bdae907SThomas Monjalon #include <rte_ring.h>
916bdae907SThomas Monjalon #include <rte_mempool.h>
926bdae907SThomas Monjalon
936bdae907SThomas Monjalon #include "application.h"
946bdae907SThomas Monjalon
956bdae907SThomas MonjalonHeader File Guards
966bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~
976bdae907SThomas Monjalon
986bdae907SThomas MonjalonHeaders should be protected against multiple inclusion with the usual:
996bdae907SThomas Monjalon
1006bdae907SThomas Monjalon.. code-block:: c
1016bdae907SThomas Monjalon
1026bdae907SThomas Monjalon   #ifndef _FILE_H_
1036bdae907SThomas Monjalon   #define _FILE_H_
1046bdae907SThomas Monjalon
1056bdae907SThomas Monjalon   /* Code */
1066bdae907SThomas Monjalon
1076bdae907SThomas Monjalon   #endif /* _FILE_H_ */
1086bdae907SThomas Monjalon
1096bdae907SThomas Monjalon
1106bdae907SThomas MonjalonMacros
1116bdae907SThomas Monjalon~~~~~~
1126bdae907SThomas Monjalon
1136bdae907SThomas MonjalonDo not ``#define`` or declare names except with the standard DPDK prefix: ``RTE_``.
1146bdae907SThomas MonjalonThis is to ensure there are no collisions with definitions in the application itself.
1156bdae907SThomas Monjalon
1166bdae907SThomas MonjalonThe names of "unsafe" macros (ones that have side effects), and the names of macros for manifest constants, are all in uppercase.
1176bdae907SThomas Monjalon
1186bdae907SThomas MonjalonThe expansions of expression-like macros are either a single token or have outer parentheses.
1196bdae907SThomas MonjalonIf a macro is an inline expansion of a function, the function name is all in lowercase and the macro has the same name all in uppercase.
1206bdae907SThomas MonjalonIf the macro encapsulates a compound statement, enclose it in a do-while loop, so that it can be used safely in if statements.
1216bdae907SThomas MonjalonAny final statement-terminating semicolon should be supplied by the macro invocation rather than the macro, to make parsing easier for pretty-printers and editors.
1226bdae907SThomas Monjalon
1236bdae907SThomas MonjalonFor example:
1246bdae907SThomas Monjalon
1256bdae907SThomas Monjalon.. code-block:: c
1266bdae907SThomas Monjalon
1276bdae907SThomas Monjalon #define MACRO(x, y) do {                                        \
1286bdae907SThomas Monjalon         variable = (x) + (y);                                   \
1296bdae907SThomas Monjalon         (y) += 2;                                               \
1306bdae907SThomas Monjalon } while(0)
1316bdae907SThomas Monjalon
1326bdae907SThomas Monjalon.. note::
1336bdae907SThomas Monjalon
1346bdae907SThomas Monjalon Wherever possible, enums and inline functions should be preferred to macros, since they provide additional degrees of type-safety and can allow compilers to emit extra warnings about unsafe code.
1356bdae907SThomas Monjalon
1366bdae907SThomas MonjalonConditional Compilation
1376bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~~
1386bdae907SThomas Monjalon
139cadb255eSBruce Richardson.. note::
140cadb255eSBruce Richardson
141cadb255eSBruce Richardson   Conditional compilation should be used only when absolutely necessary,
142cadb255eSBruce Richardson   as it increases the number of target binaries that need to be built and tested.
143cadb255eSBruce Richardson   See below for details of some utility macros/defines available
144cadb255eSBruce Richardson   to allow ifdefs/macros to be replaced by C conditional in some cases.
145cadb255eSBruce Richardson
146cadb255eSBruce RichardsonSome high-level guidelines on the use of conditional compilation:
147cadb255eSBruce Richardson
148cadb255eSBruce Richardson* If code can compile on all platforms/systems,
149cadb255eSBruce Richardson  but cannot run on some due to lack of support,
150cadb255eSBruce Richardson  then regular C conditionals, as described in the next section,
151cadb255eSBruce Richardson  should be used instead of conditional compilation.
152cadb255eSBruce Richardson* If the code in question cannot compile on all systems,
153cadb255eSBruce Richardson  but constitutes only a small fragment of a file,
154cadb255eSBruce Richardson  then conditional compilation should be used, as described in this section.
155cadb255eSBruce Richardson* If the code for conditional compilation implements an interface in an OS
156cadb255eSBruce Richardson  or platform-specific way, then create a file for each OS or platform
157cadb255eSBruce Richardson  and select the appropriate file using the Meson build system.
158cadb255eSBruce Richardson  In most cases, these environment-specific files should be created inside the EAL library,
159cadb255eSBruce Richardson  rather than having each library implement its own abstraction layer.
160cadb255eSBruce Richardson
161cadb255eSBruce RichardsonAdditional style guidance for the use of conditional compilation macros:
162cadb255eSBruce Richardson
1636bdae907SThomas Monjalon* When code is conditionally compiled using ``#ifdef`` or ``#if``, a comment may be added following the matching
1646bdae907SThomas Monjalon  ``#endif`` or ``#else`` to permit the reader to easily discern where conditionally compiled code regions end.
1656bdae907SThomas Monjalon* This comment should be used only for (subjectively) long regions, regions greater than 20 lines, or where a series of nested ``#ifdef``'s may be confusing to the reader.
1666bdae907SThomas Monjalon  Exceptions may be made for cases where code is conditionally not compiled for the purposes of lint(1), or other tools, even though the uncompiled region may be small.
1676bdae907SThomas Monjalon* The comment should be separated from the ``#endif`` or ``#else`` by a single space.
1686bdae907SThomas Monjalon* For short conditionally compiled regions, a closing comment should not be used.
1696bdae907SThomas Monjalon* The comment for ``#endif`` should match the expression used in the corresponding ``#if`` or ``#ifdef``.
1706bdae907SThomas Monjalon* The comment for ``#else`` and ``#elif`` should match the inverse of the expression(s) used in the preceding ``#if`` and/or ``#elif`` statements.
1716bdae907SThomas Monjalon* In the comments, the subexpression ``defined(FOO)`` is abbreviated as "FOO".
1726bdae907SThomas Monjalon  For the purposes of comments, ``#ifndef FOO`` is treated as ``#if !defined(FOO)``.
1736bdae907SThomas Monjalon
1746bdae907SThomas Monjalon.. code-block:: c
1756bdae907SThomas Monjalon
1766bdae907SThomas Monjalon #ifdef KTRACE
1776bdae907SThomas Monjalon #include <sys/ktrace.h>
1786bdae907SThomas Monjalon #endif
1796bdae907SThomas Monjalon
1806bdae907SThomas Monjalon #ifdef COMPAT_43
1816bdae907SThomas Monjalon /* A large region here, or other conditional code. */
1826bdae907SThomas Monjalon #else /* !COMPAT_43 */
1836bdae907SThomas Monjalon /* Or here. */
1846bdae907SThomas Monjalon #endif /* COMPAT_43 */
1856bdae907SThomas Monjalon
1866bdae907SThomas Monjalon #ifndef COMPAT_43
1876bdae907SThomas Monjalon /* Yet another large region here, or other conditional code. */
1886bdae907SThomas Monjalon #else /* COMPAT_43 */
1896bdae907SThomas Monjalon /* Or here. */
1906bdae907SThomas Monjalon #endif /* !COMPAT_43 */
1916bdae907SThomas Monjalon
192cadb255eSBruce RichardsonDefines to Avoid Conditional Compilation
193cadb255eSBruce Richardson~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1946bdae907SThomas Monjalon
195cadb255eSBruce RichardsonIn many cases in DPDK, one wants to run code based on
196cadb255eSBruce Richardsonthe target platform, or runtime environment.
197cadb255eSBruce RichardsonWhile this can be done using the conditional compilation directives,
198cadb255eSBruce Richardsone.g. ``#ifdef RTE_EXEC_ENV_LINUX``, present in DPDK for many releases,
199cadb255eSBruce Richardsonthis can also be done in many cases using regular ``if`` statements
200cadb255eSBruce Richardsonand the following defines:
201cadb255eSBruce Richardson
202cadb255eSBruce Richardson* ``RTE_ENV_FREEBSD``, ``RTE_ENV_LINUX``, ``RTE_ENV_WINDOWS`` -
203cadb255eSBruce Richardson  these define ids for each operating system environment.
204cadb255eSBruce Richardson* ``RTE_EXEC_ENV`` - this defines the id of the current environment,
205cadb255eSBruce Richardson  i.e. one of the items in list above.
206cadb255eSBruce Richardson* ``RTE_EXEC_ENV_IS_FREEBSD``, ``RTE_EXEC_ENV_IS_LINUX``, ``RTE_EXEC_ENV_IS_WINDOWS`` -
207cadb255eSBruce Richardson  0/1 values indicating if the current environment is that specified,
208cadb255eSBruce Richardson  shortcuts for checking e.g. ``RTE_EXEC_ENV == RTE_ENV_WINDOWS``
209cadb255eSBruce Richardson
210cadb255eSBruce RichardsonExamples of use:
211cadb255eSBruce Richardson
212cadb255eSBruce Richardson.. code-block:: c
213cadb255eSBruce Richardson
214cadb255eSBruce Richardson   /* report a unit tests as unsupported on Windows */
215cadb255eSBruce Richardson   if (RTE_EXEC_ENV_IS_WINDOWS)
216cadb255eSBruce Richardson       return TEST_SKIPPED;
217cadb255eSBruce Richardson
218cadb255eSBruce Richardson   /* set different default values depending on OS Environment */
219cadb255eSBruce Richardson   switch (RTE_EXEC_ENV) {
220cadb255eSBruce Richardson   case RTE_ENV_FREEBSD:
221cadb255eSBruce Richardson       default = x;
222cadb255eSBruce Richardson       break;
223cadb255eSBruce Richardson   case RTE_ENV_LINUX:
224cadb255eSBruce Richardson       default = y;
225cadb255eSBruce Richardson       break;
226cadb255eSBruce Richardson   case RTE_ENV_WINDOWS:
227cadb255eSBruce Richardson       default = z;
228cadb255eSBruce Richardson       break;
229cadb255eSBruce Richardson   }
230cadb255eSBruce Richardson
2316bdae907SThomas Monjalon
2326bdae907SThomas MonjalonC Types
2336bdae907SThomas Monjalon-------
2346bdae907SThomas Monjalon
2356bdae907SThomas MonjalonIntegers
2366bdae907SThomas Monjalon~~~~~~~~
2376bdae907SThomas Monjalon
2386bdae907SThomas MonjalonFor fixed/minimum-size integer values, the project uses the form uintXX_t (from stdint.h) instead of older BSD-style integer identifiers of the form u_intXX_t.
2396bdae907SThomas Monjalon
2406bdae907SThomas MonjalonEnumerations
2416bdae907SThomas Monjalon~~~~~~~~~~~~
2426bdae907SThomas Monjalon
2436bdae907SThomas Monjalon* Enumeration values are all uppercase.
2446bdae907SThomas Monjalon
2456bdae907SThomas Monjalon.. code-block:: c
2466bdae907SThomas Monjalon
2476bdae907SThomas Monjalon enum enumtype { ONE, TWO } et;
2486bdae907SThomas Monjalon
2496bdae907SThomas Monjalon* Enum types should be used in preference to macros #defining a set of (sequential) values.
2506bdae907SThomas Monjalon* Enum types should be prefixed with ``rte_`` and the elements by a suitable prefix [generally starting ``RTE_<enum>_`` - where <enum> is a shortname for the enum type] to avoid namespace collisions.
2516bdae907SThomas Monjalon
2526bdae907SThomas MonjalonBitfields
2536bdae907SThomas Monjalon~~~~~~~~~
2546bdae907SThomas Monjalon
2556bdae907SThomas MonjalonThe developer should group bitfields that are included in the same integer, as follows:
2566bdae907SThomas Monjalon
2576bdae907SThomas Monjalon.. code-block:: c
2586bdae907SThomas Monjalon
2596bdae907SThomas Monjalon struct grehdr {
2606bdae907SThomas Monjalon   uint16_t rec:3,
2616bdae907SThomas Monjalon       srr:1,
2626bdae907SThomas Monjalon       seq:1,
2636bdae907SThomas Monjalon       key:1,
2646bdae907SThomas Monjalon       routing:1,
2656bdae907SThomas Monjalon       csum:1,
2666bdae907SThomas Monjalon       version:3,
2676bdae907SThomas Monjalon       reserved:4,
2686bdae907SThomas Monjalon       ack:1;
2696bdae907SThomas Monjalon /* ... */
2706bdae907SThomas Monjalon }
2716bdae907SThomas Monjalon
2726bdae907SThomas MonjalonVariable Declarations
2736bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~
2746bdae907SThomas Monjalon
2756bdae907SThomas MonjalonIn declarations, do not put any whitespace between asterisks and adjacent tokens, except for tokens that are identifiers related to types.
2766bdae907SThomas Monjalon(These identifiers are the names of basic types, type qualifiers, and typedef-names other than the one being declared.)
2776bdae907SThomas MonjalonSeparate these identifiers from asterisks using a single space.
2786bdae907SThomas Monjalon
2796bdae907SThomas MonjalonFor example:
2806bdae907SThomas Monjalon
2816bdae907SThomas Monjalon.. code-block:: c
2826bdae907SThomas Monjalon
2836bdae907SThomas Monjalon   int *x;         /* no space after asterisk */
2846bdae907SThomas Monjalon   int * const x;  /* space after asterisk when using a type qualifier */
2856bdae907SThomas Monjalon
2866bdae907SThomas Monjalon* All externally-visible variables should have an ``rte_`` prefix in the name to avoid namespace collisions.
2876bdae907SThomas Monjalon* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in variable names.
2886bdae907SThomas Monjalon  Lower-case letters and underscores only.
2896bdae907SThomas Monjalon
2906bdae907SThomas MonjalonStructure Declarations
2916bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~
2926bdae907SThomas Monjalon
2936bdae907SThomas Monjalon* In general, when declaring variables in new structures, declare them sorted by use, then by size (largest to smallest), and then in alphabetical order.
2946bdae907SThomas Monjalon  Sorting by use means that commonly used variables are used together and that the structure layout makes logical sense.
2956bdae907SThomas Monjalon  Ordering by size then ensures that as little padding is added to the structure as possible.
2966bdae907SThomas Monjalon* For existing structures, additions to structures should be added to the end so for backward compatibility reasons.
2976bdae907SThomas Monjalon* Each structure element gets its own line.
2986bdae907SThomas Monjalon* Try to make the structure readable by aligning the member names using spaces as shown below.
2996bdae907SThomas Monjalon* Names following extremely long types, which therefore cannot be easily aligned with the rest, should be separated by a single space.
3006bdae907SThomas Monjalon
3016bdae907SThomas Monjalon.. code-block:: c
3026bdae907SThomas Monjalon
3036bdae907SThomas Monjalon struct foo {
3046bdae907SThomas Monjalon         struct foo      *next;          /* List of active foo. */
3056bdae907SThomas Monjalon         struct mumble   amumble;        /* Comment for mumble. */
3066bdae907SThomas Monjalon         int             bar;            /* Try to align the comments. */
3076bdae907SThomas Monjalon         struct verylongtypename *baz;   /* Won't fit with other members */
3086bdae907SThomas Monjalon };
3096bdae907SThomas Monjalon
3106bdae907SThomas Monjalon
3116bdae907SThomas Monjalon* Major structures should be declared at the top of the file in which they are used, or in separate header files if they are used in multiple source files.
3126bdae907SThomas Monjalon* Use of the structures should be by separate variable declarations and those declarations must be extern if they are declared in a header file.
3136bdae907SThomas Monjalon* Externally visible structure definitions should have the structure name prefixed by ``rte_`` to avoid namespace collisions.
3146bdae907SThomas Monjalon
315904ffb2eSMarko Kovacevic.. note::
316904ffb2eSMarko Kovacevic
317904ffb2eSMarko Kovacevic    Uses of ``bool`` in structures are not preferred as is wastes space and
318904ffb2eSMarko Kovacevic    it's also not clear as to what type size the bool is. A preferred use of
319904ffb2eSMarko Kovacevic    ``bool`` is mainly as a return type from functions that return true/false,
320904ffb2eSMarko Kovacevic    and maybe local variable functions.
321904ffb2eSMarko Kovacevic
322904ffb2eSMarko Kovacevic    Ref: `LKML <https://lkml.org/lkml/2017/11/21/384>`_
323904ffb2eSMarko Kovacevic
3246bdae907SThomas MonjalonQueues
3256bdae907SThomas Monjalon~~~~~~
3266bdae907SThomas Monjalon
3276bdae907SThomas MonjalonUse queue(3) macros rather than rolling your own lists, whenever possible.
3286bdae907SThomas MonjalonThus, the previous example would be better written:
3296bdae907SThomas Monjalon
3306bdae907SThomas Monjalon.. code-block:: c
3316bdae907SThomas Monjalon
3326bdae907SThomas Monjalon #include <sys/queue.h>
3336bdae907SThomas Monjalon
3346bdae907SThomas Monjalon struct foo {
3356bdae907SThomas Monjalon         LIST_ENTRY(foo) link;      /* Use queue macros for foo lists. */
3366bdae907SThomas Monjalon         struct mumble   amumble;   /* Comment for mumble. */
3376bdae907SThomas Monjalon         int             bar;       /* Try to align the comments. */
3386bdae907SThomas Monjalon         struct verylongtypename *baz;   /* Won't fit with other members */
3396bdae907SThomas Monjalon };
3406bdae907SThomas Monjalon LIST_HEAD(, foo) foohead;          /* Head of global foo list. */
3416bdae907SThomas Monjalon
3426bdae907SThomas Monjalon
3436bdae907SThomas MonjalonDPDK also provides an optimized way to store elements in lockless rings.
3446bdae907SThomas MonjalonThis should be used in all data-path code, when there are several consumer and/or producers to avoid locking for concurrent access.
3456bdae907SThomas Monjalon
34657c789fdSStephen HemmingerNaming
34757c789fdSStephen Hemminger------
34857c789fdSStephen Hemminger
34957c789fdSStephen HemmingerFor symbol names and documentation, new usage of
35057c789fdSStephen Hemminger'master / slave' (or 'slave' independent of 'master') and 'blacklist /
35157c789fdSStephen Hemmingerwhitelist' is not allowed.
35257c789fdSStephen Hemminger
35357c789fdSStephen HemmingerRecommended replacements for 'master / slave' are:
35457c789fdSStephen Hemminger    '{primary,main} / {secondary,replica,subordinate}'
35557c789fdSStephen Hemminger    '{initiator,requester} / {target,responder}'
35657c789fdSStephen Hemminger    '{controller,host} / {device,worker,proxy}'
35757c789fdSStephen Hemminger    'leader / follower'
35857c789fdSStephen Hemminger    'director / performer'
35957c789fdSStephen Hemminger
36057c789fdSStephen HemmingerRecommended replacements for 'blacklist/whitelist' are:
36157c789fdSStephen Hemminger    'denylist / allowlist'
36257c789fdSStephen Hemminger    'blocklist / passlist'
36357c789fdSStephen Hemminger
36457c789fdSStephen HemmingerExceptions for introducing new usage is to maintain compatibility
36557c789fdSStephen Hemmingerwith an existing (as of 2020) hardware or protocol
36657c789fdSStephen Hemmingerspecification that mandates those terms.
36757c789fdSStephen Hemminger
36857c789fdSStephen Hemminger
3696bdae907SThomas MonjalonTypedefs
3706bdae907SThomas Monjalon~~~~~~~~
3716bdae907SThomas Monjalon
3726bdae907SThomas MonjalonAvoid using typedefs for structure types.
3736bdae907SThomas Monjalon
3746bdae907SThomas MonjalonFor example, use:
3756bdae907SThomas Monjalon
3766bdae907SThomas Monjalon.. code-block:: c
3776bdae907SThomas Monjalon
3786bdae907SThomas Monjalon struct my_struct_type {
3796bdae907SThomas Monjalon /* ... */
3806bdae907SThomas Monjalon };
3816bdae907SThomas Monjalon
3826bdae907SThomas Monjalon struct my_struct_type my_var;
3836bdae907SThomas Monjalon
3846bdae907SThomas Monjalon
3856bdae907SThomas Monjalonrather than:
3866bdae907SThomas Monjalon
3876bdae907SThomas Monjalon.. code-block:: c
3886bdae907SThomas Monjalon
3896bdae907SThomas Monjalon typedef struct my_struct_type {
3906bdae907SThomas Monjalon /* ... */
3916bdae907SThomas Monjalon } my_struct_type;
3926bdae907SThomas Monjalon
3936bdae907SThomas Monjalon my_struct_type my_var
3946bdae907SThomas Monjalon
3956bdae907SThomas Monjalon
3966bdae907SThomas MonjalonTypedefs are problematic because they do not properly hide their underlying type;
3976bdae907SThomas Monjalonfor example, you need to know if the typedef is the structure itself, as shown above, or a pointer to the structure.
3986bdae907SThomas MonjalonIn addition, they must be declared exactly once, whereas an incomplete structure type can be mentioned as many times as necessary.
3996bdae907SThomas MonjalonTypedefs are difficult to use in stand-alone header files.
4006bdae907SThomas MonjalonThe header that defines the typedef must be included before the header that uses it, or by the header that uses it (which causes namespace pollution),
4016bdae907SThomas Monjalonor there must be a back-door mechanism for obtaining the typedef.
4026bdae907SThomas Monjalon
4036bdae907SThomas MonjalonNote that #defines used instead of typedefs also are problematic (since they do not propagate the pointer type correctly due to direct text replacement).
4046bdae907SThomas MonjalonFor example, ``#define pint int *`` does not work as expected, while ``typedef int *pint`` does work.
4056bdae907SThomas MonjalonAs stated when discussing macros, typedefs should be preferred to macros in cases like this.
4066bdae907SThomas Monjalon
4076bdae907SThomas MonjalonWhen convention requires a typedef; make its name match the struct tag.
4086bdae907SThomas MonjalonAvoid typedefs ending in ``_t``, except as specified in Standard C or by POSIX.
4096bdae907SThomas Monjalon
4106bdae907SThomas Monjalon.. note::
4116bdae907SThomas Monjalon
4126bdae907SThomas Monjalon	It is recommended to use typedefs to define function pointer types, for reasons of code readability.
4136bdae907SThomas Monjalon	This is especially true when the function type is used as a parameter to another function.
4146bdae907SThomas Monjalon
4156bdae907SThomas MonjalonFor example:
4166bdae907SThomas Monjalon
4176bdae907SThomas Monjalon.. code-block:: c
4186bdae907SThomas Monjalon
4196bdae907SThomas Monjalon	/**
4206bdae907SThomas Monjalon	 * Definition of a remote launch function.
4216bdae907SThomas Monjalon	 */
4226bdae907SThomas Monjalon	typedef int (lcore_function_t)(void *);
4236bdae907SThomas Monjalon
4246bdae907SThomas Monjalon	/* launch a function of lcore_function_t type */
425cb056611SStephen Hemminger	int rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned worker_id);
4266bdae907SThomas Monjalon
4276bdae907SThomas Monjalon
4286bdae907SThomas MonjalonC Indentation
4296bdae907SThomas Monjalon-------------
4306bdae907SThomas Monjalon
4316bdae907SThomas MonjalonGeneral
4326bdae907SThomas Monjalon~~~~~~~
4336bdae907SThomas Monjalon
4346bdae907SThomas Monjalon* Indentation is a hard tab, that is, a tab character, not a sequence of spaces,
4356bdae907SThomas Monjalon
4366bdae907SThomas Monjalon.. note::
4376bdae907SThomas Monjalon
4386bdae907SThomas Monjalon	Global whitespace rule in DPDK, use tabs for indentation, spaces for alignment.
4396bdae907SThomas Monjalon
4406bdae907SThomas Monjalon* Do not put any spaces before a tab for indentation.
4416bdae907SThomas Monjalon* If you have to wrap a long statement, put the operator at the end of the line, and indent again.
4426bdae907SThomas Monjalon* For control statements (if, while, etc.), continuation it is recommended that the next line be indented by two tabs, rather than one,
4436bdae907SThomas Monjalon  to prevent confusion as to whether the second line of the control statement forms part of the statement body or not.
4446bdae907SThomas Monjalon  Alternatively, the line continuation may use additional spaces to line up to an appropriately point on the preceding line, for example, to align to an opening brace.
4456bdae907SThomas Monjalon
4466bdae907SThomas Monjalon.. note::
4476bdae907SThomas Monjalon
4486bdae907SThomas Monjalon	As with all style guidelines, code should match style already in use in an existing file.
4496bdae907SThomas Monjalon
4506bdae907SThomas Monjalon.. code-block:: c
4516bdae907SThomas Monjalon
4526bdae907SThomas Monjalon while (really_long_variable_name_1 == really_long_variable_name_2 &&
4536bdae907SThomas Monjalon     var3 == var4){  /* confusing to read as */
4546bdae907SThomas Monjalon     x = y + z;      /* control stmt body lines up with second line of */
4556bdae907SThomas Monjalon     a = b + c;      /* control statement itself if single indent used */
4566bdae907SThomas Monjalon }
4576bdae907SThomas Monjalon
4586bdae907SThomas Monjalon if (really_long_variable_name_1 == really_long_variable_name_2 &&
4596bdae907SThomas Monjalon         var3 == var4){  /* two tabs used */
4606bdae907SThomas Monjalon     x = y + z;          /* statement body no longer lines up */
4616bdae907SThomas Monjalon     a = b + c;
4626bdae907SThomas Monjalon }
4636bdae907SThomas Monjalon
4646bdae907SThomas Monjalon z = a + really + long + statement + that + needs +
4656bdae907SThomas Monjalon         two + lines + gets + indented + on + the +
4666bdae907SThomas Monjalon         second + and + subsequent + lines;
4676bdae907SThomas Monjalon
4686bdae907SThomas Monjalon
4696bdae907SThomas Monjalon* Do not add whitespace at the end of a line.
4706bdae907SThomas Monjalon
4716bdae907SThomas Monjalon* Do not add whitespace or a blank line at the end of a file.
4726bdae907SThomas Monjalon
4736bdae907SThomas Monjalon
4746bdae907SThomas MonjalonControl Statements and Loops
4756bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4766bdae907SThomas Monjalon
4776bdae907SThomas Monjalon* Include a space after keywords (if, while, for, return, switch).
4786bdae907SThomas Monjalon* Do not use braces (``{`` and ``}``) for control statements with zero or just a single statement, unless that statement is more than a single line in which case the braces are permitted.
4796bdae907SThomas Monjalon
4806bdae907SThomas Monjalon.. code-block:: c
4816bdae907SThomas Monjalon
4826bdae907SThomas Monjalon for (p = buf; *p != '\0'; ++p)
4836bdae907SThomas Monjalon         ;       /* nothing */
4846bdae907SThomas Monjalon for (;;)
4856bdae907SThomas Monjalon         stmt;
4866bdae907SThomas Monjalon for (;;) {
4876bdae907SThomas Monjalon         z = a + really + long + statement + that + needs +
4886bdae907SThomas Monjalon                 two + lines + gets + indented + on + the +
4896bdae907SThomas Monjalon                 second + and + subsequent + lines;
4906bdae907SThomas Monjalon }
4916bdae907SThomas Monjalon for (;;) {
4926bdae907SThomas Monjalon         if (cond)
4936bdae907SThomas Monjalon                 stmt;
4946bdae907SThomas Monjalon }
4956bdae907SThomas Monjalon if (val != NULL)
4966bdae907SThomas Monjalon         val = realloc(val, newsize);
4976bdae907SThomas Monjalon
4986bdae907SThomas Monjalon
4996bdae907SThomas Monjalon* Parts of a for loop may be left empty.
5006bdae907SThomas Monjalon
5016bdae907SThomas Monjalon.. code-block:: c
5026bdae907SThomas Monjalon
5036bdae907SThomas Monjalon for (; cnt < 15; cnt++) {
5046bdae907SThomas Monjalon         stmt1;
5056bdae907SThomas Monjalon         stmt2;
5066bdae907SThomas Monjalon }
5076bdae907SThomas Monjalon
5086bdae907SThomas Monjalon* Closing and opening braces go on the same line as the else keyword.
5096bdae907SThomas Monjalon* Braces that are not necessary should be left out.
5106bdae907SThomas Monjalon
5116bdae907SThomas Monjalon.. code-block:: c
5126bdae907SThomas Monjalon
5136bdae907SThomas Monjalon if (test)
5146bdae907SThomas Monjalon         stmt;
5156bdae907SThomas Monjalon else if (bar) {
5166bdae907SThomas Monjalon         stmt;
5176bdae907SThomas Monjalon         stmt;
5186bdae907SThomas Monjalon } else
5196bdae907SThomas Monjalon         stmt;
5206bdae907SThomas Monjalon
5216bdae907SThomas Monjalon
5226bdae907SThomas MonjalonFunction Calls
5236bdae907SThomas Monjalon~~~~~~~~~~~~~~
5246bdae907SThomas Monjalon
5256bdae907SThomas Monjalon* Do not use spaces after function names.
5266bdae907SThomas Monjalon* Commas should have a space after them.
5276bdae907SThomas Monjalon* No spaces after ``(`` or ``[`` or preceding the ``]`` or ``)`` characters.
5286bdae907SThomas Monjalon
5296bdae907SThomas Monjalon.. code-block:: c
5306bdae907SThomas Monjalon
5316bdae907SThomas Monjalon	error = function(a1, a2);
5326bdae907SThomas Monjalon	if (error != 0)
5336bdae907SThomas Monjalon		exit(error);
5346bdae907SThomas Monjalon
5356bdae907SThomas Monjalon
5366bdae907SThomas MonjalonOperators
5376bdae907SThomas Monjalon~~~~~~~~~
5386bdae907SThomas Monjalon
5396bdae907SThomas Monjalon* Unary operators do not require spaces, binary operators do.
5406bdae907SThomas Monjalon* Do not use parentheses unless they are required for precedence or unless the statement is confusing without them.
5416bdae907SThomas Monjalon  However, remember that other people may be more easily confused than you.
5426bdae907SThomas Monjalon
5436bdae907SThomas MonjalonExit
5446bdae907SThomas Monjalon~~~~
5456bdae907SThomas Monjalon
5466bdae907SThomas MonjalonExits should be 0 on success, or 1 on failure.
5476bdae907SThomas Monjalon
5486bdae907SThomas Monjalon.. code-block:: c
5496bdae907SThomas Monjalon
5506bdae907SThomas Monjalon         exit(0);        /*
5516bdae907SThomas Monjalon                          * Avoid obvious comments such as
5526bdae907SThomas Monjalon                          * "Exit 0 on success."
5536bdae907SThomas Monjalon                          */
5546bdae907SThomas Monjalon }
5556bdae907SThomas Monjalon
5566bdae907SThomas MonjalonLocal Variables
5576bdae907SThomas Monjalon~~~~~~~~~~~~~~~
5586bdae907SThomas Monjalon
5596bdae907SThomas Monjalon* Variables should be declared at the start of a block of code rather than in the middle.
5606bdae907SThomas Monjalon  The exception to this is when the variable is ``const`` in which case the declaration must be at the point of first use/assignment.
5617122fb67SFerruh Yigit  Declaring variable inside a for loop is OK.
5626bdae907SThomas Monjalon* When declaring variables in functions, multiple variables per line are OK.
5636bdae907SThomas Monjalon  However, if multiple declarations would cause the line to exceed a reasonable line length, begin a new set of declarations on the next line rather than using a line continuation.
5646bdae907SThomas Monjalon* Be careful to not obfuscate the code by initializing variables in the declarations, only the last variable on a line should be initialized.
5652fe68f32SJohn McNamara  If multiple variables are to be initialized when defined, put one per line.
5666bdae907SThomas Monjalon* Do not use function calls in initializers, except for ``const`` variables.
5676bdae907SThomas Monjalon
5686bdae907SThomas Monjalon.. code-block:: c
5696bdae907SThomas Monjalon
5706bdae907SThomas Monjalon int i = 0, j = 0, k = 0;  /* bad, too many initializer */
5716bdae907SThomas Monjalon
5726bdae907SThomas Monjalon char a = 0;        /* OK, one variable per line with initializer */
5736bdae907SThomas Monjalon char b = 0;
5746bdae907SThomas Monjalon
5756bdae907SThomas Monjalon float x, y = 0.0;  /* OK, only last variable has initializer */
5766bdae907SThomas Monjalon
5776bdae907SThomas Monjalon
5786bdae907SThomas MonjalonCasts and sizeof
5796bdae907SThomas Monjalon~~~~~~~~~~~~~~~~
5806bdae907SThomas Monjalon
5816bdae907SThomas Monjalon* Casts and sizeof statements are not followed by a space.
5826bdae907SThomas Monjalon* Always write sizeof statements with parenthesis.
5836bdae907SThomas Monjalon  The redundant parenthesis rules do not apply to sizeof(var) instances.
5846bdae907SThomas Monjalon
5856bdae907SThomas MonjalonC Function Definition, Declaration and Use
5866bdae907SThomas Monjalon-------------------------------------------
5876bdae907SThomas Monjalon
5886bdae907SThomas MonjalonPrototypes
5896bdae907SThomas Monjalon~~~~~~~~~~
5906bdae907SThomas Monjalon
5916bdae907SThomas Monjalon* It is recommended (and generally required by the compiler) that all non-static functions are prototyped somewhere.
5926bdae907SThomas Monjalon* Functions local to one source module should be declared static, and should not be prototyped unless absolutely necessary.
5936bdae907SThomas Monjalon* Functions used from other parts of code (external API) must be prototyped in the relevant include file.
5946bdae907SThomas Monjalon* Function prototypes should be listed in a logical order, preferably alphabetical unless there is a compelling reason to use a different ordering.
5956bdae907SThomas Monjalon* Functions that are used locally in more than one module go into a separate header file, for example, "extern.h".
5966bdae907SThomas Monjalon* Do not use the ``__P`` macro.
5976bdae907SThomas Monjalon* Functions that are part of an external API should be documented using Doxygen-like comments above declarations. See :ref:`doxygen_guidelines` for details.
5986bdae907SThomas Monjalon* Functions that are part of the external API must have an ``rte_`` prefix on the function name.
5996bdae907SThomas Monjalon* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in function names. Lower-case letters and underscores only.
6006bdae907SThomas Monjalon* When prototyping functions, associate names with parameter types, for example:
6016bdae907SThomas Monjalon
6026bdae907SThomas Monjalon.. code-block:: c
6036bdae907SThomas Monjalon
6046bdae907SThomas Monjalon void function1(int fd); /* good */
6056bdae907SThomas Monjalon void function2(int);    /* bad */
6066bdae907SThomas Monjalon
6076bdae907SThomas Monjalon* Short function prototypes should be contained on a single line.
6086bdae907SThomas Monjalon  Longer prototypes, e.g. those with many parameters, can be split across multiple lines.
6096bdae907SThomas Monjalon  The second and subsequent lines should be further indented as for line statement continuations as described in the previous section.
6106bdae907SThomas Monjalon
6116bdae907SThomas Monjalon.. code-block:: c
6126bdae907SThomas Monjalon
6136bdae907SThomas Monjalon static char *function1(int _arg, const char *_arg2,
6146bdae907SThomas Monjalon        struct foo *_arg3,
6156bdae907SThomas Monjalon        struct bar *_arg4,
6166bdae907SThomas Monjalon        struct baz *_arg5);
6176bdae907SThomas Monjalon static void usage(void);
6186bdae907SThomas Monjalon
6196bdae907SThomas Monjalon.. note::
6206bdae907SThomas Monjalon
6216bdae907SThomas Monjalon	Unlike function definitions, the function prototypes do not need to place the function return type on a separate line.
6226bdae907SThomas Monjalon
6236bdae907SThomas MonjalonDefinitions
6246bdae907SThomas Monjalon~~~~~~~~~~~
6256bdae907SThomas Monjalon
6266bdae907SThomas Monjalon* The function type should be on a line by itself preceding the function.
6276bdae907SThomas Monjalon* The opening brace of the function body should be on a line by itself.
6286bdae907SThomas Monjalon
6296bdae907SThomas Monjalon.. code-block:: c
6306bdae907SThomas Monjalon
6316bdae907SThomas Monjalon static char *
6326bdae907SThomas Monjalon function(int a1, int a2, float fl, int a4)
6336bdae907SThomas Monjalon {
6346bdae907SThomas Monjalon
6356bdae907SThomas Monjalon
6366bdae907SThomas Monjalon* Do not declare functions inside other functions.
6376bdae907SThomas Monjalon  ANSI C states that such declarations have file scope regardless of the nesting of the declaration.
6386bdae907SThomas Monjalon  Hiding file declarations in what appears to be a local scope is undesirable and will elicit complaints from a good compiler.
6396bdae907SThomas Monjalon* Old-style (K&R) function declaration should not be used, use ANSI function declarations instead as shown below.
6406bdae907SThomas Monjalon* Long argument lists should be wrapped as described above in the function prototypes section.
6416bdae907SThomas Monjalon
6426bdae907SThomas Monjalon.. code-block:: c
6436bdae907SThomas Monjalon
6446bdae907SThomas Monjalon /*
6456bdae907SThomas Monjalon  * All major routines should have a comment briefly describing what
6466bdae907SThomas Monjalon  * they do. The comment before the "main" routine should describe
6476bdae907SThomas Monjalon  * what the program does.
6486bdae907SThomas Monjalon  */
6496bdae907SThomas Monjalon int
6506bdae907SThomas Monjalon main(int argc, char *argv[])
6516bdae907SThomas Monjalon {
6526bdae907SThomas Monjalon         char *ep;
6536bdae907SThomas Monjalon         long num;
6546bdae907SThomas Monjalon         int ch;
6556bdae907SThomas Monjalon
6566bdae907SThomas MonjalonC Statement Style and Conventions
6576bdae907SThomas Monjalon---------------------------------
6586bdae907SThomas Monjalon
6596bdae907SThomas MonjalonNULL Pointers
6606bdae907SThomas Monjalon~~~~~~~~~~~~~
6616bdae907SThomas Monjalon
6626bdae907SThomas Monjalon* NULL is the preferred null pointer constant.
6636bdae907SThomas Monjalon  Use NULL instead of ``(type *)0`` or ``(type *)NULL``, except where the compiler does not know the destination type e.g. for variadic args to a function.
6646bdae907SThomas Monjalon* Test pointers against NULL, for example, use:
6656bdae907SThomas Monjalon
6666bdae907SThomas Monjalon.. code-block:: c
6676bdae907SThomas Monjalon
6686bdae907SThomas Monjalon if (p == NULL) /* Good, compare pointer to NULL */
6696bdae907SThomas Monjalon
6706bdae907SThomas Monjalon if (!p) /* Bad, using ! on pointer */
6716bdae907SThomas Monjalon
6726bdae907SThomas Monjalon
6736bdae907SThomas Monjalon* Do not use ! for tests unless it is a boolean, for example, use:
6746bdae907SThomas Monjalon
6756bdae907SThomas Monjalon.. code-block:: c
6766bdae907SThomas Monjalon
6776bdae907SThomas Monjalon	if (*p == '\0') /* check character against (char)0 */
6786bdae907SThomas Monjalon
6796bdae907SThomas MonjalonReturn Value
6806bdae907SThomas Monjalon~~~~~~~~~~~~
6816bdae907SThomas Monjalon
6826bdae907SThomas Monjalon* Functions which create objects, or allocate memory, should return pointer types, and NULL on error.
6836965091eSDariusz Sosnowski  The error type should be indicated by setting the variable ``rte_errno`` appropriately.
6846bdae907SThomas Monjalon* Functions which work on bursts of packets, such as RX-like or TX-like functions, should return the number of packets handled.
6856bdae907SThomas Monjalon* Other functions returning int should generally behave like system calls:
6866bdae907SThomas Monjalon  returning 0 on success and -1 on error, setting ``rte_errno`` to indicate the specific type of error.
6876bdae907SThomas Monjalon* Where already standard in a given library, the alternative error approach may be used where the negative value is not -1 but is instead ``-errno`` if relevant, for example, ``-EINVAL``.
6886bdae907SThomas Monjalon  Note, however, to allow consistency across functions returning integer or pointer types, the previous approach is preferred for any new libraries.
6896bdae907SThomas Monjalon* For functions where no error is possible, the function type should be ``void`` not ``int``.
6906bdae907SThomas Monjalon* Routines returning ``void *`` should not have their return values cast to any pointer type.
6916bdae907SThomas Monjalon  (Typecasting can prevent the compiler from warning about missing prototypes as any implicit definition of a function returns int,
6926bdae907SThomas Monjalon  which, unlike ``void *``, needs a typecast to assign to a pointer variable.)
6936bdae907SThomas Monjalon
6946bdae907SThomas Monjalon.. note::
6956bdae907SThomas Monjalon
6966bdae907SThomas Monjalon	The above rule about not typecasting ``void *`` applies to malloc, as well as to DPDK functions.
6976bdae907SThomas Monjalon
6986bdae907SThomas Monjalon* Values in return statements should not be enclosed in parentheses.
6996bdae907SThomas Monjalon
7006bdae907SThomas MonjalonLogging and Errors
7016bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~
7026bdae907SThomas Monjalon
7036bdae907SThomas MonjalonIn the DPDK environment, use the logging interface provided:
7046bdae907SThomas Monjalon
7056bdae907SThomas Monjalon.. code-block:: c
7066bdae907SThomas Monjalon
707c1b5fa94SOlivier Matz /* register log types for this application */
708c1b5fa94SOlivier Matz int my_logtype1 = rte_log_register("myapp.log1");
709c1b5fa94SOlivier Matz int my_logtype2 = rte_log_register("myapp.log2");
7106bdae907SThomas Monjalon
711c1b5fa94SOlivier Matz /* set global log level to INFO */
712c1b5fa94SOlivier Matz rte_log_set_global_level(RTE_LOG_INFO);
713c1b5fa94SOlivier Matz
714c1b5fa94SOlivier Matz /* only display messages higher than NOTICE for log2 (default
715c1b5fa94SOlivier Matz  * is DEBUG) */
716c1b5fa94SOlivier Matz rte_log_set_level(my_logtype2, RTE_LOG_NOTICE);
717c1b5fa94SOlivier Matz
7187f0bb634SStephen Hemminger /* enable all PMD logs (whose identifier string starts with "pmd.") */
7197f0bb634SStephen Hemminger rte_log_set_level_pattern("pmd.*", RTE_LOG_DEBUG);
7206bdae907SThomas Monjalon
7216bdae907SThomas Monjalon /* log in debug level */
722c1b5fa94SOlivier Matz rte_log_set_global_level(RTE_LOG_DEBUG);
723f43d3dbbSDavid Marchand RTE_LOG(DEBUG, my_logtype1, "this is a debug level message\n");
724f43d3dbbSDavid Marchand RTE_LOG(INFO, my_logtype1, "this is a info level message\n");
725f43d3dbbSDavid Marchand RTE_LOG(WARNING, my_logtype1, "this is a warning level message\n");
726f43d3dbbSDavid Marchand RTE_LOG(WARNING, my_logtype2, "this is a debug level message (not displayed)\n");
7276bdae907SThomas Monjalon
7286bdae907SThomas Monjalon /* log in info level */
729c1b5fa94SOlivier Matz rte_log_set_global_level(RTE_LOG_INFO);
730c1b5fa94SOlivier Matz RTE_LOG(DEBUG, my_logtype1, "debug level message (not displayed)\n");
7316bdae907SThomas Monjalon
7326bdae907SThomas MonjalonBranch Prediction
7336bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~
7346bdae907SThomas Monjalon
7356bdae907SThomas Monjalon* When a test is done in a critical zone (called often or in a data path) the code can use the ``likely()`` and ``unlikely()`` macros to indicate the expected, or preferred fast path.
7366bdae907SThomas Monjalon  They are expanded as a compiler builtin and allow the developer to indicate if the branch is likely to be taken or not. Example:
7376bdae907SThomas Monjalon
7386bdae907SThomas Monjalon.. code-block:: c
7396bdae907SThomas Monjalon
7406bdae907SThomas Monjalon #include <rte_branch_prediction.h>
7416bdae907SThomas Monjalon if (likely(x > 1))
7426bdae907SThomas Monjalon   do_stuff();
7436bdae907SThomas Monjalon
7446bdae907SThomas Monjalon.. note::
7456bdae907SThomas Monjalon
7466bdae907SThomas Monjalon	The use of ``likely()`` and ``unlikely()`` should only be done in performance critical paths,
7476bdae907SThomas Monjalon	and only when there is a clearly preferred path, or a measured performance increase gained from doing so.
7486bdae907SThomas Monjalon	These macros should be avoided in non-performance-critical code.
7496bdae907SThomas Monjalon
7506bdae907SThomas MonjalonStatic Variables and Functions
7516bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7526bdae907SThomas Monjalon
7536bdae907SThomas Monjalon* All functions and variables that are local to a file must be declared as ``static`` because it can often help the compiler to do some optimizations (such as, inlining the code).
7546bdae907SThomas Monjalon* Functions that should be inlined should to be declared as ``static inline`` and can be defined in a .c or a .h file.
7556bdae907SThomas Monjalon
7566bdae907SThomas Monjalon.. note::
7576bdae907SThomas Monjalon	Static functions defined in a header file must be declared as ``static inline`` in order to prevent compiler warnings about the function being unused.
7586bdae907SThomas Monjalon
7596bdae907SThomas MonjalonConst Attribute
7606bdae907SThomas Monjalon~~~~~~~~~~~~~~~
7616bdae907SThomas Monjalon
7626bdae907SThomas MonjalonThe ``const`` attribute should be used as often as possible when a variable is read-only.
7636bdae907SThomas Monjalon
7646bdae907SThomas MonjalonInline ASM in C code
7656bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~
7666bdae907SThomas Monjalon
7676bdae907SThomas MonjalonThe ``asm`` and ``volatile`` keywords do not have underscores. The AT&T syntax should be used.
7686bdae907SThomas MonjalonInput and output operands should be named to avoid confusion, as shown in the following example:
7696bdae907SThomas Monjalon
7706bdae907SThomas Monjalon.. code-block:: c
7716bdae907SThomas Monjalon
7726bdae907SThomas Monjalon	asm volatile("outb %[val], %[port]"
7736bdae907SThomas Monjalon		: :
7746bdae907SThomas Monjalon		[port] "dN" (port),
7756bdae907SThomas Monjalon		[val] "a" (val));
7766bdae907SThomas Monjalon
7776bdae907SThomas MonjalonControl Statements
7786bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~
7796bdae907SThomas Monjalon
7806bdae907SThomas Monjalon* Forever loops are done with for statements, not while statements.
7816bdae907SThomas Monjalon* Elements in a switch statement that cascade should have a FALLTHROUGH comment. For example:
7826bdae907SThomas Monjalon
7836bdae907SThomas Monjalon.. code-block:: c
7846bdae907SThomas Monjalon
7856bdae907SThomas Monjalon         switch (ch) {         /* Indent the switch. */
7866bdae907SThomas Monjalon         case 'a':             /* Don't indent the case. */
7876bdae907SThomas Monjalon                 aflag = 1;    /* Indent case body one tab. */
7886bdae907SThomas Monjalon                 /* FALLTHROUGH */
7896bdae907SThomas Monjalon         case 'b':
7906bdae907SThomas Monjalon                 bflag = 1;
7916bdae907SThomas Monjalon                 break;
7926bdae907SThomas Monjalon         case '?':
7936bdae907SThomas Monjalon         default:
7946bdae907SThomas Monjalon                 usage();
7956bdae907SThomas Monjalon                 /* NOTREACHED */
7966bdae907SThomas Monjalon         }
797d1a22085SJohn McNamara
7985c9f84a8SBruce Richardson.. _dynamic_logging:
7995c9f84a8SBruce Richardson
8007db274b9SHarry van HaarenDynamic Logging
8017db274b9SHarry van Haaren---------------
8027db274b9SHarry van Haaren
8037db274b9SHarry van HaarenDPDK provides infrastructure to perform logging during runtime. This is very
8047db274b9SHarry van Haarenuseful for enabling debug output without recompilation. To enable or disable
8057db274b9SHarry van Haarenlogging of a particular topic, the ``--log-level`` parameter can be provided
8067db274b9SHarry van Haarento EAL, which will change the log level. DPDK code can register topics,
8077db274b9SHarry van Haarenwhich allows the user to adjust the log verbosity for that specific topic.
8087db274b9SHarry van Haaren
8091f6f9526SBruce RichardsonTo register a library or driver for dynamic logging,
8101f6f9526SBruce Richardsonusing the standardized naming scheme described below,
8111f6f9526SBruce Richardsonuse ``RTE_LOG_REGISTER_DEFAULT`` macro
8121f6f9526SBruce Richardsonto define a log-type variable inside your component's main C file.
8131f6f9526SBruce RichardsonThereafter, it is usual to define a macro or macros inside your component
8141f6f9526SBruce Richardsonto make logging more convenient.
8151f6f9526SBruce Richardson
8161f6f9526SBruce RichardsonFor example, the ``rte_cfgfile`` library defines:
8171f6f9526SBruce Richardson
8181f6f9526SBruce Richardson.. literalinclude:: ../../../lib/cfgfile/rte_cfgfile.c
8191f6f9526SBruce Richardson   :language: c
8201f6f9526SBruce Richardson   :start-after: Setting up dynamic logging 8<
8211f6f9526SBruce Richardson   :end-before: >8 End of setting up dynamic logging
8221f6f9526SBruce Richardson
8231f6f9526SBruce Richardson.. note::
8241f6f9526SBruce Richardson
8251f6f9526SBruce Richardson   The statically-defined log types defined in ``rte_log.h`` are for legacy components,
8261f6f9526SBruce Richardson   and they will likely be removed in a future release.
8271f6f9526SBruce Richardson   Do not add new entries to this file.
8281f6f9526SBruce Richardson
8291f6f9526SBruce RichardsonDynamic Logging Naming Scheme
8301f6f9526SBruce Richardson~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8311f6f9526SBruce Richardson
8327db274b9SHarry van HaarenIn general, the naming scheme is as follows: ``type.section.name``
8337db274b9SHarry van Haaren
8347db274b9SHarry van Haaren * Type is the type of component, where ``lib``, ``pmd``, ``bus`` and ``user``
8357db274b9SHarry van Haaren   are the common options.
8367db274b9SHarry van Haaren * Section refers to a specific area, for example a poll-mode-driver for an
8377db274b9SHarry van Haaren   ethernet device would use ``pmd.net``, while an eventdev PMD uses
8387db274b9SHarry van Haaren   ``pmd.event``.
8397db274b9SHarry van Haaren * The name identifies the individual item that the log applies to.
8407db274b9SHarry van Haaren   The name section must align with
8417db274b9SHarry van Haaren   the directory that the PMD code resides. See examples below for clarity.
8427db274b9SHarry van Haaren
8437db274b9SHarry van HaarenExamples:
8447db274b9SHarry van Haaren
8457db274b9SHarry van Haaren * The virtio network PMD in ``drivers/net/virtio`` uses ``pmd.net.virtio``
8467db274b9SHarry van Haaren * The eventdev software poll mode driver in ``drivers/event/sw`` uses ``pmd.event.sw``
8477db274b9SHarry van Haaren * The octeontx mempool driver in ``drivers/mempool/octeontx`` uses ``pmd.mempool.octeontx``
84899a2dd95SBruce Richardson * The DPDK hash library in ``lib/hash`` uses ``lib.hash``
8497db274b9SHarry van Haaren
8507db274b9SHarry van HaarenSpecializations
8517db274b9SHarry van Haaren~~~~~~~~~~~~~~~
8527db274b9SHarry van Haaren
8537db274b9SHarry van HaarenIn addition to the above logging topic, any PMD or library can further split
8547db274b9SHarry van Haarenlogging output by using "specializations". A specialization could be the
8557db274b9SHarry van Haarendifference between initialization code, and logs of events that occur at runtime.
8567db274b9SHarry van Haaren
8577db274b9SHarry van HaarenAn example could be the initialization log messages getting one
8587db274b9SHarry van Haarenspecialization, while another specialization handles mailbox command logging.
8597db274b9SHarry van HaarenEach PMD, library or component can create as many specializations as required.
8607db274b9SHarry van Haaren
8617db274b9SHarry van HaarenA specialization looks like this:
8627db274b9SHarry van Haaren
8637db274b9SHarry van Haaren * Initialization output: ``type.section.name.init``
8647db274b9SHarry van Haaren * PF/VF mailbox output: ``type.section.name.mbox``
8657db274b9SHarry van Haaren
8661f6f9526SBruce RichardsonThese specializations are created using the ``RTE_LOG_REGISTER_SUFFIX`` macro.
8671f6f9526SBruce Richardson
8687db274b9SHarry van HaarenA real world example is the i40e poll mode driver which exposes two
8699631253fSFerruh Yigitspecializations, one for initialization ``pmd.net.i40e.init`` and the other for
8709631253fSFerruh Yigitthe remaining driver logs ``pmd.net.i40e.driver``.
8717db274b9SHarry van Haaren
8727db274b9SHarry van HaarenNote that specializations have no formatting rules, but please follow
8737db274b9SHarry van Haarena precedent if one exists. In order to see all current log topics and
8747db274b9SHarry van Haarenspecializations, run the ``app/test`` binary, and use the ``dump_log_types``
875d1a22085SJohn McNamara
876d1a22085SJohn McNamaraPython Code
877d1a22085SJohn McNamara-----------
878d1a22085SJohn McNamara
8793f6f8362SLouise KilheeneyAll Python code should be compliant with
880d76a5927SJohn McNamara`PEP8 (Style Guide for Python Code) <https://www.python.org/dev/peps/pep-0008/>`_.
881d1a22085SJohn McNamara
882d1a22085SJohn McNamaraThe ``pep8`` tool can be used for testing compliance with the guidelines.
883*3c4898efSJuraj LinkešNote that line lengths are acceptable up to 100 characters, which is in line with C recommendations.
88444a6dfacSBruce Richardson
88544a6dfacSBruce RichardsonIntegrating with the Build System
88644a6dfacSBruce Richardson---------------------------------
88744a6dfacSBruce Richardson
8883cc6ecfdSCiara PowerDPDK is built using the tools ``meson`` and ``ninja``.
88944a6dfacSBruce Richardson
890bc461743SBruce Richardson.. note::
891bc461743SBruce Richardson
892bc461743SBruce Richardson   In order to catch possible issues as soon as possible,
893bc461743SBruce Richardson   it is recommended that developers build DPDK in "developer mode" to enable additional checks.
894bc461743SBruce Richardson   By default, this mode is enabled if the build is being done from a git checkout,
895bc461743SBruce Richardson   but the mode can be manually enabled/disabled using the
896bc461743SBruce Richardson   ``developer_mode`` meson configuration option.
897bc461743SBruce Richardson
8983cc6ecfdSCiara PowerTherefore all new component additions should include a ``meson.build`` file,
8993cc6ecfdSCiara Powerand should be added to the component lists in the ``meson.build`` files in the
9003cc6ecfdSCiara Powerrelevant top-level directory:
90144a6dfacSBruce Richardsoneither ``lib`` directory or a ``driver`` subdirectory.
90244a6dfacSBruce Richardson
90344a6dfacSBruce RichardsonMeson Build File Contents - Libraries
90444a6dfacSBruce Richardson~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90544a6dfacSBruce Richardson
90644a6dfacSBruce RichardsonThe ``meson.build`` file for a new DPDK library should be of the following basic
90744a6dfacSBruce Richardsonformat.
90844a6dfacSBruce Richardson
90944a6dfacSBruce Richardson.. code-block:: python
91044a6dfacSBruce Richardson
91144a6dfacSBruce Richardson	sources = files('file1.c', ...)
912eeafaf40SRami Rosen	headers = files('file1.h', ...)
91344a6dfacSBruce Richardson
91444a6dfacSBruce Richardson
915eeafaf40SRami RosenThis will build based on a number of conventions and assumptions within the DPDK
91644a6dfacSBruce Richardsonitself, for example, that the library name is the same as the directory name in
91744a6dfacSBruce Richardsonwhich the files are stored.
91844a6dfacSBruce Richardson
91944a6dfacSBruce RichardsonFor a library ``meson.build`` file, there are number of variables which can be
92044a6dfacSBruce Richardsonset, some mandatory, others optional. The mandatory fields are:
92144a6dfacSBruce Richardson
92244a6dfacSBruce Richardsonsources
92344a6dfacSBruce Richardson	**Default Value = []**.
92444a6dfacSBruce Richardson	This variable should list out the files to be compiled up to create the
92544a6dfacSBruce Richardson	library. Files must be specified using the meson ``files()`` function.
92644a6dfacSBruce Richardson
92744a6dfacSBruce Richardson
92844a6dfacSBruce RichardsonThe optional fields are:
92944a6dfacSBruce Richardson
93044a6dfacSBruce Richardsonbuild
93144a6dfacSBruce Richardson	**Default Value = true**
93244a6dfacSBruce Richardson	Used to optionally compile a library, based on its dependencies or
9338baad6f8SBruce Richardson	environment. When set to "false" the ``reason`` value, explained below, should
9348baad6f8SBruce Richardson	also be set to explain to the user why the component is not being built.
9358baad6f8SBruce Richardson	A simple example of use would be:
93644a6dfacSBruce Richardson
93744a6dfacSBruce Richardson.. code-block:: python
93844a6dfacSBruce Richardson
939adf93ca5SBruce Richardson	if not is_linux
94044a6dfacSBruce Richardson	        build = false
9418baad6f8SBruce Richardson	        reason = 'only supported on Linux'
94244a6dfacSBruce Richardson	endif
94344a6dfacSBruce Richardson
94444a6dfacSBruce Richardson
94544a6dfacSBruce Richardsoncflags
946b114af16SBruce Richardson	**Default Value = [<-march/-mcpu flags>]**.
94744a6dfacSBruce Richardson	Used to specify any additional cflags that need to be passed to compile
94844a6dfacSBruce Richardson	the sources in the library.
94944a6dfacSBruce Richardson
95044a6dfacSBruce Richardsondeps
95144a6dfacSBruce Richardson	**Default Value = ['eal']**.
95244a6dfacSBruce Richardson	Used to list the internal library dependencies of the library. It should
95344a6dfacSBruce Richardson	be assigned to using ``+=`` rather than overwriting using ``=``.  The
95444a6dfacSBruce Richardson	dependencies should be specified as strings, each one giving the name of
95544a6dfacSBruce Richardson	a DPDK library, without the ``librte_`` prefix. Dependencies are handled
95644a6dfacSBruce Richardson	recursively, so specifying e.g. ``mempool``, will automatically also
95744a6dfacSBruce Richardson	make the library depend upon the mempool library's dependencies too -
95844a6dfacSBruce Richardson	``ring`` and ``eal``. For libraries that only depend upon EAL, this
95944a6dfacSBruce Richardson	variable may be omitted from the ``meson.build`` file.  For example:
96044a6dfacSBruce Richardson
96144a6dfacSBruce Richardson.. code-block:: python
96244a6dfacSBruce Richardson
96344a6dfacSBruce Richardson	deps += ['ethdev']
96444a6dfacSBruce Richardson
96544a6dfacSBruce Richardson
96644a6dfacSBruce Richardsonext_deps
96744a6dfacSBruce Richardson	**Default Value = []**.
96844a6dfacSBruce Richardson	Used to specify external dependencies of this library. They should be
96944a6dfacSBruce Richardson	returned as dependency objects, as returned from the meson
97044a6dfacSBruce Richardson	``dependency()`` or ``find_library()`` functions. Before returning
97144a6dfacSBruce Richardson	these, they should be checked to ensure the dependencies have been
97244a6dfacSBruce Richardson	found, and, if not, the ``build`` variable should be set to ``false``.
97344a6dfacSBruce Richardson	For example:
97444a6dfacSBruce Richardson
97544a6dfacSBruce Richardson.. code-block:: python
97644a6dfacSBruce Richardson
97744a6dfacSBruce Richardson	my_dep = dependency('libX', required: 'false')
97844a6dfacSBruce Richardson	if my_dep.found()
97944a6dfacSBruce Richardson		ext_deps += my_dep
98044a6dfacSBruce Richardson	else
98144a6dfacSBruce Richardson		build = false
98244a6dfacSBruce Richardson	endif
98344a6dfacSBruce Richardson
98444a6dfacSBruce Richardson
98544a6dfacSBruce Richardsonheaders
98644a6dfacSBruce Richardson	**Default Value = []**.
98744a6dfacSBruce Richardson	Used to return the list of header files for the library that should be
9889599c59bSBruce Richardson	installed to $PREFIX/include when ``meson install`` is run. As with
98944a6dfacSBruce Richardson	source files, these should be specified using the meson ``files()``
99044a6dfacSBruce Richardson	function.
99105050ac4SBruce Richardson	When ``check_includes`` build option is set to ``true``, each header file
99205050ac4SBruce Richardson	has additional checks performed on it, for example to ensure that it is
99305050ac4SBruce Richardson	not missing any include statements for dependent headers.
99405050ac4SBruce Richardson	For header files which are public, but only included indirectly in
99505050ac4SBruce Richardson	applications, these checks can be skipped by using the ``indirect_headers``
99605050ac4SBruce Richardson	variable rather than ``headers``.
99705050ac4SBruce Richardson
99805050ac4SBruce Richardsonindirect_headers
99905050ac4SBruce Richardson	**Default Value = []**.
100005050ac4SBruce Richardson	As with ``headers`` option above, except that the files are not checked
100105050ac4SBruce Richardson	for all needed include files as part of a DPDK build when
100205050ac4SBruce Richardson	``check_includes`` is set to ``true``.
100344a6dfacSBruce Richardson
1004610beca4SBruce Richardsonincludes:
1005610beca4SBruce Richardson	**Default Value = []**.
1006610beca4SBruce Richardson	Used to indicate any additional header file paths which should be
1007610beca4SBruce Richardson	added to the header search path for other libs depending on this
1008610beca4SBruce Richardson	library. EAL uses this so that other libraries building against it
1009610beca4SBruce Richardson	can find the headers in subdirectories of the main EAL directory. The
1010610beca4SBruce Richardson	base directory of each library is always given in the include path,
1011610beca4SBruce Richardson	it does not need to be specified here.
1012610beca4SBruce Richardson
101344a6dfacSBruce Richardsonname
101444a6dfacSBruce Richardson	**Default Value = library name derived from the directory name**.
101544a6dfacSBruce Richardson	If a library's .so or .a file differs from that given in the directory
101644a6dfacSBruce Richardson	name, the name should be specified using this variable. In practice,
101744a6dfacSBruce Richardson	since the convention is that for a library called ``librte_xyz.so``, the
101899a2dd95SBruce Richardson	sources are stored in a directory ``lib/xyz``, this value should
101944a6dfacSBruce Richardson	never be needed for new libraries.
102044a6dfacSBruce Richardson
102144a6dfacSBruce Richardson.. note::
102244a6dfacSBruce Richardson
102344a6dfacSBruce Richardson	The name value also provides the name used to find the function version
102444a6dfacSBruce Richardson	map file, as part of the build process, so if the directory name and
102544a6dfacSBruce Richardson	library names differ, the ``version.map`` file should be named
102644a6dfacSBruce Richardson	consistently with the library, not the directory
102744a6dfacSBruce Richardson
102844a6dfacSBruce Richardsonobjs
102944a6dfacSBruce Richardson	**Default Value = []**.
103044a6dfacSBruce Richardson	This variable can be used to pass to the library build some pre-built
103144a6dfacSBruce Richardson	objects that were compiled up as part of another target given in the
103244a6dfacSBruce Richardson	included library ``meson.build`` file.
103344a6dfacSBruce Richardson
10348baad6f8SBruce Richardsonreason
10358baad6f8SBruce Richardson	**Default Value = '<unknown reason>'**.
10368baad6f8SBruce Richardson	This variable should be used when a library is not to be built i.e. when
10378baad6f8SBruce Richardson	``build`` is set to "false", to specify the reason why a library will not be
10388baad6f8SBruce Richardson	built. For missing dependencies this should be of the form
10398baad6f8SBruce Richardson	``'missing dependency, "libname"'``.
10408baad6f8SBruce Richardson
1041a5d4ea59SBruce Richardsonuse_function_versioning
1042a5d4ea59SBruce Richardson	**Default Value = false**.
1043a5d4ea59SBruce Richardson	Specifies if the library in question has ABI versioned functions. If it
1044a5d4ea59SBruce Richardson	has, this value should be set to ensure that the C files are compiled
1045a5d4ea59SBruce Richardson	twice with suitable parameters for each of shared or static library
1046a5d4ea59SBruce Richardson	builds.
1047a5d4ea59SBruce Richardson
104844a6dfacSBruce RichardsonMeson Build File Contents - Drivers
104944a6dfacSBruce Richardson~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105044a6dfacSBruce Richardson
105144a6dfacSBruce RichardsonFor drivers, the values are largely the same as for libraries. The variables
105244a6dfacSBruce Richardsonsupported are:
105344a6dfacSBruce Richardson
105444a6dfacSBruce Richardsonbuild
105544a6dfacSBruce Richardson	As above.
105644a6dfacSBruce Richardson
105744a6dfacSBruce Richardsoncflags
105844a6dfacSBruce Richardson	As above.
105944a6dfacSBruce Richardson
106044a6dfacSBruce Richardsondeps
106144a6dfacSBruce Richardson	As above.
106244a6dfacSBruce Richardson
106344a6dfacSBruce Richardsonext_deps
106444a6dfacSBruce Richardson	As above.
106544a6dfacSBruce Richardson
106644a6dfacSBruce Richardsonincludes
106744a6dfacSBruce Richardson	**Default Value = <driver directory>** Some drivers include a base
106844a6dfacSBruce Richardson	directory for additional source files and headers, so we have this
106944a6dfacSBruce Richardson	variable to allow the headers from that base directory to be found when
107044a6dfacSBruce Richardson	compiling driver sources. Should be appended to using ``+=`` rather than
107144a6dfacSBruce Richardson	overwritten using ``=``.  The values appended should be meson include
107244a6dfacSBruce Richardson	objects got using the ``include_directories()`` function. For example:
107344a6dfacSBruce Richardson
107444a6dfacSBruce Richardson.. code-block:: python
107544a6dfacSBruce Richardson
107644a6dfacSBruce Richardson	includes += include_directories('base')
107744a6dfacSBruce Richardson
107844a6dfacSBruce Richardsonname
107944a6dfacSBruce Richardson	As above, though note that each driver class can define it's own naming
108044a6dfacSBruce Richardson	scheme for the resulting ``.so`` files.
108144a6dfacSBruce Richardson
108244a6dfacSBruce Richardsonobjs
108344a6dfacSBruce Richardson	As above, generally used for the contents of the ``base`` directory.
108444a6dfacSBruce Richardson
108544a6dfacSBruce Richardsonpkgconfig_extra_libs
108644a6dfacSBruce Richardson	**Default Value = []**
108744a6dfacSBruce Richardson	This variable is used to pass additional library link flags through to
108844a6dfacSBruce Richardson	the DPDK pkgconfig file generated, for example, to track any additional
108944a6dfacSBruce Richardson	libraries that may need to be linked into the build - especially when
109044a6dfacSBruce Richardson	using static libraries. Anything added here will be appended to the end
109144a6dfacSBruce Richardson	of the ``pkgconfig --libs`` output.
109244a6dfacSBruce Richardson
10938baad6f8SBruce Richardsonreason
10948baad6f8SBruce Richardson	As above.
10958baad6f8SBruce Richardson
109644a6dfacSBruce Richardsonsources [mandatory]
109744a6dfacSBruce Richardson	As above
109844a6dfacSBruce Richardson
109930105f66SDavid Marchandheaders
110030105f66SDavid Marchand	As above
110130105f66SDavid Marchand
110244a6dfacSBruce Richardsonversion
110344a6dfacSBruce Richardson	As above
1104f2cdd95fSBruce Richardson
1105f2cdd95fSBruce Richardson
1106f2cdd95fSBruce RichardsonMeson Coding Style
1107f2cdd95fSBruce Richardson------------------
1108f2cdd95fSBruce Richardson
1109f2cdd95fSBruce RichardsonThe following guidelines apply to the build system code in meson.build files in DPDK.
1110f2cdd95fSBruce Richardson
1111f2cdd95fSBruce Richardson* Indentation should be using 4 spaces, no hard tabs.
1112f2cdd95fSBruce Richardson
1113f2cdd95fSBruce Richardson* Line continuations should be doubly-indented to ensure visible difference from normal indentation.
1114f2cdd95fSBruce Richardson  Any line continuations beyond the first may be singly indented to avoid large amounts of indentation.
1115f2cdd95fSBruce Richardson
1116dad3fd5fSBruce Richardson* Where a line is split in the middle of a statement, e.g. a multiline `if` statement,
1117dad3fd5fSBruce Richardson  brackets should be used in preference to escaping the line break.
1118dad3fd5fSBruce Richardson
1119dad3fd5fSBruce RichardsonExample::
1120dad3fd5fSBruce Richardson
1121dad3fd5fSBruce Richardson    if (condition1 and condition2            # line breaks inside () need no escaping
1122dad3fd5fSBruce Richardson            and condition3 and condition4)
1123dad3fd5fSBruce Richardson        x = y
1124dad3fd5fSBruce Richardson    endif
1125dad3fd5fSBruce Richardson
1126f2cdd95fSBruce Richardson* Lists of files or components must be alphabetical unless doing so would cause errors.
1127f2cdd95fSBruce Richardson
1128f2cdd95fSBruce Richardson* Two formats are supported for lists of files or list of components:
1129f2cdd95fSBruce Richardson
1130f2cdd95fSBruce Richardson   * For a small number of list entries, generally 3 or fewer, all elements may be put on a single line.
1131f2cdd95fSBruce Richardson     In this case, the opening and closing braces of the list must be on the same line as the list items.
1132f2cdd95fSBruce Richardson     No trailing comma is put on the final list entry.
1133f2cdd95fSBruce Richardson   * For lists with more than 3 items,
1134f2cdd95fSBruce Richardson     it is recommended that the lists be put in the files with a *single* entry per line.
1135f2cdd95fSBruce Richardson     In this case, the opening brace, or ``files`` function call must be on a line on its own,
1136f2cdd95fSBruce Richardson     and the closing brace must similarly be on a line on its own at the end.
1137f2cdd95fSBruce Richardson     To help with readability of nested sublists, the closing brace should be dedented to appear
1138f2cdd95fSBruce Richardson     at the same level as the opening braced statement.
1139f2cdd95fSBruce Richardson     The final list entry must have a trailing comma,
1140f2cdd95fSBruce Richardson     so that adding a new entry to the list never modifies any other line in the list.
1141f2cdd95fSBruce Richardson
1142f2cdd95fSBruce RichardsonExamples::
1143f2cdd95fSBruce Richardson
1144f2cdd95fSBruce Richardson    sources = files('file1.c', 'file2.c')
1145f2cdd95fSBruce Richardson
1146f2cdd95fSBruce Richardson    subdirs = ['dir1', 'dir2']
1147f2cdd95fSBruce Richardson
1148f2cdd95fSBruce Richardson    headers = files(
1149f2cdd95fSBruce Richardson            'header1.c',
1150f2cdd95fSBruce Richardson            'header2.c',
1151f2cdd95fSBruce Richardson            'header3.c',   # always include trailing comma
1152f2cdd95fSBruce Richardson    )                      # closing brace at indent level of opening brace
1153f2cdd95fSBruce Richardson
1154f2cdd95fSBruce Richardson    components = [
1155f2cdd95fSBruce Richardson            'comp1',
1156f2cdd95fSBruce Richardson            'comp2',
1157f2cdd95fSBruce Richardson            ...
1158f2cdd95fSBruce Richardson            'compN',
1159f2cdd95fSBruce Richardson    ]
1160