Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b81fdbb
Initial component ffi
paullegranddc Dec 17, 2024
a59b186
Add examples
paullegranddc Dec 23, 2024
3743039
Add library-config feature to profiling artifact build
paullegranddc Dec 23, 2024
ba25130
fix function prefix
paullegranddc Dec 23, 2024
cbde4ba
build profiling ffi also commit cargo toml
paullegranddc Dec 24, 2024
c840768
Add static config deserialzation
paullegranddc Dec 26, 2024
785bee2
fix(library_config): Generate for CPP (Python) + small fixes
BaptisteFoy Dec 27, 2024
83affc3
add partial process matching
BaptisteFoy Dec 30, 2024
62b32df
licenses & test fixes
BaptisteFoy Dec 30, 2024
8ffe755
more ci fixes
BaptisteFoy Dec 31, 2024
766522b
feat(libconfig): Add ddog_library_configurator_get_from_bytes method
BaptisteFoy Dec 31, 2024
b6d3078
public static_config for nodejs
BaptisteFoy Dec 31, 2024
8a71af6
fix off by one
BaptisteFoy Dec 31, 2024
6266f3b
* Split configuration in two crates for easier
paullegranddc Jan 14, 2025
8ba1544
Add dictionnary keys for tags and env variables
paullegranddc Jan 14, 2025
6349c50
Apply lints
paullegranddc Jan 14, 2025
933368f
Add license header
paullegranddc Jan 14, 2025
3279aab
clippy
paullegranddc Jan 14, 2025
7ef9130
Update 3rd party locense file
paullegranddc Jan 14, 2025
2d85a05
Fix docker build
paullegranddc Jan 15, 2025
4c444b9
lints
BaptisteFoy Jan 15, 2025
08fa3d9
impl LibraryConfigName
BaptisteFoy Jan 15, 2025
68706d7
Merge branch 'main' into paullgdc/library_config/initial_component
BaptisteFoy Jan 15, 2025
16a118e
* Fix typos
paullegranddc Jan 16, 2025
f685627
Add a few more comments
paullegranddc Jan 16, 2025
b70b834
Change builder feature name in tests
paullegranddc Jan 16, 2025
458ea7d
Undelete build telemetry script
paullegranddc Jan 16, 2025
d7849ed
Merge branch 'main' into paullgdc/library_config/initial_component
paullegranddc Jan 16, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ jobs:
env:
RUSTFLAGS: "${{ matrix.flags }}"
run: |
cargo run --bin release --features profiling,telemetry,data-pipeline,symbolizer,crashtracker --release -- --out $LIBDD_OUTPUT_FOLDER
cargo run --bin release --features profiling,telemetry,data-pipeline,symbolizer,crashtracker,library-config --release -- --out $LIBDD_OUTPUT_FOLDER

- name: 'Publish libdatadog'
uses: actions/upload-artifact@v4
Expand Down
42 changes: 42 additions & 0 deletions Cargo.lock

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

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ members = [
"ddsketch",
"tinybytes",
"dogstatsd-client",
"library-config-ffi",
"library-config",
]

# https://doc.rust-lang.org/cargo/reference/resolver.html#feature-resolver-version-2
Expand Down Expand Up @@ -66,7 +68,7 @@ debug = 2 # full debug info
codegen-units = 1
debug = "line-tables-only"
lto = true
opt-level = "s" # optimize for size
opt-level = "s" # optimize for size

[profile.release.package.datadog-serverless-trace-mini-agent]
strip = true
Expand All @@ -82,4 +84,4 @@ codegen-units = 1
# proptest pulls in a dependency on libm, which changes the runtime of some math functions
# so benchmarks are not measuring the same thing as the release build. This patch removes
# the default dependency on libm. A PR will be opened to proptest to make this optional.
proptest = { git = 'https://github.com/bantonsson/proptest.git', branch = "ban/avoid-libm-in-std"}
proptest = { git = 'https://github.com/bantonsson/proptest.git', branch = "ban/avoid-libm-in-std" }
252 changes: 245 additions & 7 deletions LICENSE-3rdparty.yml

Large diffs are not rendered by default.

148 changes: 148 additions & 0 deletions build-config-ffi.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#!/usr/bin/env bash

# Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
# SPDX-License-Identifier: Apache-2.0

