KO
|
EN
gitlite — search
Search
#python
#java
#python3
#arduino
#golang
#machine-learning
#rust
#html
#flask
#javascript
#seismology
#nodejs
NativeLibsCommon
★ 12
Open GitHub ↗
Native libs common
Download README (.md)
Explore Similar Repositories
SuperLemminiToo
:
My personal fork of SuperLemmini, which itself is a fork of Lemmini
anime-launcher
:
List your offline anime in an app
Meshtastic-Telegram
:
Simple app connecting Meshtastic with Telegram API
AimBotStandoff2ForModMenu
:
No description available.
maid
:
(WIP) self-contained todo list tui, inspired by void-rs
// repository documentation
Was this content helpful?
★ 0
(0 ratings)
Select Rating:
★
★
★
★
★
Submit Feedback
Recent Feedback
×
Download README
Do you want to download the
README.md
file for
NativeLibsCommon
?
Download (.md)
# Native libs common stuff ## Prerequisites - Conan C++ package manager 2.0.4 or higher - CMake 3.24 or higher - GCC 9 or higher / Clang 8 or higher ## Build ### Linux ```shell mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_CXX_FLAGS="-stdlib=libc++" \ .. ``` ### Windows ```shell mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ^ -DCMAKE_C_FLAGS_DEBUG=/MT ^ -DCMAKE_CXX_FLAGS_DEBUG=/MT ^ -G Ninja ^ .. ``` ### macOS ```shell mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_CXX_FLAGS="-stdlib=libc++" \ .. ``` ### Cross-compiling with zig [zig](https://ziglang.org/) can be used as a self-contained cross-compiler via its `cc` / `c++` subcommands, which removes the need for a separate cross toolchain: ```shell mkdir build && cd build cmake -DCMAKE_C_COMPILER="zig;cc;-target;x86_64-linux-musl" \ -DCMAKE_CXX_COMPILER="zig;c++;-target;x86_64-linux-musl" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_SYSTEM_PROCESSOR=x86_64 \ -DCMAKE_CROSSCOMPILING=ON \ -GNinja \ .. ``` `CMAKE_SYSTEM_PROCESSOR` must match the `-target` architecture: it is the only source for the Conan `arch` setting. Without it, `arch` is inherited from the build machine's default profile, and Conan would resolve dependencies for the host architecture while zig compiles for the target. The compiler must be passed as a CMake list (`zig;cc;-target;...`), since `zig cc` is a subcommand rather than a standalone binary. Conan's `compiler_executables` accepts only an argument-less executable, so `cmake/conan_provider.cmake` detects this form and generates wrapper scripts in `${CMAKE_BINARY_DIR}/zig-wrappers/` that re-attach the subcommand and target, then points the Conan profile at those. The wrappers are named after the target triple, following the usual cross-toolchain convention, so build systems that infer cross-compilation from the compiler name recognise them: ```text zig-wrappers/x86_64-linux-musl-cc zig-wrappers/x86_64-linux-musl-c++ ``` Two settings distinguish zig builds from ordinary ones: - `compiler.libcxx` is left out of the profile, as zig supplies its own libc++ per target. - `os.ag_cc_is_zig=1` is added, so packages built with zig get their own package ID instead of colliding with packages built by a plain clang of the same version. Currently, it contains Conan recipes for AdGuard libs ## Testing ### Build All Tests ```shell # Configure the project (if not done already) cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug # Build all tests cmake --build build --target tests ``` ### Run All Tests ```shell # Run all tests using CTest ctest --test-dir build --verbose ``` ### Run Specific Tests ```shell # Run a specific test executable directly ./build/common/network_monitor_test ``` ## How to use conan Conan is a C++ package manager. It is similar to maven, but stores recipes and binaries separately. Binaries can be uploaded to a repo and reused. It is recommended to use the custom remote repo as the main repo (`-i 0`). Conan looks up binaries in the repo from which recipes were downloaded. So if a recipe is from conan-center, you won't be able to store binaries because it has the highest priority by default. ```shell conan remote add --index 0 $REMOTE_NAME https://$ARTIFACTORY_HOST/artifactory/api/conan/$REPO_NAME ``` We customized some packages, so they need to be exported to local conan repository. ```shell ./scripts/export_conan.sh ``` If you want to upload built binaries and recipes to conan remote repository, use following command: ```shell conan upload -r $REMOTE_NAME -c '*' ``` If you want to upload exported only recipes to conan remote repository, use following command: ```shell conan upload -r $REMOTE_NAME -c '*' --only-recipe ``` ## Testing changes as a dependency To test local changes in the library when it is used as a Conan package dependency, export a recipe and point the dependent project at it. Use `conan export` (not `conan create`) so the package is built later with the dependent project's target profile rather than the default one. 1) If the default `vcs_url` in `<root>/conanfile.py` is not suitable, change it accordingly. 2) Export the current working tree as version `local` (the recipe stages the git-tracked working tree, so no commit or push is required): ```shell conan export . --version local ``` 3) In the dependent project, replace `native_libs_common/1.0.0@adguard/oss` with `native_libs_common/local`. 4) Re-run the cmake command; the package is built with that project's profile. Note: after further changes, purge the cached copy before re-exporting: `conan remove -c "native_libs_common/local"`. ## Code style ### Common 1. Indentation is 4 spaces (imported files may have another indent). 2. Code must be commented enough in terms of control flow. All public and big static methods should have a description in Doxygen format (`/** */`) 3. Formatting rules. We use CLion basic rules. They are based on LLVM and Apple rules, and applies 4 spaces indentation by default. But there are also rules not related to indentation: - Binary operator are always separated by spaces from their operands (x + y) - Screen width: 120 symbols (not 80) - In function definition, operator block is started on function line `int main(int argc, char **argv) {`. However, `int func() try {` is prohibited. If it makes harder to read the code, next line may be empty: ```c++ int very_long_function_definition( int foo1234567890, int bar9876543210, int baz9999999999, int x4242424242, int y1010101010, int z0101010101) noexcept { do_smth(); } ``` - In loops and ifs, operator block is started on function line too. Single-line branches should be in operator braces too. 4. Identifier prefixes other than `p_`, `m_`, `g_` and `_` is prohibited 5. Don't use `p` prefix unless it is really needed. In most cases type of identifier says what is it. 6. All new headers should contain `#pragma once` guard instead of `#define` one. ### C No new C code please. ### C++ 1. Language standard - C++20 (-std=c++20) 2. Class prefixes - use namespaces instead. 3. Namespaces - root namespace is ag::, max depth is 2 (plus may be ::test). Namespace names are snake_cases. 4. Class naming - Capital CamelCase (Rust-like) 5. Using naming - Capital CamelCase. If it is wrapped pointer to type with `snake_case`, then it may be named `snake_case_ptr`. 6. Instance naming - snake_case 7. Member function, non-member variable and parameter naming - `snake_case` 8. Member variable naming - `m_snake_case`, public members of struct are `snake_case`. 9. Member access - `m_something`, or `this->something` if `m_` is missing in name. 10. Constants and enum values (static const, constexpr and defines) naming - `CAPITAL_UNDER_SCORE` 11. Global variables - `g_snake_case` 12. Includes order - Chromium-style: a. List of external headers in `<>` b. List of our public headers, alphabetically sorted, in `""`. If current unit is implementation of the public header, that include should anyway be included here. c. List of current directory headers, alphabetically sorted, in `""`. This section should not exist in public headers. Code example: ```c++ #pragma once #include <string> namespace ag::utils { class Strings { public: /** * Make greeting to the world * @param x Some random value * @return The greeting */ static std::string hello_world(int x); } } ``` ```c++ #include <string> #include "common/utils.h" #include "another_utils.h" namespace ag::utils { std::string Strings::hello_world(int x) { if (x % 2) { return "Hello, world!!"; } else { return "Hello, world!1"; } } } ``` ### Doxygen comments - All public methods and functions should be documented. - Use Javadoc style with an `autobrief` feature. - `autobrief` means that the first statement of a long description automatically becomes a brief description. So `@brief` is redundant. - Use `@return`, not `@returns` - Use `[out]` in `@param` only if code is not self-explanatory. - Don't use `[in]` in `@param`. - Don't use extra line endings. - Use infinitive instead of the third person in brief descriptions. - Descriptions should start with a capital letter. Examples: ```c++ /** * Sum of x and y. * This function is usually used to get sum of x and y. * @param x The x * @param yy The y * @return Sum of x and y. int plus(int x, int yy) { return x + yy; } enum class t { A, /**< One-line post-identifier comment */ /** Another one-line comment */ B, /** Third one-line comment */ C, D, /**< One-line post-identifier comment */ } ```