This document outlines how to contribute code to the CNDP project.
The CNDP code can be cloned from the repository on GitHub:
git clone https://github.com/CloudNativeDataPlane/cndp.git
Use GitHub Pull requests to change CNDP.
C code should follow the CNDP coding standards.
A .clang-format file is available in the CNDP repo and can be run with ninja:
ninja -C builddir clang-format
Or with git-clang-format if it is installed:
git clang-format --diff
Or a Pre-commit hook is available and can be used to apply the linters to modified files in a commit. You can install pre-commit by running the following command:
pip install pre-commit
After installing pre-commit, you need to install the pre-commit hooks by running the following command:
pre-commit install
To run pre-commit manually
pre-commit run --all-files
Guidelines for public or private APIs is to hide as much of the internal API from the developer. Which means we need to label function prototypes as public using the CNDP_API macro. The macro is defined as
#define CNDP_API __attribute__((visibility("default")))
And used in this way:
CNDP_API int cne_init();
We also use function versioning macros to allow for build time function linking using the following APIs:
#ifdef CNE_BUILD_SHARED_LIBS
#define FUNCTION_VERSION(internal, api, ver) __asm__(".symver " #internal ", " #api "@" #ver)
#define DEFAULT_VERSION(internal, api, ver) __asm__(".symver " #internal ", " #api "@@" #ver)
#else
#define FUNCTION_VERSION(internal, api, ver)
#define DEFAULT_VERSION(internal, api, ver)
#endif
To hide internal APIs we have public and private headers. The public headers are installed in the system, but the private headers are not. The public headers should use typedefs to hide the internal structures by:
typedef void foo_t;
foo_t *foo;
where the structure may be
struct foo {
int bar;
};
Do not hide the '*' type inside the typedef.
This requires the public APIs to only return void pointers and the public functions are passed these void types and must cast the void pointer into the private structure pointer i.e.
int foobar(foo_t *foo) {
struct foo *f = foo; // Cast of foo is not required as *foo is a void *
return 0;
}
Naming header files as xyz_private.h and cne_xyz.h is preferred. The .c files should be named xyz.c or cne_xyz.c.
Do not use braces where a single statement (if, while, for, ...) will do:
if (foo)
do_this();
else
do_that();
Avoid using "Unable to xxxx", use "Failed to xxx" instead for logging failed function calls:
CNE_ERR_GOTO(out, "Unable to init CNE\n"); // Do NOT use 'unable to' phase here
CNE_ERR_GOTO(out, "Failed to init CNE\n"); // Use 'failed to' instead.
The CNDP maintainers are as follows:
- Jeff Shaw
- Keith Wiles