Skip to content
Merged
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
33 changes: 32 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,35 @@ jobs:
run: |
docker run --rm liblpm-go:ci

# Java bindings test
test-java-bindings:
name: Test Java Bindings
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build Java container
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile.java
push: false
load: true
tags: liblpm-java:ci
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run Java tests
run: |
docker run --rm liblpm-java:ci

# C# bindings test
test-csharp-bindings:
name: Test C# Bindings
Expand Down Expand Up @@ -339,7 +368,7 @@ jobs:
ci-summary:
name: CI Summary
runs-on: ubuntu-latest
needs: [build-and-test, test-cpp-bindings, test-go-bindings, test-csharp-bindings, test-lua-bindings, test-perl-bindings, test-php-bindings, test-python-bindings, code-quality]
needs: [build-and-test, test-cpp-bindings, test-go-bindings, test-java-bindings, test-csharp-bindings, test-lua-bindings, test-perl-bindings, test-php-bindings, test-python-bindings, code-quality]
if: always()

steps:
Expand All @@ -349,6 +378,7 @@ jobs:
echo "Build and test: ${{ needs.build-and-test.result }}"
echo "C++ bindings: ${{ needs.test-cpp-bindings.result }}"
echo "Go bindings: ${{ needs.test-go-bindings.result }}"
echo "Java bindings: ${{ needs.test-java-bindings.result }}"
echo "C# bindings: ${{ needs.test-csharp-bindings.result }}"
echo "Lua bindings: ${{ needs.test-lua-bindings.result }}"
echo "Perl bindings: ${{ needs.test-perl-bindings.result }}"
Expand All @@ -360,6 +390,7 @@ jobs:
if [[ "${{ needs.build-and-test.result }}" == "failure" ]] || \
[[ "${{ needs.test-cpp-bindings.result }}" == "failure" ]] || \
[[ "${{ needs.test-go-bindings.result }}" == "failure" ]] || \
[[ "${{ needs.test-java-bindings.result }}" == "failure" ]] || \
[[ "${{ needs.test-csharp-bindings.result }}" == "failure" ]] || \
[[ "${{ needs.test-lua-bindings.result }}" == "failure" ]] || \
[[ "${{ needs.test-perl-bindings.result }}" == "failure" ]] || \
Expand Down
104 changes: 15 additions & 89 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ option(WITH_DPDK_BENCHMARK "Build DPDK comparison benchmark" OFF)
option(WITH_EXTERNAL_LPM_BENCHMARK "Build benchmarks with external LPM libraries" OFF)
option(BUILD_GO_WRAPPER "Build Go wrapper and bindings" OFF)
option(BUILD_CPP_WRAPPER "Build C++ wrapper and bindings" OFF)
option(BUILD_JAVA_WRAPPER "Build Java wrapper and bindings" OFF)
option(BUILD_CSHARP_WRAPPER "Build C# wrapper and bindings" OFF)
option(BUILD_LUA_WRAPPER "Build Lua wrapper and bindings" OFF)
option(BUILD_PERL_WRAPPER "Build Perl wrapper and bindings" OFF)
Expand Down Expand Up @@ -329,96 +330,16 @@ if(BUILD_CPP_WRAPPER)
add_subdirectory(bindings/cpp)
endif()

# Python wrapper
if(BUILD_PYTHON_WRAPPER)
find_package(Python COMPONENTS Interpreter Development.Module)
find_program(CYTHON_EXECUTABLE NAMES cython cython3)
if(Python_FOUND AND CYTHON_EXECUTABLE)
message(STATUS "Found Python: ${Python_EXECUTABLE} (${Python_VERSION})")
message(STATUS "Found Cython: ${CYTHON_EXECUTABLE}")
add_subdirectory(bindings/python)
# Java wrapper
if(BUILD_JAVA_WRAPPER)
find_package(JNI)
find_package(Java COMPONENTS Development)
if(JNI_FOUND AND Java_FOUND)
message(STATUS "Found JNI: ${JNI_INCLUDE_DIRS}")
message(STATUS "Found Java: ${Java_VERSION}")
add_subdirectory(bindings/java)
else()
if(NOT Python_FOUND)
message(WARNING "Python not found, skipping Python bindings")
endif()
if(NOT CYTHON_EXECUTABLE)
message(WARNING "Cython not found, skipping Python bindings. Install with: pip install cython")
endif()
endif()
endif()

