131 строка
5.1 KiB
Markdown
131 строка
5.1 KiB
Markdown
Development Guide
|
|
=================
|
|
|
|
Coding Conventions
|
|
------------------
|
|
|
|
* **DO** use fixed length types defined in `stdint.h` instead
|
|
of language keywords determined by the compiler (e.g., `int64_t, uint8_t`, not
|
|
`long, unsigned char`).
|
|
|
|
* **DO** use `const` and `static` and visibility modifiers to scope exposure of
|
|
variables and methods as much as possible.
|
|
|
|
* **DO** use doxygen comments, with \[in,out\]
|
|
[direction annotation](http://www.doxygen.nl/manual/commands.html#cmdparam) in all public API
|
|
headers. This is also encouraged, but not strictly required, for internal API
|
|
headers as well.
|
|
|
|
* **DO** disable doxygen documentation for elements that are not in the public
|
|
API as described [here](./refman/doxygen-howto.md#disable-doxygen).
|
|
|
|
* **DON'T** use global variables where possible.
|
|
|
|
* **DON'T** use abbreviations unless they are already well-known terms known by
|
|
users (e.g., "app", "info"), or are already required for use by developers (e.g.,
|
|
"min", "max", "args"). Examples of bad use would be `num_widgets` instead of
|
|
`widget_count`, and `opt_widgets` instead of `option_widgets` or `optional_widgets`.
|
|
|
|
* **DON'T** use hard-coded magic numbers for things that have to be consistent
|
|
between different files. Instead use a `#define` or an enum or const value, as appropriate.
|
|
|
|
* **DON'T** use the same C function name with two different prototypes across
|
|
the project where possible.
|
|
|
|
* **DON'T** use commented-out code, or code in an `#if 0` or equivalent. Make sure all code is actually
|
|
built.
|
|
|
|
Header Files
|
|
------------
|
|
|
|
* **DO** make sure any header file can be included directly, without requiring other
|
|
headers to be included first. That is, any dependencies should be included within
|
|
the header file itself.
|
|
|
|
* **DO** include system headers (with `<>`) before local headers (with `""`), and list them
|
|
in alphabetical order where possible. This helps ensure there are not duplicate includes,
|
|
and also helps ensure that headers are usable directly.
|
|
|
|
* **DO** use `#pragma once` in all header files, rather than using ifdefs to test for duplicate inclusion.
|
|
|
|
Style Guide
|
|
-----------
|
|
|
|
### Automated Formatting with `clang-format`
|
|
|
|
For all C/C++ files (`*.c`, `*.cpp` and `*.h`), we use `clang-format` (specifically
|
|
version 3.6) to apply our code formatting rules. After modifying C/C++ files and
|
|
before merging, be sure to run:
|
|
|
|
```sh
|
|
$ ./scripts/format-code
|
|
```
|
|
|
|
This allows us to apply formatting choices such as the use of [Allman style](
|
|
http://en.wikipedia.org/wiki/Indent_style#Allman_style) braces and the 80
|
|
character column width consistently.
|
|
|
|
Please stage the formatting changes with your commit, instead of making an extra
|
|
"Format Code" commit. Your editor can likely be set up to automatically run
|
|
`clang-format` across the file or region you're editing. See:
|
|
|
|
- [clang-format.el](https://github.com/llvm-mirror/clang/blob/master/tools/clang-format/clang-format.el) for Emacs
|
|
- [vim-clang-format](https://github.com/rhysd/vim-clang-format) for Vim
|
|
- [vscode-cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
|
|
for Visual Studio Code
|
|
|
|
The [.clang-format](../.clang-format) file describes the style that is enforced
|
|
by the script, which is based off the LLVM style with modifications closer to
|
|
the default Visual Studio style. See [clang-format style options](
|
|
http://releases.llvm.org/3.6.0/tools/clang/docs/ClangFormatStyleOptions.html)
|
|
for details.
|
|
|
|
If you see unexpected formatting changes in the code, verify that you are running version 11 or higher of the LLVM tool-chain.
|
|
|
|
### License Header
|
|
|
|
The following license header **must** be included at the top of every code file:
|
|
|
|
```
|
|
// Copyright (c) Microsoft Corporation
|
|
// SPDX-License-Identifier: MIT
|
|
```
|
|
|
|
It should be prefixed with the file's comment marker. If there is a compelling
|
|
reason to not include this header, the file can be added to
|
|
`.check-license.ignore`.
|
|
|
|
All files are checked for this header with the script:
|
|
|
|
```sh
|
|
$ ./scripts/check-license
|
|
```
|
|
|
|
### Naming Conventions
|
|
|
|
Naming conventions we use that are not automated include:
|
|
|
|
1. Use `lower_snake_case` for variable, member/field, and function names.
|
|
2. Use `UPPER_SNAKE_CASE` for macro names and constants.
|
|
3. Prefer `lower_snake_case` file names for headers and sources.
|
|
4. Prefer full words for names over contractions (i.e., `memory_context`, not
|
|
`mem_ctx`).
|
|
5. Prefix names with `_` to indicate internal and private fields or methods
|
|
(e.g., `_internal_field, _internal_method()`).
|
|
6. The single underscore (`_` ) is reserved for local definitions (static,
|
|
file-scope definitions).
|
|
e.g., static ebpf_result_t _do_something(..).
|
|
7. Prefix `struct` definitions with `_` (this is an exception to point 6), and always create a `typedef` with the
|
|
suffix `_t`. For example:
|
|
```c
|
|
typedef struct _ebpf_widget
|
|
{
|
|
uint64_t count;
|
|
} ebpf_widget_t;
|
|
```
|
|
8. Prefix eBPF specific names in the global namespace with `ebpf_` (e.g., `ebpf_result_t`).
|
|
|
|
Above all, if a file happens to differ in style from these guidelines (e.g.,
|
|
private members are named `m_member` rather than `_member`), the existing style
|
|
in that file takes precedence.
|