get_abs_filename() {
# $1 : relative filename
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

# Location to place all artifacts
if [ -z $CARGO_TARGET_DIR ] ; then
export CARGO_TARGET_DIR=$PWD/target
fi

set -eu

destdir="$1"

if [ $CARGO_TARGET_DIR = $destdir ]; then
echo "Error: CARGO_TARGET_DIR and destdir cannot be the same"
exit 1
fi

mkdir -v -p "$destdir/include/datadog" "$destdir/lib/pkgconfig" "$destdir/cmake"

version=$(awk -F\" '$1 ~ /^version/ { print $2 }' < profiling-ffi/Cargo.toml)
target="$(rustc -vV | awk '/^host:/ { print $2 }')"
shared_library_suffix=".so"
static_library_suffix=".a"
library_prefix="lib"
remove_rpath=0
fix_macos_rpath=0

# Rust provides this note about the link libraries:
# note: Link against the following native artifacts when linking against this
# static library. The order and any duplication can be significant on some
# platforms.
#
# We've decided to strip out -lgcc_s because if it's provided then it will
# always make it into the final runtime dependencies, even if -static-libgcc is
# provided. At least on Alpine, libgcc_s may not even exist in the users'
# images, so -static-libgcc is recommended there.
case "$target" in
"x86_64-alpine-linux-musl"|"aarch64-alpine-linux-musl")
# on alpine musl, Rust adds some weird runpath to cdylibs
remove_rpath=1
;;

"x86_64-apple-darwin"|"aarch64-apple-darwin")

shared_library_suffix=".dylib"
# fix usage of library in macos via rpath
fix_macos_rpath=1
;;

"x86_64-unknown-linux-gnu"|"aarch64-unknown-linux-gnu")
;;

"x86_64-pc-windows-msvc")
shared_library_suffix=".dll"
static_library_suffix=".lib"
library_prefix=""
;;

*)
>&2 echo "Unknown platform '${target}'"
exit 1
;;
esac


cp -v LICENSE LICENSE-3rdparty.yml NOTICE "$destdir/"


crate_dir="library-config-ffi"
crate="datadog-library-config-ffi"


FEATURES=(
"cbindgen"
)

FEATURES=$(IFS=, ; echo "${FEATURES[*]}")
echo "Building for features: $FEATURES"

# build inside the crate to use the config.toml file
( cd "$crate_dir" && cargo build --features $FEATURES --release --target "${target}" )

# Remove _ffi suffix when copying
crate_name_underscore=$(echo "$crate" | sed 's/-/_/g')
renamed_stem=$(echo "$crate_name_underscore" | sed 's/_ffi//g')

shared_library_name="${library_prefix}${crate_name_underscore}${shared_library_suffix}"
shared_library_rename="${library_prefix}${renamed_stem}${shared_library_suffix}"

static_library_name="${library_prefix}${crate_name_underscore}${static_library_suffix}"
static_library_rename="${library_prefix}${renamed_stem}${static_library_suffix}"

cp -v "$CARGO_TARGET_DIR/${target}/release/${shared_library_name}" "$destdir/lib/${shared_library_rename}"
cp -v "$CARGO_TARGET_DIR/${target}/release/${static_library_name}" "$destdir/lib/${static_library_rename}"

shared_library_name="${shared_library_rename}"
static_library_name="${static_library_rename}"

if [[ "$remove_rpath" -eq 1 ]]; then
patchelf --remove-rpath "$destdir/lib/${shared_library_name}"
fi

if [[ "$fix_macos_rpath" -eq 1 ]]; then
install_name_tool -id @rpath/${shared_library_name} "$destdir/lib/${shared_library_name}"
fi

if command -v patchelf > /dev/null && [[ "$target" != "x86_64-pc-windows-msvc" ]]; then
patchelf --set-soname ${shared_library_name} "$destdir/lib/${shared_library_rename}"
fi

# objcopy might not be available on macOS
if command -v objcopy > /dev/null && [[ "$target" != "x86_64-pc-windows-msvc" ]]; then
# Remove .llvmbc section which is not useful for clients
objcopy --remove-section .llvmbc "$destdir/lib/${static_library_name}"

# Ship debug information separate from shared library, so that downstream packages can selectively include it
# https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
objcopy --only-keep-debug "$destdir/lib/$shared_library_name" "$destdir/lib/$shared_library_name.debug"
strip -S "$destdir/lib/$shared_library_name"
objcopy --add-gnu-debuglink="$destdir/lib/$shared_library_name.debug" "$destdir/lib/$shared_library_name"
fi

echo "Building tools"
cargo build --package tools --bins

echo "Generating $destdir/include/libdatadog headers..."
rm -r $destdir/include/datadog/
mkdir $destdir/include/datadog/

CBINDGEN_HEADERS="common.h library-config.h"

CBINDGEN_HEADERS_DESTS=""
for header in $CBINDGEN_HEADERS; do
HEADER_DEST="$destdir/include/datadog/$header"
cp "$CARGO_TARGET_DIR/include/datadog/$header" "$HEADER_DEST"
CBINDGEN_HEADERS_DESTS="$CBINDGEN_HEADERS_DESTS $HEADER_DEST"
done

