diff --git a/.cargo/config.github b/.cargo/config.github new file mode 100644 index 000000000..59320e8f2 --- /dev/null +++ b/.cargo/config.github @@ -0,0 +1,5 @@ +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" + +[target.aarch64-unknown-linux-musl] +linker = "aarch64-linux-musl-gcc" \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 000000000..b46430e75 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,318 @@ +name: .NET +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +env: + OUTPUT_DIR: bin + PACKAGES_DIR: packages + NUGET_NAME: ganeshnj.libdatadog + +jobs: + build: + runs-on: ${{ matrix.os }} + + # container: ${{ matrix.container }} + + env: + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + + strategy: + matrix: + include: + - os: windows-latest + target: x86_64-pc-windows-msvc + - os: windows-latest + target: i686-pc-windows-msvc + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + container: centos:7 +# - os: ubuntu-24.04 #TODO why doesn't this work +# target: aarch64-unknown-linux-gnu +# container: centos:7 + # - os: ubuntu-latest + # target: x86_64-unknown-linux-musl + # container: alpine:3.19 + # - os: arm-4core-linux-ubuntu24.04 + # target: aarch64-unknown-linux-musl + # container: alpine:3.19 + - os: macos-latest + target: aarch64-apple-darwin + - os: macos-latest + target: x86_64-apple-darwin + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: centos:7 + uses: addnab/docker-run-action@v3 + if: matrix.container == 'centos:7' + with: + image: ${{ matrix.container }} + options: -v ${{ github.workspace }}:/workspace + run: | + sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* + + yum install epel-release -y + + yum clean all -y && yum makecache -y && yum update -y + + yum install -y centos-release-scl \ + && sed -i s/mirror.centos.org/buildlogs.centos.org/g /etc/yum.repos.d/CentOS-SCLo-*.repo \ + && sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS-SCLo-*.repo \ + && sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS-SCLo-*.repo \ + && yum install -y --setopt=tsflags=nodocs --nogpgcheck \ + curl \ + devtoolset-9 \ + git \ + make \ + pkg-config \ + unzip \ + strace \ + zlib-devel \ + jq \ + && yum clean all --enablerepo='*' \ + + # switch to GCC9 environment for the duration of the script + source scl_source enable devtoolset-9 + + gcc --version + ldd --version + + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source $HOME/.cargo/env + rustup target add ${{ matrix.target }} + rustup default ${{ matrix.target }} + cargo install --force cbindgen + + cd /workspace + ./windows/build-artifacts.sh ${{ env.OUTPUT_DIR }} ${{ matrix.target }} + + - name: alpine:3.19 + uses: addnab/docker-run-action@v3 + if: matrix.container == 'alpine:3.19' + with: + image: ${{ matrix.container }} + options: -v ${{ github.workspace }}:/workspace + run: | + apk update \ + && apk add --no-cache \ + build-base \ + cargo \ + cmake \ + curl \ + git \ + make \ + patchelf \ + protoc \ + pkgconf \ + unzip \ + bash \ + jq \ + clang16-libclang \ + && mkdir /usr/local/src \ + + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source $HOME/.cargo/env + rustup target add ${{ matrix.target }} + rustup default ${{ matrix.target }} + cargo install --force cbindgen + + gcc --version + ldd --version + + cd /workspace + ./windows/build-artifacts.sh ${{ env.OUTPUT_DIR }} ${{ matrix.target }} + + - name: Windows + if: matrix.os == 'windows-latest' + run: | + $ProgressPreference = "SilentlyContinue" + Invoke-WebRequest https://win.rustup.rs/ -OutFile rustup-init.exe + .\rustup-init.exe -y --default-host=${{ matrix.target }} --default-toolchain stable --profile minimal + del rustup-init.exe + rustup target add ${{ matrix.target }} + ./windows/build-artifacts.ps1 ${{ env.OUTPUT_DIR }} ${{ matrix.target }} + shell: powershell + + - name: macOS + if: matrix.os == 'macos-latest' + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source $HOME/.cargo/env + rustup target add ${{ matrix.target }} + cargo install --force cbindgen + ./windows/build-artifacts.sh ${{ env.OUTPUT_DIR }} ${{ matrix.target }} + shell: bash + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-${{ matrix.target }} + path: | + bin/* + !bin/*/*/build + !bin/*/*/deps + !bin/*/*/examples + !bin/*/*/incremental + !bin/*/*/.fingerprint + !bin/debug + !bin/release + + pack: + runs-on: windows-latest + needs: build + outputs: + NUGET_VERSION: ${{ steps.dotnet-pack.outputs.NUGET_VERSION }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download x86_64-pc-windows-msvc + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-x86_64-pc-windows-msvc + path: bin + + - name: Download i686-pc-windows-msvc + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-i686-pc-windows-msvc + path: bin + + - name: Download x86_64-unknown-linux-gnu + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-x86_64-unknown-linux-gnu + path: bin + + - name: Download aarch64-unknown-linux-gnu + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-aarch64-unknown-linux-gnu + path: bin + + # - name: Download x86_64-unknown-linux-musl + # uses: actions/download-artifact@v4 + # with: + # name: ${{ env.OUTPUT_DIR }}-x86_64-unknown-linux-musl + # path: bin + + # - name: Download aarch64-unknown-linux-musl + # uses: actions/download-artifact@v4 + # with: + # name: ${{ env.OUTPUT_DIR }}-aarch64-unknown-linux-musl + # path: bin + + - name: Download aarch64-apple-darwin + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-aarch64-apple-darwin + path: bin + + - name: Download x86_64-apple-darwin + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_DIR }}-x86_64-apple-darwin + path: bin + + - name: dotnet pack + id: dotnet-pack + run: | + $cargo_content=Get-Content Cargo.toml -Raw + $cargo_content -match '(?m)^version += +"([^"]+)"' + $current_version=$Matches[1] + $version_suffix="ci.${{ github.event.number }}.${{ github.run_number }}" + $version="$current_version-$version_suffix" + echo "NUGET_VERSION=$version" >> $env:GITHUB_OUTPUT + dotnet pack windows/libdatadog.csproj -p:LibDatadogBinariesOutputDir=../${{ env.OUTPUT_DIR }} -p:LibDatadogVersion=$version -p:PackageID=${{ env.NUGET_NAME }} -o ${{ env.PACKAGES_DIR }} + + - name: Upload package + uses: actions/upload-artifact@v4 # v4 + with: + name: ${{ env.PACKAGES_DIR }} + path: ${{ env.PACKAGES_DIR }} + + test: + runs-on: ${{ matrix.os }} + needs: pack + + strategy: + matrix: + include: + - os: windows-latest + - os: ubuntu-latest + container: centos:7 + - os: macos-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download package + uses: actions/download-artifact@v4 + with: + name: ${{ env.PACKAGES_DIR }} + path: ${{ env.PACKAGES_DIR }} + + - name: ${{ matrix.container }} Test + uses: addnab/docker-run-action@v3 + if: matrix.container == 'centos:7' || matrix.container == 'alpine:3.19' + with: + image: ${{ matrix.container }} + options: -v ${{ github.workspace }}:/workspace + run: | + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 6.0 + export PATH=$PATH:~/.dotnet + dotnet --info + + cd /workspace/tests/nuget_package + export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 + dotnet add nuget_package.csproj package ${{ env.NUGET_NAME }} --version ${{ needs.pack.outputs.NUGET_VERSION }} + dotnet run + + - name: Install .NET SDK + if: matrix.os == 'windows-latest' || matrix.os == 'macos-latest' + uses: actions/setup-dotnet@3e891b0cb619bf60e2c25674b222b8940e2c1c25 #v4 + with: + dotnet-version: 6.0.X + + - name: Test + if: matrix.os == 'windows-latest' || matrix.os == 'macos-latest' + run: | + cd tests/nuget_package + dotnet add nuget_package.csproj package ${{ env.NUGET_NAME }} --version ${{ needs.pack.outputs.NUGET_VERSION }} + + dotnet run + + nuget-push: + runs-on: windows-latest + needs: test + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download package + uses: actions/download-artifact@v4 + with: + name: ${{ env.PACKAGES_DIR }} + path: ${{ env.PACKAGES_DIR }} + + - name: Install .NET SDK + uses: actions/setup-dotnet@3e891b0cb619bf60e2c25674b222b8940e2c1c25 #v4 + with: + dotnet-version: 6.0.X + + - name: NuGet push + run: | + cd ${{ env.PACKAGES_DIR }} + dotnet nuget push *.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/build-profiling-ffi.sh b/build-profiling-ffi.sh index 46094b4d1..f1401270f 100755 --- a/build-profiling-ffi.sh +++ b/build-profiling-ffi.sh @@ -17,18 +17,20 @@ set -eu ARG_FEATURES="" run_tests=true +target="" usage() { - echo "Usage: `basename "$0"` [-h] [-f FEATURES] [-T] dest-dir" + echo "Usage: `basename "$0"` [-h] [-f FEATURES] [-T] [-t TARGET] dest-dir" echo echo "Options:" echo " -h This help text" echo " -f FEATURES Enable specified features (comma separated if more than one)" echo " -T Skip checks after building" + echo " -t TARGET Specify the target platform" exit $1 } -while getopts f:hT flag +while getopts f:hTt: flag do case "${flag}" in f) @@ -43,6 +45,11 @@ do run_tests=false shift ;; + t) + target=${OPTARG} + shift + shift + ;; esac done @@ -59,7 +66,10 @@ 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 }')" +if [ -z "${target:-}" ]; then + target="$(rustc -vV | awk '/^host:/ { print $2 }')" +fi +echo "Building for target: $target" shared_library_suffix=".so" static_library_suffix=".a" library_prefix="lib" @@ -77,7 +87,7 @@ symbolizer=0 # 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") + "x86_64-alpine-linux-musl"|"aarch64-alpine-linux-musl"|"x86_64-unknown-linux-musl"|"aarch64-unknown-linux-musl") expected_native_static_libs=" -lssp_nonshared -lgcc_s -lc" native_static_libs=" -lssp_nonshared -lc" # on alpine musl, Rust adds some weird runpath to cdylibs diff --git a/nuget.config b/nuget.config new file mode 100644 index 000000000..8b9945591 --- /dev/null +++ b/nuget.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/nuget_package/Program.cs b/tests/nuget_package/Program.cs new file mode 100644 index 000000000..1f9c63d58 --- /dev/null +++ b/tests/nuget_package/Program.cs @@ -0,0 +1,279 @@ +// See https://aka.ms/new-console-template for more information + +using System; +using System.Runtime.InteropServices; + +class Program +{ + public static int Main(string[] args) + { + var url = new CharSlice("http://localhost:8126"); + var tracerVersion = new CharSlice("1.0.0"); + var language = new CharSlice(".NET"); + var languageVersion = new CharSlice("5.0.0"); + var languageInterpreter = new CharSlice(".NET"); + var hostname = new CharSlice("localhost"); + var env = new CharSlice("development"); + var service = new CharSlice("dotnet-test"); + var serviceVersion = new CharSlice("1.0.0"); + + Console.WriteLine("Creating config"); + Native.ddog_trace_exporter_config_new(out var config); + Console.WriteLine("Config created"); + + Console.WriteLine("Setting config values"); + SetConfig(config, url, Native.ddog_trace_exporter_config_set_url); + SetConfig(config, tracerVersion, Native.ddog_trace_exporter_config_set_tracer_version); + SetConfig(config, tracerVersion, Native.ddog_trace_exporter_config_set_tracer_version); + SetConfig(config, language, Native.ddog_trace_exporter_config_set_language); + SetConfig(config, languageVersion, Native.ddog_trace_exporter_config_set_lang_version); + SetConfig(config, languageInterpreter, Native.ddog_trace_exporter_config_set_lang_interpreter); + SetConfig(config, hostname, Native.ddog_trace_exporter_config_set_hostname); + SetConfig(config, env, Native.ddog_trace_exporter_config_set_env); + SetConfig(config, service, Native.ddog_trace_exporter_config_set_service); + SetConfig(config, serviceVersion, Native.ddog_trace_exporter_config_set_version); + Console.WriteLine("Config values set"); + + var newError = Native.ddog_trace_exporter_new(out var handle, config); + if (newError != IntPtr.Zero) + { + Console.WriteLine("Error creating exporter"); + var error = GetError(newError); + Console.WriteLine(error.Value.Code); + Console.WriteLine(error.Value.ToString()); + Native.ddog_trace_exporter_config_free(config); + return -1; + } + + Console.WriteLine("Exporter created"); + + Console.WriteLine("Sending traces"); + var traces = new byte[] + { + 0x90 + }; + + // pin traces + var traceSlice = new ByteSlice + { + Ptr = Marshal.UnsafeAddrOfPinnedArrayElement(traces, 0), + Len = (UIntPtr)traces.Length, + }; + var traceCount = (UIntPtr)1; + + var responsePtr = IntPtr.Zero; + var sendError = Native.ddog_trace_exporter_send(handle, traceSlice, traceCount, ref responsePtr); + if (sendError != IntPtr.Zero) + { + Console.WriteLine("Error sending traces"); + var error = GetError(sendError); + Console.WriteLine(error.Value.Code); + Console.WriteLine(error.Value.ToString()); + Native.ddog_trace_exporter_error_free(sendError); + + // this is expected when agent is not running + if (error.Value.Code != TraceExporterError.ErrorCode.IoError) + { + return -1; + } + } + + if (sendError == IntPtr.Zero) + { + // marshal the response struct + var response = Marshal.PtrToStructure(responsePtr); + Console.WriteLine("Response rate: " + response.Rate); + } + + Console.WriteLine("Traces sent"); + + Console.WriteLine("Freeing exporter"); + Native.ddog_trace_exporter_free(handle); + Console.WriteLine("Exporter freed"); + Console.WriteLine("Done"); + return 0; + } + + static TraceExporterError? GetError(IntPtr errorPtr) + { + if (errorPtr == IntPtr.Zero) + return null; + + return Marshal.PtrToStructure(errorPtr); + } + + static void SetConfig(IntPtr config, CharSlice value, Func setter) + { + Console.WriteLine("Setting config value for " + value); + var error = setter(config, value); + + if (error == IntPtr.Zero) + { + return; + } + + // marshal the error struct + var errorStruct = Marshal.PtrToStructure(error); + Console.WriteLine("Error setting config value: " + errorStruct); + Native.ddog_trace_exporter_error_free(error); + } + + internal enum TraceExporterInputFormat + { + Proxy = 0, + V04 = 1, + } + + internal enum TraceExporterOutputFormat + { + V04 = 0, + V07 = 1, + } + + internal static class Native + { + private const string DllName = "datadog_profiling_ffi"; + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void ddog_trace_exporter_error_free(IntPtr error); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void ddog_trace_exporter_config_new(out IntPtr outHandle); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void ddog_trace_exporter_config_free(IntPtr handle); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_url(IntPtr config, CharSlice url); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_tracer_version(IntPtr config, CharSlice version); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_language(IntPtr config, CharSlice lang); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_lang_version(IntPtr config, CharSlice version); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_lang_interpreter(IntPtr config, + CharSlice interpreter); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_hostname(IntPtr config, CharSlice hostname); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_env(IntPtr config, CharSlice env); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_version(IntPtr config, CharSlice version); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_config_set_service(IntPtr config, CharSlice service); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_new(out IntPtr outHandle, IntPtr config); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void ddog_trace_exporter_free(IntPtr handle); + + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr ddog_trace_exporter_send(IntPtr handle, ByteSlice trace, UIntPtr traceCount, + ref IntPtr response); + } + + [StructLayout(LayoutKind.Sequential)] + internal struct AgentResponse + { + internal double Rate; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ByteSlice + { + internal IntPtr Ptr; + internal UIntPtr Len; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct CharSlice + { + internal IntPtr Ptr; + internal UIntPtr Len; + + internal CharSlice(string str) + { + var bytes = System.Text.Encoding.UTF8.GetBytes(str); + Ptr = Marshal.AllocHGlobal(bytes.Length); + Marshal.Copy(bytes, 0, Ptr, bytes.Length); + Len = (UIntPtr)bytes.Length; + } + } + +/* + * typedef struct ddog_TraceExporterError { + enum ddog_TraceExporterErrorCode code; + char *msg; + } ddog_TraceExporterError; + */ + [StructLayout(LayoutKind.Sequential)] + internal struct TraceExporterError + { + internal ErrorCode Code; + internal IntPtr Msg; + + internal enum ErrorCode + { + AddressInUse = 0, + ConnectionAborted = 1, + ConnectionRefused = 2, + ConnectionReset = 3, + HttpBodyFormat = 4, + HttpBodyTooLong = 5, + HttpClient = 6, + HttpParse = 7, + HttpServer = 8, + HttpUnknown = 9, + HttpWrongStatus = 10, + InvalidArgument = 11, + InvalidData = 12, + InvalidInput = 13, + InvalidUrl = 14, + IoError = 15, + NetworkUnknown = 16, + Serde = 17, + TimedOut = 18, + } + + public override string ToString() + { + return IntPtrExtension.ToUtf8String(Msg); + } + } + + class IntPtrExtension + { + public static string ToUtf8String(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + { + return string.Empty; + } + + var len = 0; + while (Marshal.ReadByte(ptr, len) != 0) + { + len++; + } + + if (len == 0) + { + return string.Empty; + } + + var buffer = new byte[len]; + Marshal.Copy(ptr, buffer, 0, buffer.Length); + return System.Text.Encoding.UTF8.GetString(buffer); + } + } +} \ No newline at end of file diff --git a/tests/nuget_package/nuget_package.csproj b/tests/nuget_package/nuget_package.csproj new file mode 100644 index 000000000..679e0dd9d --- /dev/null +++ b/tests/nuget_package/nuget_package.csproj @@ -0,0 +1,15 @@ + + + + Exe + net6.0 + enable + enable + 8.0 + disable + + + + + + diff --git a/windows/README.md b/windows/README.md new file mode 100644 index 000000000..5d521634c --- /dev/null +++ b/windows/README.md @@ -0,0 +1,67 @@ +# libdatadog + +## About + +This package is binary distribution of [libdatadog](https://github.com/DataDog/libdatadog). It supports both native (C/C++) and .NET projects. + +## Getting started + +### Native (C/C++) projects + +For Native projects, `libdatadog` supports both static and dynamic linking. The dynamic linking is the default option. To use the static linking, you need to disable the dynamic linking by setting the msbuild property `LibDatadogDynamicLink` to `false`. Both `debug` and `release` congfiguration libraries are provided to allow better debugging experience. + +Depending on the target platform, binaries are compied to project output directory. + +### .NET projects + +For .NET projects, `libdatadog` supports only dynamic linking targetting .NET Standard 2.0. + +Depending on the target platform, binaries are copied to project output directory under `runtimes` directory as per [.NET conventions](https://learn.microsoft.com/en-us/nuget/create-packages/native-files-in-net-packages#native-assets) (`runtimes/{RID}/native`). + +> [!IMPORTANT] +> `nuget` fails to resolve the shared library if same directory is not used in the nuget package and the project output directory. Hence, only `release` configuration is supported for .NET projects. + +## Package content + +``` +libdatadog.14.3.1-ci.771.90/ +├── build +│   ├── native +│   │   ├── lib +│   │   │   ├── x64 +│   │   │   │   ├── debug +│   │   │   │   │   ├── libdatadog win-x64 shared library and pdb (debug) +│   │   │   │   │   └── static +│   │   │   │   │   └── libdatadog win-x64 static library (debug) +│   │   │   │   └── release +│   │   │   │   ├── libdatadog win-x64 shared library and pdb (release) +│   │   │   │   └── static +│   │   │   │   └── libdatadog win-x64 static library (release) +│   │   │   └── x86 +│   │   │   ├── debug +│   │   │   │   ├── libdatadog win-x86 shared library and pdb (debug) +│   │   │   │   └── static +│   │   │   │   └── libdatadog win-x86 static library (debug) +│   │   │   └── release +│   │   │   ├── libdatadog win-x86 shared library and pdb (release) +│   │   │   └── static +│   │   │   └── libdatadog win-x86 static library (release) +│   │   └── libdatadog.props +│   └── netstandard2.0 +│   └── libdatadog.props +├── include +│   └── native +│   └── datadog +│   ├── C headers +└── runtimes + ├── win-x64 + │   └── native + │   └── libdatadog win-x64 shared library and pdb + └── win-x86 + └── native + └── libdatadog win-x86 shared library and pdb +``` + +## License + +Apache-2.0 \ No newline at end of file diff --git a/windows/build-artifacts.ps1 b/windows/build-artifacts.ps1 index a6d3b80dd..a7dbcca22 100644 --- a/windows/build-artifacts.ps1 +++ b/windows/build-artifacts.ps1 @@ -9,11 +9,17 @@ function Invoke-Call { } $output_dir = $args[0] +$target = $args[1] if ([string]::IsNullOrEmpty($output_dir)) { throw "You must specify an output directory. Ex: $($myInvocation.InvocationName) my_rust_project/ bin" } +$targets = @("i686-pc-windows-msvc", "x86_64-pc-windows-msvc") +if (![string]::IsNullOrEmpty($target)) { + $targets = @($target) +} + if (![System.IO.Path]::IsPathRooted($output_dir)) { $output_dir = [System.IO.Path]::Combine($(Get-Location), $output_dir) } @@ -32,10 +38,10 @@ $features = @( Write-Host "Building for features: $features" -ForegroundColor Magenta pushd profiling-ffi -Invoke-Call -ScriptBlock { cargo build --features $features --target i686-pc-windows-msvc --release --target-dir $output_dir } -Invoke-Call -ScriptBlock { cargo build --features $features --target i686-pc-windows-msvc --target-dir $output_dir } -Invoke-Call -ScriptBlock { cargo build --features $features --target x86_64-pc-windows-msvc --release --target-dir $output_dir } -Invoke-Call -ScriptBlock { cargo build --features $features --target x86_64-pc-windows-msvc --target-dir $output_dir } +foreach ($target in $targets) { + Invoke-Call -ScriptBlock { cargo build --features $features --target $target --release --target-dir $output_dir } + Invoke-Call -ScriptBlock { cargo build --features $features --target $target --target-dir $output_dir } +} popd Write-Host "Building tools" -ForegroundColor Magenta diff --git a/windows/build-artifacts.sh b/windows/build-artifacts.sh new file mode 100755 index 000000000..549651bd9 --- /dev/null +++ b/windows/build-artifacts.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ +# SPDX-License-Identifier: Apache-2.0 + +set -e + +output_dir=$1 +target=$2 + +if [ -z "$output_dir" ]; then + echo "You must specify an output directory. Ex: $0 my_rust_project/ bin" + exit 1 +fi + +targets=("i686-pc-windows-msvc" "x86_64-pc-windows-msvc") +if [ -n "$target" ]; then + targets=("$target") +fi + +if [[ "$output_dir" != /* ]]; then + output_dir=$(pwd)/"$output_dir" +fi + +echo -e "Building project into $output_dir" + +features="data-pipeline-ffi,datadog-profiling-ffi/crashtracker-collector,datadog-profiling-ffi/crashtracker-receiver,datadog-profiling-ffi/ddtelemetry-ffi,datadog-profiling-ffi/demangler" + +echo -e "Building for features: $features" + +pushd profiling-ffi > /dev/null +for target in "${targets[@]}"; do + cargo build --features "$features" --target "$target" --release --target-dir "$output_dir" + cargo build --features "$features" --target "$target" --target-dir "$output_dir" +done +popd > /dev/null + +echo -e "Building tools" +cd tools +cargo build --release +cd .. + +echo -e "Generating headers" +cbindgen --crate ddcommon-ffi --config ddcommon-ffi/cbindgen.toml --output "$output_dir/common.h" +cbindgen --crate datadog-profiling-ffi --config profiling-ffi/cbindgen.toml --output "$output_dir/profiling.h" +cbindgen --crate ddtelemetry-ffi --config ddtelemetry-ffi/cbindgen.toml --output "$output_dir/telemetry.h" +cbindgen --crate data-pipeline-ffi --config data-pipeline-ffi/cbindgen.toml --output "$output_dir/data-pipeline.h" +cbindgen --crate datadog-crashtracker-ffi --config crashtracker-ffi/cbindgen.toml --output "$output_dir/crashtracker.h" +./target/release/dedup_headers "$output_dir/common.h" "$output_dir/profiling.h" "$output_dir/telemetry.h" "$output_dir/data-pipeline.h" "$output_dir/crashtracker.h" + +echo -e "Build finished" diff --git a/windows/libdatadog.csproj b/windows/libdatadog.csproj index 8de12382c..e3eaf9fcd 100644 --- a/windows/libdatadog.csproj +++ b/windows/libdatadog.csproj @@ -23,9 +23,10 @@ true - + - + + @@ -38,7 +39,7 @@ - @@ -72,6 +73,42 @@ + Pack="true" PackagePath="build\native\lib\x86\release\datadog_profiling_ffi.pdb" /> --> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/windows/libdatadog.props b/windows/libdatadog.props index 41474ea3c..4fcdf5cc5 100644 --- a/windows/libdatadog.props +++ b/windows/libdatadog.props @@ -50,4 +50,4 @@ Importance="high" Condition="'@(FilesToDelete)' != ''" /> - \ No newline at end of file + diff --git a/windows/netstandard2.0/libdatadog.props b/windows/netstandard2.0/libdatadog.props new file mode 100644 index 000000000..d9e4740c8 --- /dev/null +++ b/windows/netstandard2.0/libdatadog.props @@ -0,0 +1,10 @@ + + + + + + runtimes\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + \ No newline at end of file