Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

build:lint-rust --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect
build:lint-rust --output_groups=+clippy_checks
build:lint-rust --@rules_rust//:clippy.toml=//:clippy.toml
47 changes: 47 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2025 Accenture
#
# SPDX-License-Identifier: Apache-2.0

name: CI

on:
push:
branches: ["main"]
pull_request:
branches: ["*"]
workflow_dispatch:

jobs:
bazel-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: bazelbuild/setup-bazelisk@v3

- uses: actions/cache@v4
with:
path: "~/.cache/bazel"
key: bazel

- name: Build all workspace targets
run: bazel build //...

- name: Lint rust code (with clippy)
run: bazel build --config=lint-rust //...

cargo-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.83.0
components: clippy, rustfmt

- run: cargo clippy --all-features

- run: cargo fmt --check

- run: cargo build
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

# Cargo
target

# Bazel
bazel-*
MODULE.bazel.lock

# IDEs
.vscode
8 changes: 8 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

exports_files([
"clippy.toml",
"MODULE.bazel",
])
32 changes: 32 additions & 0 deletions Cargo.lock

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

11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

[workspace]
members = ["examples/rust/mw_log"]
resolver = "2"

[workspace.dependencies]
cc = "1.2.16"
log = "0.4.26"
62 changes: 62 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

module(
name = "score_mw_log",
version = "0.1",
compatibility_level = 0,
)

# Rust setup
bazel_dep(name = "rules_rust", version = "0.56.0")

RUST_EDITION = "2021"

RUST_VERSION = "1.83.0"

rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = RUST_EDITION,
sha256s = {
"rustc-1.83.0-x86_64-unknown-linux-gnu.tar.xz": "6ec40e0405c8cbed3b786a97d374c144b012fc831b7c22b535f8ecb524f495ad",
"clippy-1.83.0-x86_64-unknown-linux-gnu.tar.xz": "ef6c05abcfd861ff0bca41d408e126dda195dc966ee35abee57645a12d418f5b",
"cargo-1.83.0-x86_64-unknown-linux-gnu.tar.xz": "de834a4062d9cd200f8e0cdca894c0b98afe26f1396d80765df828880a39b98c",
"llvm-tools-1.83.0-x86_64-unknown-linux-gnu.tar.xz": "b931673b309c229e234f03271aaa777ea149c3c41f0fb43f3ef13a272540299a",
"rust-std-1.83.0-x86_64-unknown-linux-gnu.tar.xz": "c88fe6cb22f9d2721f26430b6bdd291e562da759e8629e2b4c7eb2c7cad705f2",
},
versions = [RUST_VERSION],
)
use_repo(rust, "rust_toolchains")

crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
crate.from_cargo(
name = "cargo",
cargo_lockfile = "//:Cargo.lock",
manifests = [
"//:Cargo.toml",
"//examples/rust/mw_log:Cargo.toml",
],
)
use_repo(crate, "cargo")

# To update, run `bazel run @rules_rust//tools/rust_analyzer:gen_rust_project`.
rust_analyzer = use_extension("@rules_rust//tools/rust_analyzer:deps.bzl", "rust")
rust_analyzer.rust_analyzer_dependencies()

# C/C++ setup
bazel_dep(name = "googletest", version = "1.15.0")
bazel_dep(name = "rules_cc", version = "0.0.17")
bazel_dep(name = "toolchains_llvm", version = "1.3.0")

# Configure and register the toolchain.
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
llvm.toolchain(
llvm_version = "19.1.3",
)
use_repo(llvm, "llvm_toolchain_llvm")

register_toolchains("@llvm_toolchain_llvm//:all")

# Buildifier dependency for formatting and linting bazel files.
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0")
3 changes: 3 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0
28 changes: 28 additions & 0 deletions examples/rust/mw_log/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