# Package configuration for find_package(liblpm)
include(CMakePackageConfigHelpers)

# Generate version file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/liblpmConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)

# Generate config file from template
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/liblpmConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/liblpmConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/liblpm
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
)

# Install CMake config files (devel component)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/liblpmConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/liblpmConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/liblpm
COMPONENT devel
)

# Export targets (devel component)
install(EXPORT liblpmTargets
FILE liblpmTargets.cmake
NAMESPACE liblpm::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/liblpm
COMPONENT devel
)

# Go wrapper
if(BUILD_GO_WRAPPER)
find_program(GO_EXECUTABLE go)
if(GO_EXECUTABLE)
message(STATUS "Found Go: ${GO_EXECUTABLE}")

# Custom target to build Go wrapper
add_custom_target(go_wrapper ALL
COMMAND ${CMAKE_COMMAND} -E echo "Building Go wrapper..."
COMMAND ${GO_EXECUTABLE} build ./...
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/go
DEPENDS lpm
COMMENT "Building Go wrapper and bindings"
)

# Custom target to test Go wrapper
add_custom_target(go_test
COMMAND ${GO_EXECUTABLE} test -v ./liblpm/
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/go
DEPENDS go_wrapper
COMMENT "Testing Go wrapper"
)

# Custom target to run Go benchmarks
add_custom_target(go_bench
COMMAND ${GO_EXECUTABLE} test -bench=. -benchmem ./benchmarks/
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/go
DEPENDS go_wrapper
COMMENT "Running Go benchmarks"
)

message(STATUS "Go wrapper targets added:")
message(STATUS " make go_wrapper - Build Go wrapper")
message(STATUS " make go_test - Run Go tests")
message(STATUS " make go_bench - Run Go benchmarks")
else()
message(WARNING "Go not found. Go wrapper will not be built.")
message(WARNING "Install Go to build the wrapper: sudo apt install golang-go")
message(WARNING "Java JDK or JNI not found, skipping Java bindings")
endif()
endif()

Expand Down Expand Up @@ -656,6 +577,11 @@ if(BUILD_CPP_WRAPPER)
else()
message(STATUS " Build C++ wrapper: OFF")
endif()
if(BUILD_JAVA_WRAPPER AND JNI_FOUND)
message(STATUS " Build Java wrapper: ON")
else()
message(STATUS " Build Java wrapper: OFF")
endif()
if(BUILD_CSHARP_WRAPPER AND DOTNET_EXECUTABLE)
message(STATUS " Build C# wrapper: ON")
else()
Expand Down
16 changes: 16 additions & 0 deletions bindings/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,25 @@ install(TARGETS lpm_cpp lpm_cpp_impl
EXPORT liblpmCppTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Export targets
# Note: When building as part of the main project, the lpm target needs to be
# included in this export set to satisfy CMake's dependency tracking.
# Only install if lpm is a real target, not an IMPORTED target.
if(TARGET lpm)
get_target_property(lpm_type lpm TYPE)
get_target_property(lpm_imported lpm IMPORTED)
if(NOT lpm_imported)
# lpm is a local (non-imported) target, include it in the export
install(TARGETS lpm
EXPORT liblpmCppTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()
endif()

install(EXPORT liblpmCppTargets
FILE liblpmCppTargets.cmake
NAMESPACE liblpm::
Expand Down
22 changes: 22 additions & 0 deletions bindings/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Gradle
.gradle/
build/
!gradle/wrapper/gradle-wrapper.jar

# IDE
.idea/
*.iml
.vscode/

# Native build
build/
*.so
*.dylib
*.dll

# Test outputs
test-results/
reports/

# Local configuration
local.properties
Loading
Loading