"$CARGO_TARGET_DIR"/debug/dedup_headers $CBINDGEN_HEADERS_DESTS

echo "Done."
4 changes: 3 additions & 1 deletion build-profiling-ffi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,11 @@ rm -r $destdir/include/datadog/
mkdir $destdir/include/datadog/

CBINDGEN_HEADERS="common.h profiling.h telemetry.h crashtracker.h data-pipeline.h"
# When optional features are added, don't forget to also include thei headers here
# When optional features are added, don't forget to also include the headers here
case $ARG_FEATURES in
datadog-library-config-ffi) CBINDGEN_HEADERS="$CBINDGEN_HEADERS library-config.h"
esac

CBINDGEN_HEADERS_DESTS=""
for header in $CBINDGEN_HEADERS; do
HEADER_DEST="$destdir/include/datadog/$header"
Expand Down
1 change: 1 addition & 0 deletions builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ profiling = []
telemetry = []
data-pipeline = []
symbolizer = []
library-config = []

[lib]
bench = false
Expand Down
2 changes: 2 additions & 0 deletions builder/src/bin/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub fn main() {
f.push("crashtracker-ffi".to_string());
#[cfg(feature = "symbolizer")]
f.push("symbolizer".to_string());
#[cfg(feature = "library-config")]
f.push("datadog-library-config-ffi".to_string());
f
};

Expand Down
2 changes: 2 additions & 0 deletions builder/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ impl Profiling {
headers.push("data-pipeline.h");
#[cfg(feature = "symbolizer")]
headers.push("blazesym.h");
#[cfg(feature = "library-config")]
headers.push("library-config.h");

let mut origin_path: PathBuf = [&self.source_include, "dummy.h"].iter().collect();
let mut target_path: PathBuf = [&self.target_include, "dummy.h"].iter().collect();
Expand Down
102 changes: 102 additions & 0 deletions ddcommon-ffi/src/cstr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use core::fmt;
use std::{
ffi::c_char,
marker::PhantomData,
mem::{self, ManuallyDrop},
ptr::{self, NonNull},
};

/// Ffi safe type representing a borrowed null-terminated C array
/// Equivalent to a std::ffi::CStr
#[repr(C)]
pub struct CStr<'a> {
/// Null terminated char array
ptr: ptr::NonNull<c_char>,
/// Length of the array, not counting the null-terminator
length: usize,
_lifetime_marker: std::marker::PhantomData<&'a c_char>,
}

impl<'a> CStr<'a> {
pub fn from_std(s: &'a std::ffi::CStr) -> Self {
Self {
ptr: unsafe { ptr::NonNull::new_unchecked(s.as_ptr().cast_mut()) },
length: s.to_bytes().len() - 1,
_lifetime_marker: std::marker::PhantomData,
}
}

pub fn into_std(&self) -> &'a std::ffi::CStr {
unsafe {
std::ffi::CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts(
self.ptr.as_ptr().cast_const().cast(),
self.length,
))
}
}
}

/// Ffi safe type representing an owned null-terminated C array
/// Equivalent to a std::ffi::CString
#[repr(C)]
pub struct CString {
/// Null terminated char array
ptr: ptr::NonNull<c_char>,
/// Length of the array, not counting the null-terminator
length: usize,
}

impl fmt::Debug for CString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_cstr().into_std().fmt(f)
}
}

impl CString {
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<Self, std::ffi::NulError> {
Ok(Self::from_std(std::ffi::CString::new(t)?))
}

pub fn as_cstr(&self) -> CStr<'_> {
CStr {
ptr: self.ptr,
length: self.length + 1, // +1 for the null terminator
_lifetime_marker: PhantomData,
}
}

pub fn from_std(s: std::ffi::CString) -> Self {
let s = ManuallyDrop::new(s);
Self {
ptr: unsafe { ptr::NonNull::new_unchecked(s.as_ptr().cast_mut()) },
length: s.to_bytes().len(),
}
}

pub fn into_std(self) -> std::ffi::CString {
let s = ManuallyDrop::new(self);
unsafe {
std::ffi::CString::from_vec_with_nul_unchecked(Vec::from_raw_parts(
s.ptr.as_ptr().cast(),
s.length,
s.length,
))
}
}
}

impl Drop for CString {
fn drop(&mut self) {
let ptr = mem::replace(&mut self.ptr, NonNull::dangling());
drop(unsafe {
std::ffi::CString::from_vec_with_nul_unchecked(Vec::from_raw_parts(
ptr.as_ptr().cast(),
self.length,
self.length,
))
});
}
}
Loading