Files
allwpilib/wpimath/CMakeLists.txt
Peter Johnson cf54d9ccb7 [wpiutil, ntcore] Add structured data support (#5391)
This adds support for two serialization formats for complex data types:

- Protobuf for complex objects with variable length internals that need forward and backward wire compatibility (lower speed, more flexible)
- Raw struct (ByteBuffer-style) for fixed-length objects (higher speed, less flexible)

Deserialization can be done either by creating a new object (for immutable objects) or overwriting the contents of an existing object (for mutable objects).

Implementing classes should provide inner classes that implement the Protobuf or Struct interface (in Java) or specialize the wpi::Protobuf or wpi::Struct struct (in C++). It is possible for classes to implement both. If the class itself does not implement serialization, it's possible for third parties/users to provide an implementation instead.

Uses the Google protobuf implementation for C++ and the QuickBuffers alternative protobuf implementation for Java.
2023-10-19 21:41:47 -07:00

186 lines
7.8 KiB
CMake

project(wpimath)
include(SubDirList)
include(CompileWarnings)
include(AddTest)
include(DownloadAndCheck)
file(GLOB wpimath_proto_src src/main/proto/*.proto)
protobuf_generate_cpp(WPIMATH_PROTO_SRCS WPIMATH_PROTO_HDRS PROTOC_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf" PROTOS ${wpimath_proto_src})
function(quickbuf_generate SRCS JAVA_PACKAGE)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_QUICKBUF() called without any proto files")
return()
endif()
set(_generated_srcs_all)
foreach(_proto ${ARGN})
get_filename_component(_abs_file ${_proto} ABSOLUTE)
get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
get_filename_component(_basename ${_proto} NAME_WLE)
file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
# convert to QuickBuffers Java case (geometry2d -> Geometry2D)
string(REGEX MATCHALL "[A-Za-z_]+|[0-9]+" _name_components ${_basename})
set(_name_components_out)
foreach(_part ${_name_components})
string(SUBSTRING ${_part} 0 1 _first_letter)
string(TOUPPER ${_first_letter} _first_letter)
string(REGEX REPLACE "^.(.*)" "${_first_letter}\\1" _part_out "${_part}")
list(APPEND _name_components_out ${_part_out})
endforeach()
list(JOIN _name_components_out "" _basename_title)
set(_generated_src "${CMAKE_CURRENT_BINARY_DIR}/quickbuf/${JAVA_PACKAGE}/${_basename_title}.java")
list(APPEND _generated_srcs_all ${_generated_src})
add_custom_command(
OUTPUT ${_generated_src}
COMMAND protobuf::protoc
ARGS --plugin=protoc-gen-quickbuf=${Quickbuf_EXECUTABLE} --quickbuf_out=gen_descriptors=true:${CMAKE_CURRENT_BINARY_DIR}/quickbuf -I${_abs_dir} ${_abs_file}
DEPENDS ${_abs_file} protobuf::protoc
COMMENT "Running quickbuf protocol buffer compiler on ${_proto}"
VERBATIM )
endforeach()
set(${SRCS} ${_generated_srcs_all} PARENT_SCOPE)
endfunction()
file(GLOB wpimath_jni_src src/main/native/cpp/jni/WPIMathJNI_DARE.cpp
src/main/native/cpp/jni/WPIMathJNI_Eigen.cpp
src/main/native/cpp/jni/WPIMathJNI_Exceptions.cpp
src/main/native/cpp/jni/WPIMathJNI_Pose3d.cpp
src/main/native/cpp/jni/WPIMathJNI_StateSpaceUtil.cpp
src/main/native/cpp/jni/WPIMathJNI_Trajectory.cpp)
# Java bindings
if (WITH_JAVA)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava)
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
quickbuf_generate(WPIMATH_QUICKBUF_SRCS "edu/wpi/first/math/proto" ${wpimath_proto_src})
if(NOT EXISTS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/ejml-simple-0.43.1.jar")
set(BASE_URL "https://search.maven.org/remotecontent?filepath=")
set(JAR_ROOT "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml")
message(STATUS "Downloading EJML jarfiles...")
download_and_check("${BASE_URL}org/ejml/ejml-cdense/0.43.1/ejml-cdense-0.43.1.jar"
"${JAR_ROOT}/ejml-cdense-0.43.1.jar")
download_and_check("${BASE_URL}org/ejml/ejml-core/0.43.1/ejml-core-0.43.1.jar"
"${JAR_ROOT}/ejml-core-0.43.1.jar")
download_and_check("${BASE_URL}org/ejml/ejml-ddense/0.43.1/ejml-ddense-0.43.1.jar"
"${JAR_ROOT}/ejml-ddense-0.43.1.jar")
download_and_check("${BASE_URL}org/ejml/ejml-dsparse/0.43.1/ejml-dsparse-0.43.1.jar"
"${JAR_ROOT}/ejml-dsparse-0.43.1.jar")
download_and_check("${BASE_URL}org/ejml/ejml-fdense/0.43.1/ejml-fdense-0.43.1.jar"
"${JAR_ROOT}/ejml-fdense-0.43.1.jar")
download_and_check("${BASE_URL}org/ejml/ejml-simple/0.43.1/ejml-simple-0.43.1.jar"
"${JAR_ROOT}/ejml-simple-0.43.1.jar")
download_and_check("${BASE_URL}org/ejml/ejml-zdense/0.43.1/ejml-zdense-0.43.1.jar"
"${JAR_ROOT}/ejml-zdense-0.43.1.jar")
message(STATUS "All files downloaded.")
endif()
file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar")
file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar")
file(GLOB QUICKBUF_JAR
${WPILIB_BINARY_DIR}/wpiutil/thirdparty/quickbuf/*.jar)
set(CMAKE_JAVA_INCLUDE_PATH wpimath.jar ${EJML_JARS} ${JACKSON_JARS} ${QUICKBUF_JAR})
execute_process(COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/generate_numbers.py ${WPILIB_BINARY_DIR}/wpimath RESULT_VARIABLE generateResult)
if(NOT (generateResult EQUAL "0"))
# Try python
execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/generate_numbers.py ${WPILIB_BINARY_DIR}/wpimath RESULT_VARIABLE generateResult)
if(NOT (generateResult EQUAL "0"))
message(FATAL_ERROR "python and python3 generate_numbers.py failed")
endif()
endif()
set(CMAKE_JNI_TARGET true)
file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java ${WPILIB_BINARY_DIR}/wpimath/generated/*.java)
add_jar(wpimath_jar ${JAVA_SOURCES} ${WPIMATH_QUICKBUF_SRCS} INCLUDE_JARS ${EJML_JARS} wpiutil_jar OUTPUT_NAME wpimath GENERATE_NATIVE_HEADERS wpimath_jni_headers)
get_property(WPIMATH_JAR_FILE TARGET wpimath_jar PROPERTY JAR_FILE)
install(FILES ${WPIMATH_JAR_FILE} DESTINATION "${java_lib_dest}")
set_property(TARGET wpimath_jar PROPERTY FOLDER "java")
add_library(wpimathjni ${wpimath_jni_src})
wpilib_target_warnings(wpimathjni)
target_link_libraries(wpimathjni PUBLIC wpimath)
set_property(TARGET wpimathjni PROPERTY FOLDER "libraries")
target_link_libraries(wpimathjni PRIVATE wpimath_jni_headers)
add_dependencies(wpimathjni wpimath_jar)
install(TARGETS wpimathjni EXPORT wpimathjni)
endif()
file(GLOB_RECURSE wpimath_native_src src/main/native/cpp/*.cpp)
list(REMOVE_ITEM wpimath_native_src ${wpimath_jni_src})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS FALSE)
add_library(wpimath ${wpimath_native_src} ${WPIMATH_PROTO_SRCS})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set_target_properties(wpimath PROPERTIES DEBUG_POSTFIX "d")
set_property(TARGET wpimath PROPERTY FOLDER "libraries")
target_compile_definitions(wpimath PRIVATE WPILIB_EXPORTS)
target_compile_features(wpimath PUBLIC cxx_std_20)
if (MSVC)
target_compile_options(wpimath PUBLIC /bigobj)
endif()
wpilib_target_warnings(wpimath)
target_link_libraries(wpimath wpiutil)
if (NOT USE_SYSTEM_EIGEN)
install(DIRECTORY src/main/native/thirdparty/eigen/include/ DESTINATION "${include_dest}/wpimath")
target_include_directories(wpimath SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/thirdparty/eigen/include>
$<INSTALL_INTERFACE:${include_dest}/wpimath>)
else()
find_package(Eigen3 CONFIG REQUIRED)
target_link_libraries (wpimath Eigen3::Eigen)
endif()
install(DIRECTORY src/main/native/thirdparty/gcem/include/ DESTINATION "${include_dest}/wpimath")
target_include_directories(wpimath SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/thirdparty/gcem/include>)
install(DIRECTORY src/main/native/include/ DESTINATION "${include_dest}/wpimath")
target_include_directories(wpimath PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/protobuf>
$<INSTALL_INTERFACE:${include_dest}/wpimath>)
install(TARGETS wpimath EXPORT wpimath)
if (WITH_FLAT_INSTALL)
set (wpimath_config_dir ${wpilib_dest})
else()
set (wpimath_config_dir share/wpimath)
endif()
configure_file(wpimath-config.cmake.in ${WPILIB_BINARY_DIR}/wpimath-config.cmake )
install(FILES ${WPILIB_BINARY_DIR}/wpimath-config.cmake DESTINATION ${wpimath_config_dir})
install(EXPORT wpimath DESTINATION ${wpimath_config_dir})
if (WITH_TESTS)
wpilib_add_test(wpimath src/test/native/cpp)
target_include_directories(wpimath_test PRIVATE src/test/native/include)
target_link_libraries(wpimath_test wpimath gmock_main)
endif()