Skip to content
Closed
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
574 changes: 88 additions & 486 deletions .github/workflows/actions.yml

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions .gitmodules
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
[submodule "libddwaf"]
path = libddwaf
url = https://github.com/DataDog/libddwaf.git
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,6 +9,8 @@ else()
message(FATAL_ERROR "Found JNI: failed")
endif()

add_subdirectory(deps EXCLUDE_FROM_ALL)

find_package(libddwaf REQUIRED)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand DownExpand Up@@ -36,8 +38,6 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
-Wno-implicit-fallthrough -Wno-gnu-auto-type -Wno-c++98-compat)
endif()

add_subdirectory(deps EXCLUDE_FROM_ALL)

set(SOURCE_FILES
src/main/c/base64.c
src/main/c/byte_buffer.c
Expand Down
85 changes: 41 additions & 44 deletions README.md
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,69 @@
# Introduction
# libddwaf-java

This project provides Java bindings for [libddwaf][libddwaf_repos] through JNI.
Currently supported runtimes are Linux (GNU and musl) and Windows amd64.
## Overview

# Build instructions
This project provides Java bindings for [libddwaf](https://github.com/DataDog/libddwaf) through JNI. There are 3 components:

Gradle is used to build the Java component, and CMake to build the native
components. Three components need to be built separately:
* libddwaf itself
* libsqreen\_jni, the JNI binding (native side), uses cmake
* a jar with the Java API, uses gradle

* libddwaf needs to be built and installed.
* Then the JNI binding (named libsqreen\_jni, for historical reasons).
* Finally the jar can be built with Gradle.
## Build

A jar for release purposes needs to have both the libddwaf and libsqreen
binaries for all the supported runtime environments. These are included inside
the JAR. For Linux, a shared library build of libddwaf (libddwaf.so) is included
in JAR; this DSO is used in both musl and glibc systems. On Windows, there is
only one binary, which is linked against libddwaf built as a static library.
### Simple build

For testing purposes, Gradle can invoke a debug build of libsqreen\_jni. By
default, libddwaf CMake config files are searched in
`libddwaf/Debug/out/usr/local/share/cmake/libddwaf`.
To build the JNI bindings, you can run:

The binaries for inclusion in the final release jar have to be copied into the
`native_libs` directory. Then the jar can be built with `gradle build`.
```sh
# Build JNI bindings for local testing, uses cmake under the hood
./gradlew buildNativeLib --rerun-tasks

# Or, in recent macOS you might need to specify the architecture (x86_64, arm64):
./gradlew buildNativeLib --rerun-tasks -PmacArch=arm64
```

For development purposes, a debug build of libddwaf can be obtained with:
Then all tests can be run as follows:

```sh
cd libddwaf
mkdir Debug && cd Debug
cmake .. -DCMAKE_BUILD_TYPE=Debug
make -j
DESTDIR=out make install
cd ../..
./gradlew check
```

Then the jni lib can be built with `./gradlew buildNativeLibDebug --rerun-tasks`.

To build native libraries, recommended use `--rerun-tasks` option to enforce rebuild task, because of gradle can skip building tasks due caches and lead to unexpected results.
### Build with custom libddwaf

Tests are run with `./gradlew check`. This implicitly invokes
`buildNativeLibDebug` if needed.
By default, cmake will download the required libddwaf build for the current sysem and use it. In some cases, you may
want to use a custom libddwaf build. This is required to use an unreleased version of libddwaf or to use custom build
arguments (e.g. ASAN).

### On MacOS libddwaf can be built with:
So, here's an example building a debug version of libddwaf from master:

You can set MacOSX SDK version with `CMAKE_OSX_SYSROOT` option (13.3)
```sh
git clone git@github.com:DataDog/libddwaf.git
cd libddwaf
mkdir Debug && cd Debug
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk
cmake .. -DCMAKE_BUILD_TYPE=Debug
make -j
DESTDIR=out make install
cd ../..
```
If you need specify architecture (x86_64, arm64) with gradle parameter `macArch`

Then you can build the JNI bindings with the following command:

```sh
./gradlew buildNativeLibDebug --rerun-tasks -PmacArch=arm64
./gradlew buildNativeLib -PlibddwafPath=libddwaf/Debug/out/usr/local --rerun-tasks
```

### On Windows libddwaf can be built with:
## Release build

```sh
cd libddwaf
mkdir Debug && cd Debug
cmake .. -DCMAKE_INSTALL_PREFIX=out\usr\local -A x64 -DCMAKE_BUILD_TYPE=Debug
cmake --build . --target install -j --config Debug
A jar for release purposes needs to have both the libddwaf and libsqreen
binaries for all the supported runtime environments. These are included inside
the JAR. For Linux, a shared library build of libddwaf (libddwaf.so) is included
in JAR; this DSO is used in both musl and glibc systems. On Windows, there is
only one binary, which is linked against libddwaf built as a static library.

```
The binaries for inclusion in the final release jar have to be copied into the
`build/native_libs` directory. Then the jar can be built with `gradle build`.

To build native libraries, recommended use `--rerun-tasks` option to enforce rebuild task, because of gradle can skip building tasks due caches and lead to unexpected results.

Tests in reease mode are run with `./gradlew check -Prelease`.

[libddwaf_repos]: https://github.com/DataDog/libddwaf
80 changes: 38 additions & 42 deletions build.gradle
Original file line numberDiff line numberDiff line change
Expand Up@@ -38,73 +38,69 @@ targetCompatibility = 1.8

def WINDOWS = org.gradle.internal.os.OperatingSystem.current().windows
def MACOS = org.gradle.internal.os.OperatingSystem.current().macOsX
def IS_RELEASE = project.hasProperty("release")
def cmakeBuildDir = IS_RELEASE? "$buildDir/RelWithDebInfo" : "$buildDir/Debug"

task cmakeNativeLibDebug(type: Exec) {
task cmakeNativeLib(type: Exec) {
outputs.upToDateWhen { false }
description = 'Runs cmake in a debug configuration'

def pwafConfDir = project.hasProperty('libddwafConfig') ?
project.libddwafConfig :
"$projectDir/libddwaf/Debug/out/usr/local/share/cmake/libddwaf"
description = 'Runs cmake'

doFirst {
def f = file("$pwafConfDir/libddwaf-config-debug.cmake")
if (!f.exists()) {
logger.warn("The file $f does not exist. libddwaf debug must be installed globally. " +
"Run with -PlibddwafConfig=/path/to/dir/of/libddwaf-config-debug.cmake to override")
}

file("$buildDir/Debug").mkdirs()
file(cmakeBuildDir).mkdirs()
}

inputs.file 'CMakeLists.txt'
outputs.dir "$buildDir/Debug/"
outputs.dir cmakeBuildDir
workingDir cmakeBuildDir

logging.captureStandardError LogLevel.ERROR
logging.captureStandardOutput LogLevel.INFO

def cmakeOpts
def cmakeOpts = []
if (project.hasProperty('withASAN')) {
cmakeOpts = [
cmakeOpts += [
'-DCMAKE_C_COMPILER=clang',
'-DCMAKE_CXX_COMPILER=clang++',
'-DCMAKE_C_FLAGS=-fsanitize=address -fsanitize=undefined -fsanitize=leak --coverage',
'-DCMAKE_SHARED_LINKER_FLAGS=-fsanitize=address -fsanitize=undefined -fsanitize=leak -lubsan -lasan --coverage',
]
if (WINDOWS) {
logger.warn('Address sanitizer not supported on Windows')
}
} else {
cmakeOpts = [
'-DCMAKE_C_FLAGS=--coverage',
'-DCMAKE_SHARED_LINKER_FLAGS=--coverage',
]
assert !WINDOWS, 'Address sanitizer not supported on Windows'
}

if (project.hasProperty('macArch')) {
cmakeOpts += ["-DCMAKE_OSX_ARCHITECTURES=${project.macArch}"]
}

if (WINDOWS) {
commandLine 'cmake', "-DCMAKE_PREFIX_PATH=$pwafConfDir", '-S', projectDir, '-B', '.'
if (IS_RELEASE) {
cmakeOpts += ["-DCMAKE_BUILD_TYPE=RelWithDebInfo"]
} else {
commandLine('cmake', '-DCMAKE_BUILD_TYPE=Debug', "-DCMAKE_PREFIX_PATH=$pwafConfDir",
*cmakeOpts, '-S', projectDir, '-B', '.')
cmakeOpts += [
'-DCMAKE_BUILD_TYPE=Debug',
'-DCMAKE_C_FLAGS=--coverage',
'-DCMAKE_SHARED_LINKER_FLAGS=--coverage',
]
}

cmakeOpts += ['-DCMAKE_C_FLAGS="-fno-omit-frame-pointer"']

if (project.hasProperty('libddwafPath')) {
cmakeOpts += ["-DLIBDDWAF_CUSTOM_DIR=${project.libddwafPath}"]
}

workingDir "$buildDir/Debug"
commandLine('cmake', *cmakeOpts, '-S', projectDir, '-B', '.')
}

task buildNativeLibDebug(type: Exec) {
description = 'Builds the native JNI lib in a debug configuration'
task buildNativeLib(type: Exec) {
description = 'Builds the native JNI lib'
group = 'test'

inputs.dir 'src/main/c'
if (WINDOWS) {
outputs.file "$buildDir/Debug/Debug/libsqreen_jni.dll"
outputs.file "$cmakeBuildDir/Debug/libsqreen_jni.dll"
} else if (MACOS) {
outputs.file "$buildDir/Debug/libsqreen_jni.dylib"
outputs.file "$cmakeBuildDir/libsqreen_jni.dylib"
} else {
outputs.file "$buildDir/Debug/libsqreen_jni.so"
outputs.file "$cmakeBuildDir/libsqreen_jni.so"
}

logging.captureStandardError LogLevel.ERROR
Expand All@@ -116,9 +112,9 @@ task buildNativeLibDebug(type: Exec) {
} else {
commandLine 'make', '-j', 'sqreen_jni', 'VERBOSE=1'
}
workingDir "$buildDir/Debug"
workingDir cmakeBuildDir

dependsOn cmakeNativeLibDebug
dependsOn cmakeNativeLib
}

jacocoTestReport {
Expand DownExpand Up@@ -159,7 +155,7 @@ task sourcesJar(type: Jar, dependsOn: classes) {
from sourceSets.main.allSource
}

def nativeLibsDir = "$projectDir/native_libs"
def nativeLibsDir = "$projectDir/build/native_libs"

task checkForNativeLibs {
doLast {
Expand DownExpand Up@@ -262,8 +258,8 @@ task copyNativeLibs(type: Copy) {
['linux/x86_64/musl/libsqreen_jni.so', 'linux/x86_64/libddwaf.so'],
['linux/aarch64/glibc/libsqreen_jni.so', 'linux/aarch64/libddwaf.so'],
['linux/aarch64/musl/libsqreen_jni.so', 'linux/aarch64/libddwaf.so'],
['macos/x86_64/libsqreen_jni.dylib', 'macos/x86_64/libddwaf.dylib.dwarf'],
['macos/aarch64/libsqreen_jni.dylib', 'macos/aarch64/libddwaf.dylib.dwarf'],
['macos/x86_64/libsqreen_jni.dylib', 'macos/x86_64/libddwaf.dylib'],
['macos/aarch64/libsqreen_jni.dylib', 'macos/aarch64/libddwaf.dylib'],
['windows/x86_64/sqreen_jni.dll']]

doFirst {
Expand DownExpand Up@@ -307,13 +303,13 @@ tasks.withType(Test).each {
}

it.jvmArgs += ['-Xcheck:jni', '-Dorg.slf4j.simpleLogger.defaultLogLevel=DEBUG', '-DPOWERWAF_EXIT_ON_LEAK=true']
if (project.hasProperty('useReleaseBinaries')) {
if (project.hasProperty('release')) {
it.jvmArgs += ['-DuseReleaseBinaries=true']
it.dependsOn copyNativeLibs
} else {
def javaLibPath = WINDOWS ? "$buildDir\\Debug\\Debug" : "$buildDir/Debug"
def javaLibPath = WINDOWS ? "$cmakeBuildDir\\Debug" : "$cmakeBuildDir"
it.jvmArgs += ["-Djava.library.path=$javaLibPath"]
it.dependsOn buildNativeLibDebug
it.dependsOn buildNativeLib
}

it.outputs.upToDateWhen { false }
Expand Down
1 change: 0 additions & 1 deletion ci/alpine-abuild-libc++/.gitignore

This file was deleted.

66 changes: 0 additions & 66 deletions ci/alpine-abuild-libc++/APKBUILD

This file was deleted.

26 changes: 0 additions & 26 deletions ci/alpine-abuild-libc++/Dockerfile

This file was deleted.

Loading