load("@cargo//:defs.bzl", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")

rust_library(
name = "mw_log",
srcs = glob(["src/**/*.rs"]),
deps = all_crate_deps(
normal = True,
) + [":libmw_log_cc"],
)

cc_library(
name = "libmw_log_cc",
srcs = [
"src/ffi.cc",
"src/mw_log.cc",
],
hdrs = [
"src/include/mw_log.h",
],
includes = [
"src/include",
],
)
14 changes: 14 additions & 0 deletions examples/rust/mw_log/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2025 Accenture.
#
# SPDX-License-Identifier: Apache-2.0

[package]
name = "mw_log"
version = "0.1.0"
edition = "2021"

[dependencies]
log = { workspace = true, features = ["std"] }

[build-dependencies]
cc = { workspace = true }
16 changes: 16 additions & 0 deletions examples/rust/mw_log/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2025 Accenture.
//
// SPDX-License-Identifier: Apache-2.0

fn main() {
println!("cargo::rerun-if-changed=src/include/mw_log.h");
println!("cargo::rerun-if-changed=src/mw_log.cc");
println!("cargo::rerun-if-changed=src/ffi.cc");

cc::Build::new()
.cpp(true)
.file("src/include/mw_log.h")
.file("src/mw_log.cc")
.file("src/ffi.cc")
.compile("libmw_log_cc");
}
44 changes: 44 additions & 0 deletions examples/rust/mw_log/src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2025 Accenture.
//
// SPDX-License-Identifier: Apache-2.0

use std::{thread, time::Duration};

use log::{debug, error, info, trace, warn, LevelFilter};
use mw_log::init_logging;

fn main() {
init_logging(LevelFilter::Debug);

trace!("This is a trace log, and won't show at the current level");
debug!("This is a debug log");
info!("This is an info log");
warn!("This is a warn log");
error!("This is an error log");

println!("\nRunning parallel logs\n");

let mut threads = Vec::with_capacity(10);
for msg in [
"Short message",
"This is a bit of a longer log message but still, it does not go over the buffer",
"I hope I won't be mixed with other messages",
] {
let msg = msg.to_owned();
threads.push(thread::spawn(move || {
// Messages will intermix in the output for e.g. Duration::ZERO
log_in_a_loop(&msg, 10, Duration::from_nanos(100))
}))
}

for th in threads {
th.join().unwrap();
}
}

fn log_in_a_loop(msg: &str, number_of_times: usize, timeout: Duration) {
for _ in 0..number_of_times {
info!("{msg}");
thread::sleep(timeout);
}
}
68 changes: 68 additions & 0 deletions examples/rust/mw_log/src/ffi.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2025 Accenture.
//
// SPDX-License-Identifier: Apache-2.0

#include "include/mw_log.h"

// FFI API reachable from Rust
extern "C"
{

// Create a new logger instance
void *new_logger(uint8_t max_level)
{
Logger *logger = new Logger(max_level);
return (void *)logger;
}

// Free this logger
void free_logger(void *logger_p)
{
if (logger_p != nullptr)
{
Logger *logger = (Logger *)logger_p;
delete logger;
}
}

// Check if this logger is enabled for the given metadata
//
// Has to be thread-safe
bool logger_enabled(void *logger_p, uint8_t level)
{
if (logger_p != nullptr)
{
Logger *logger = (Logger *)logger_p;
return logger->enabled(level);
}
else
{
return false;
}
}

// Log the specified message with this logger
//
// Has to be thread-safe
void logger_log(void *logger_p, uint8_t level, const unsigned char *msg_ptr, uint64_t msg_len)
{
if (logger_p != nullptr)
{

Logger *logger = (Logger *)logger_p;
logger->log(level, msg_ptr, msg_len);
}
}

// Flush this logger
//
// Has to be thread-safe
void logger_flush(void *logger_p)
{
if (logger_p != nullptr)
{
Logger *logger = (Logger *)logger_p;
logger->flush();
}
}
}
23 changes: 23 additions & 0 deletions examples/rust/mw_log/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2025 Accenture.
//
// SPDX-License-Identifier: Apache-2.0

use std::ffi::c_void;

#[link(name = "libmw_log_cc")]
unsafe extern "C" {
/// Create a new logger instance
pub unsafe fn new_logger(max_level: u8) -> *mut c_void;

/// Free this logger
pub unsafe fn free_logger(logger_p: *mut c_void);

/// Check if this logger is enabled for the given level
pub unsafe fn logger_enabled(logger_p: *mut c_void, level: u8) -> bool;

/// Log the specified message with this logger
pub unsafe fn logger_log(logger_p: *mut c_void, level: u8, msg_ptr: *const u8, msg_len: u64);

/// Flush this logger
pub unsafe fn logger_flush();
}
Loading