Skip to content

Commit

Permalink
Merge pull request #142 from UAVCAN/api-simplification
Browse files Browse the repository at this point in the history
UAVCAN v1.0 done
  • Loading branch information
pavel-kirienko authored Mar 8, 2020
2 parents c1cf930 + b16a86b commit a2f3364
Show file tree
Hide file tree
Showing 36 changed files with 5,293 additions and 3,986 deletions.
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ cmake-build-*/
build-avr/

# IDE and tools
.idea
.metadata
.settings
.project
.cproject
.pydevproject
.gdbinit
.vscode/
**/.idea/*
!**/.idea/dictionaries
!**/.idea/dictionaries/*

# Generated files
dsdlc_generated/

# Pycache
__pycache__/

# Ignore IDE folders
.vscode/
79 changes: 79 additions & 0 deletions .idea/dictionaries/pavel.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 72 additions & 22 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
dist: xenial
env:
- CTEST_OUTPUT_ON_FAILURE=1

matrix:
include:
Expand All @@ -17,44 +19,92 @@ matrix:
- g++-9-multilib
- gcc-9-multilib
- linux-libc-dev:i386
env:
- CC=gcc-9
- CXX=g++-9
script:
- CC=gcc-9 && CXX=g++-9 && cmake tests
- build-wrapper-linux-x86-64 --out-dir sonar-dump make all # The build wrapper comes from Sonar Cloud.
- ./run_tests --rng-seed time
- sonar-scanner
# ANALYSIS
# Using the build wrapper from Sonar and collecting the code coverage.
# Define NDEBUG=1 to avoid assertion checks being reported as uncovered statements.
- cmake tests -DCMAKE_BUILD_TYPE=Debug -DNO_STATIC_ANALYSIS=1 -DCMAKE_C_FLAGS='-DNDEBUG=1'
- build-wrapper-linux-x86-64 --out-dir sonar-dump make all
- make test
- gcov-9 --preserve-paths --long-file-names $(find CMakeFiles/test_private_cov.dir -name '*.gcno')
- gcov-9 --preserve-paths --long-file-names $(find CMakeFiles/test_private_le_cov.dir -name '*.gcno')
- gcov-9 --preserve-paths --long-file-names $(find CMakeFiles/test_public_cov.dir -name '*.gcno')
- 'sonar-scanner -Dsonar.projectKey=libcanard
-Dsonar.organization=uavcan
-Dsonar.sources=libcanard
-Dsonar.cfamily.gcov.reportsPath=.
-Dsonar.cfamily.build-wrapper-output=sonar-dump
-Dsonar.cfamily.cache.enabled=false'
- make clean

# DEBUG
- cmake tests -DCMAKE_BUILD_TYPE=Debug -DNO_STATIC_ANALYSIS=1
- make all VERBOSE=1 && make test
- make clean

# RELEASE
- cmake tests -DCMAKE_BUILD_TYPE=Release -DNO_STATIC_ANALYSIS=1
- make all VERBOSE=1 && make test
- make clean

# -------------------- Clang 9 --------------------
- language: cpp
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libstdc++-7-dev:i386
packages: # Install a newer GCC because https://stackoverflow.com/a/51512150/1007777.
- g++-9
- g++-9-multilib
- gcc-9-multilib
- linux-libc-dev:i386
- libc6-dev-i386
- libstdc++-7-dev:i386
script:
# Set up the toolchain.
- wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 9
- clang++-9 -E -x c++ - -v < /dev/null # Print the Clang configuration for troubleshooting purposes
- cmake -DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9 tests
- make
- ./run_tests --rng-seed time
- sudo apt install clang-tidy-9 clang-format-9
- clang++-9 -E -x c++ - -v < /dev/null # Print the Clang configuration for troubleshooting purposes.

# -------------------- Static analysis --------------------
- language: cpp
script:
- sudo rm -rf /usr/local/clang*
- wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 9
- sudo apt install clang-format-9 clang-tidy-9
- sudo ln -sf $(which clang-format-9) /usr/bin/clang-format
- sudo ln -sf $(which clang-tidy-9) /usr/bin/clang-tidy
# DEBUG
- cmake -DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9 tests -DCMAKE_BUILD_TYPE=Debug
- make VERBOSE=1 && make test
- make clean

# RELEASE
- cmake -DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9 tests -DCMAKE_BUILD_TYPE=Release
- make VERBOSE=1 && make test
- make clean

# TODO: invoke clang-tidy.
# RELWITHDEBINFO
- cmake -DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9 tests -DCMAKE_BUILD_TYPE=RelWithDebInfo
- make VERBOSE=1 && make test
- make clean

# Code style enforcement.
- ./format.sh
# MINSIZEREL
- cmake -DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9 tests -DCMAKE_BUILD_TYPE=MinSizeRel
- make VERBOSE=1 && make test
- make clean

# Format check
- make format VERBOSE=1
- 'modified="$(git status --porcelain --untracked-files=no)"'
- 'if [ -n "$modified" ]; then echo "Run format.sh to reformat the code."; exit 1; fi'
- 'if [ -n "$modified" ]; then echo "Run make format to reformat the code properly."; exit 1; fi'

# -------------------- AVR GCC --------------------
- language: c
addons:
apt:
packages:
- gcc-avr
- avr-libc
script:
# This is a trivial test where we only check whether it compiles at all with all warnings enabled.
# TODO: Write unit tests and run them on an emulator.
- avr-gcc libcanard/*.c -c -std=c11 -mmcu=at90can64 -Wall -Wextra -Werror -pedantic -Wconversion -Wtype-limits

git:
depth: false # Disable shallow clone because it is incompatible with SonarCloud
103 changes: 103 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Libcanard contribution guide

## Design principles

The library is intended for use in real-time high-integrity applications.
It is paramount that its temporal properties and resource utilization are plain to model and predict statically.
The code shall follow applicable high-reliability coding guidelines as explained later in this document.
The implementation shall be fully compliant with the UAVCAN/CAN specification.

The implementation and the API should be kept simple.
The core library `canard.c` (that is, excluding the optional DSDL presentation layer extension) shall never become
larger than 1000 logical lines of code.
This restriction ensures that the library is kept simple and easy to validate and verify.
There will be no high-level abstractions -- if that is desired, other implementations of UAVCAN should be used.

The library is intended for deeply embedded systems where the resources may be scarce.
The ROM footprint is of a particular concern because the library should be usable with embedded bootloaders.

## Directory layout

The production sources and some minimal configuration files (such as `.clang-tidy`) are located under `/libcanard/`.
Do not put anything else in there.

The tests are located under `/tests/`.
This directory also contains the top `CMakeLists.txt` needed to build and run the tests on the local machine.

There is no separate storage for the documentation because it is written directly in the header files.
This works for Libcanard because it is sufficiently compact and simple.

## Standards

The library shall be implemented in ISO C11 following MISRA C:2012.
The MISRA compliance is enforced by Clang-Tidy and SonarQube.
Deviations are documented directly in the source code as follows:

```c
// Intentional violation of MISRA: <some valid reason>
<... deviant construct ...>
```

The full list of deviations with the accompanying explanation can be found by grepping the sources.

Do not suppress compliance warnings using the means provided by static analysis tools because such deviations
are impossible to track at the source code level.
An exception applies for the case of false-positive (invalid) warnings -- those should not be mentioned in the codebase.

[Zubax C++ Coding Conventions](https://kb.zubax.com/x/84Ah) shall be followed.
Formatting is enforced by Clang-Format; it is used also to fail the CI/CD build if violations are detected.

Unfortunately, some rules are hard or impractical to enforce automatically,
so code reviewers shall be aware of MISRA and general high-reliability coding practices
to prevent non-compliant code from being accepted into upstream.

## Tools

The following tools are required to conduct library development locally:

- GCC v9 or newer.
- Clang and Clang-Tools v9 or newer.
- CMake v3.12 or newer.
- An AMD64 machine.

### Clang-Tidy

Clang-Tidy is used to enforce compliance with MISRA and Zubax Coding Conventions.
There are separate configuration files per directory:

- `/libcanard/` (the production code) is equipped with the most stringent configuration.

- `/tests/` is equipped with a separate configuration which omits certain rules that are considered
expensive to maintain.
This is because the test suite is intentionally kept to a somewhat lower quality bar to reduce development costs.

Clang-Tidy is invoked automatically on each translation unit before it is compiled;
the build will fail if the tool is not available locally.
To disable this behavior, pass `NO_STATIC_ANALYSIS=1` to CMake at the generation time.

### Clang-Format

Clang-Format is used to enforce compliance with MISRA and Zubax Coding Conventions.
There is a single configuration file at the root of the repository.

To reformat the sources, generate the project and build the target `format`; e.g., for Make: `make format`.

### SonarQube

SonarQube is a cloud solution so its use is delegated to the CI/CD pipeline.
If you need access, please get in touch with the UAVCAN Development Team members.

### IDE

The recommended development environment is JetBrains CLion. The root project file is `tests/CMakeLists.txt`.
The repository contains the spelling dictionaries for CLion located under `.idea/`, make sure to use them.

## Testing

Generate the CMake project, build all, and then build the target `test` (e.g., `make test`).
The tests are built for x86 and x86_64; the latter is why an AMD64 machine is required for local development.

At the moment, the library is not being tested against other platforms.
We would welcome contributions implementing CI/CD testing against popular embedded architectures, particularly
the ARM Cortex M series and AVR in an emulator.
As a high-integrity library, the Libcanard test suite should provide full test coverage for all commonly used platforms.
Loading

0 comments on commit a2f3364

Please sign in to comment.