-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix links and references to DNP3 * tweak the supported functions * update dependencies * update the TCP server page * update the TLS server page with info about the mode that doesn't require the x.509 role extension * Add a C++ page * fix broken C++ logging doc reference * update the serial RTU page
- Loading branch information
1 parent
9f54bc0
commit 0d68860
Showing
9 changed files
with
156 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,41 @@ | ||
--- | ||
id: dependencies | ||
title: Managing Open Source Dependencies | ||
title: Open Source Dependencies | ||
sidebar_label: Dependency Licenses | ||
slug: /dependencies | ||
--- | ||
|
||
import useBaseUrl from '@docusaurus/useBaseUrl'; | ||
import sitedata from '../../sitedata.json' | ||
|
||
Because Rust's package manager `cargo` makes it easy to work with external dependencies, Rust's open-source ecosystem tends to be oriented towards many smaller | ||
libraries. Our library only depends directly on a few third-party libraries; however, those libraries pull in dozens of sub-dependencies. Here's how we | ||
manage our direct and indirect dependencies. | ||
Rust's package manager (`cargo`) makes it easy to work with external dependencies. This is wonderful for development, but means that Rust applications | ||
and libraries tend to have many dependencies. | ||
|
||
## Automated License Checking | ||
Our library only depends directly on a handful of third-party libraries; however, those libraries pull in dozens of their own dependencies. Here's how we manage | ||
our direct and indirect dependencies. | ||
|
||
We developed an automated tool called `complicense` to ensure that our binary distributions meet the legal requirements for third-party open source licenses. | ||
This tool performs the following tasks: | ||
## Dependency Whitelisting | ||
|
||
* Analyzes each dependency's license against an allowed list of licenses. Our CI packaging will fail if add a dependency is added with a license that has not been pre-approved. | ||
* Uses the Github API to automatically retrieve the license file for each project hosted on Github. Only a few projects don't have the proper metadata; the | ||
license name and content for those are specified manually in the `complicense` configuration. | ||
* Ignores projects that are 100% copyrighted by Step Function I/O (e.g., the DNP3 library itself). | ||
* Produces a license report document called `dependencies.txt` that consolidates all the dependency and license information. We include this document in all of | ||
our binary distributions to make it easy for you to comply with the open source licenses. | ||
We use a dependency whitelist to ensure that we never incorporate dependencies into our builds unless they are manually approved. During each CI build, the following | ||
checks are performed: | ||
|
||
## Proprietary Compatible | ||
|
||
All of our library's dependencies have licenses that are both mutually compatible and compatible with commercial/proprietary products. We don't allow the | ||
incorporation of strong copyleft licenses such as the GPL. You can see a complete list of allowed licenses in <a href={`${sitedata.github_url}/blob/${sitedata.version}/deps-config.json`}>deps-config.json</a>. | ||
* Check every dependency against the whitelist. Our CI packaging will fail if add a dependency is added with a license that has not been pre-approved. | ||
* Produce a license report called `third-party-licenses.txt` that consolidates all the dependency and license information. We include this document in all of | ||
our binary distributions. | ||
* Ignore projects that are 100% copyrighted by Step Function I/O, e.g. the library itself and some dependencies we share between with our other protocol libraries. | ||
|
||
## Licenses.txt | ||
:::note | ||
The license report file differs slightly for the Java library as it incorporates some additional components for the JNI functionality. | ||
::: | ||
|
||
`complicense` produces a detailed report called <a href={`${sitedata.github_url}/releases/download/${sitedata.version}/dependencies.txt`}>dependencies.txt</a> that includes the following | ||
information for each dependency: | ||
|
||
* Unique name of the library (Rust crate) | ||
* Repository URL where the library is hosted | ||
* Authors of the library as specified on [crates.io](https://crates.io/) | ||
* Description of the library | ||
* Name of the license(s) that apply to the crate | ||
* Full license text, including any copyright notices present | ||
## Proprietary Compatible | ||
|
||
Some libraries choose to dual-license under multiple licenses and give users the choice of which license to use. In this case, the report only includes the text of the license returned by the Github API. | ||
All dependencies of the library have licenses that are both mutually compatible and compatible with commercial/proprietary products. We don't allow the | ||
incorporation of strong copyleft licenses such as the GPL. You can see a complete list of allowed dependencies and licenses in <a href={`${sitedata.github_url}/blob/${sitedata.version}/deps_config.json`}>deps_config.json</a>. | ||
|
||
## Disclaimer | ||
|
||
We've included this information because we take open source license compliance seriously. That said, this information and the `dependencies.txt` file are provided for your reference and do not constitute legal advice. Treat this information as a starting point so you can perform your own due diligence. | ||
We've included this information because we take open source license compliance seriously. That said, this information and the `third-party-licenses.txt` file are provided for your reference and do not constitute legal advice. Treat this information as a starting point so you can perform your own due diligence. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
id: cpp_bindings | ||
title: C++ bindings | ||
sidebar_label: C++ | ||
slug: /cpp_bindings | ||
--- | ||
|
||
import useBaseUrl from '@docusaurus/useBaseUrl'; | ||
import sitedata from '../../sitedata.json' | ||
|
||
Each [C package distribution](./c_lang.mdx) also includes C++ wrappers for easy usage. The `rodbus.hpp` file includes the public API | ||
and a `src/rodbus.cpp` contains the companion code which maps the C++ API to the underlying C API. | ||
|
||
## CMake Usage | ||
|
||
The CMake package script includes a `rodbus_cpp` target that automatically links with the C bindings and builds the C++ wrapper code. | ||
|
||
Make the find package script discoverable by adding it to the prefix path. Next, call `find_package`: | ||
|
||
```cmake | ||
# Define CMake project with CXX language | ||
project(my_awesome_project LANGUAGES C CXX) | ||
# Import the rodbus package | ||
set(CMAKE_PREFIX_PATH ${DISTRIBUTION_PATH}/cmake) | ||
find_package(rodbus REQUIRED) | ||
# Create and link the executable w/ the c++ library | ||
add_executable(my_awesome_project main.cpp) | ||
target_link_libraries(my_awesome_project PRIVATE rodbus_cpp) | ||
``` | ||
|
||
:::note | ||
The `rodbus_cpp` CMake target is made available only if the `CXX` language is enabled. Languages can be enabled in the | ||
[project()](https://cmake.org/cmake/help/latest/command/project.html) command or with a separate | ||
[enable_language()](https://cmake.org/cmake/help/latest/command/enable_language.html) command. | ||
::: | ||
|
||
## Mapping | ||
|
||
Most of the abstract concepts in the binding generator map directly to C++. | ||
|
||
### Errors | ||
|
||
All C API errors are transformed into a C++ exceptions containing the error enum. All exceptions derive from `std::logic_error`. | ||
|
||
Other validations (e.g. checking that a moved class isn't used after the move) also throw `std::logic_error`. | ||
|
||
:::warning | ||
Uncaught exceptions thrown in callbacks will terminate the program. Always wrap your callback logic using `try/catch` syntax if there's a possibility the callback will throw. | ||
::: | ||
|
||
### Iterators | ||
|
||
Iterators are wrapped in a class for easier manipulation. Iterating on them should done like so: | ||
|
||
```cpp | ||
while(iter.next()) { | ||
auto value = iter.get(); | ||
} | ||
``` | ||
|
||
The `next()` advances the iterator and returns `true` if a value is available. The `get()` returns the current value pointed, or throws | ||
`std::logic_error` if the end was reached. | ||
|
||
:::warning | ||
The iterator wrapper does **not** copy and accumulate the values like in C# or Java. Therefore, an iterator should **never** be used outside of the callback. | ||
Frequently, the iterator points to memory on the stack and will result in undefined behavior if it is used after the callback is complete. | ||
::: | ||
|
||
### Collections | ||
|
||
Collections are taken through a constant reference to a `std::vector`. The elements will be copied internally. | ||
|
||
### Classes | ||
|
||
Classes have a opaque pointer inside and therefore cannot be copied. They can be moved around with `std::move`. If a method | ||
is called on a moved class it throw a `std::logic_error`. | ||
|
||
The class destructor will call the underlying C destructor automatically. | ||
|
||
### Interfaces | ||
|
||
Interfaces are abstract classes containing only pure virtual functions where every callback must be implemented. The destructor is virtual to allow proper cleanup. | ||
|
||
Owned interfaces that are invoked asynchronously by the library are passed into the API as a `std::unique_ptr<T>`. Use `std::make_unique` to create these smart pointers. | ||
|
||
Non-owned (synchronous) interfaces are passed by reference. There are also functional wrappers that take a lambda | ||
function as an argument available in the `dnp3::functional` namespace. | ||
|
||
### Async methods | ||
|
||
C++ doesn't have a robust model for asynchronous computations in the standard library (yet). You can only extract a value | ||
from a C++ `std::future` using the blocking `get` method and there is no way to chain asynchronously chain futures. | ||
|
||
Asynchronous methods are mapped to callback interfaces with two methods: | ||
|
||
* `on_complete` is called when the operation succeeds | ||
* `on_failure` is called if an error occurs | ||
|
||
If you already use an external futures library, it will be easy to use our callbacks to complete your futures. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters