From b76ccc3ab56dd606d6f829abcb5f6225c51d982a Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 22 Aug 2024 08:50:29 -0700 Subject: [PATCH] [build] cmake: Include our own copy of protobuf_generate to use with plugin (#6989) The hacks we needed to do to get the existing commands required cmake 3.28. We didn't want that, so just make a local slimmed down copy of the function just for our use. Even better, its much simpler in what it does, no weird hacks. --- cmake/modules/WpiProtobuf.cmake | 92 +++++++++++++++++++++++++++++++++ wpimath/CMakeLists.txt | 12 ++--- 2 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 cmake/modules/WpiProtobuf.cmake diff --git a/cmake/modules/WpiProtobuf.cmake b/cmake/modules/WpiProtobuf.cmake new file mode 100644 index 0000000000..6fc6cad1fd --- /dev/null +++ b/cmake/modules/WpiProtobuf.cmake @@ -0,0 +1,92 @@ +function(wpi_protobuf_generate) + set(_singleargs PROTOC_OUT_DIR PLUGIN DEPENDENCIES) + if(COMMAND target_sources) + list(APPEND _singleargs TARGET) + endif() + set(_multiargs PROTOS) + + cmake_parse_arguments( + wpi_protobuf_generate + "${_options}" + "${_singleargs}" + "${_multiargs}" + "${ARGN}" + ) + + if(NOT wpi_protobuf_generate_PROTOS) + message(SEND_ERROR "Error: protobuf_generate called without any targets or source files") + return() + endif() + + if(NOT wpi_protobuf_generate_TARGET) + message(SEND_ERROR "Error: wpi_protobuf_generate called without a target") + return() + endif() + + if(NOT wpi_protobuf_generate_PROTOC_OUT_DIR) + message(SEND_ERROR "Error: protobuf_generate called without a protoc out directory") + return() + endif() + + if(NOT wpi_protobuf_generate_PLUGIN) + message(SEND_ERROR "Error: wpi_protobuf_generate called without a plugin") + return() + endif() + + set(_generate_extensions .pb.h .pb.cc) + + # Create an include path for each file specified + foreach(_file ${wpi_protobuf_generate_PROTOS}) + get_filename_component(_abs_file ${_file} ABSOLUTE) + get_filename_component(_abs_dir ${_abs_file} DIRECTORY) + list(FIND _protobuf_include_path ${_abs_dir} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${_abs_dir}) + endif() + endforeach() + + set(_generated_srcs_all) + foreach(_proto ${wpi_protobuf_generate_PROTOS}) + 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}) + + set(_possible_rel_dir) + + set(_generated_srcs) + foreach(_ext ${_generate_extensions}) + list( + APPEND + _generated_srcs + "${wpi_protobuf_generate_PROTOC_OUT_DIR}/${_possible_rel_dir}${_basename}${_ext}" + ) + endforeach() + + list(APPEND _generated_srcs_all ${_generated_srcs}) + + set(_comment "Running WPILib protocol buffer compiler on ${_proto}") + + add_custom_command( + OUTPUT ${_generated_srcs} + COMMAND protobuf::protoc + ARGS + --cpp_out ${wpi_protobuf_generate_PROTOC_OUT_DIR} --wpilib_out + ${wpi_protobuf_generate_PROTOC_OUT_DIR} + --plugin=protoc-gen-wpilib=${wpi_protobuf_generate_PLUGIN} ${_protobuf_include_path} + ${_abs_file} + DEPENDS + ${_abs_file} + protobuf::protoc + ${wpi_protobuf_generate_DEPENDENCIES} + ${wpi_protobuf_generate_PLUGIN} + COMMENT ${_comment} + VERBATIM + ) + endforeach() + + set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) + if(wpi_protobuf_generate_TARGET) + target_sources(${wpi_protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all}) + endif() +endfunction() diff --git a/wpimath/CMakeLists.txt b/wpimath/CMakeLists.txt index 82cd541a81..de2dc48ea7 100644 --- a/wpimath/CMakeLists.txt +++ b/wpimath/CMakeLists.txt @@ -4,6 +4,7 @@ include(SubDirList) include(CompileWarnings) include(AddTest) include(DownloadAndCheck) +include(WpiProtobuf) # workaround for makefiles - for some reason parent directories aren't created. file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/protobuf") @@ -127,15 +128,12 @@ target_link_libraries(protobuf wpiutil) add_library(wpimath ${wpimath_native_src} $) -protobuf_generate( - TARGET protobuf +wpi_protobuf_generate( + TARGET + protobuf PROTOS ${wpimath_proto_src} - PLUGIN "protoc-gen-wpilib=${PROTOC_WPILIB_PLUGIN}" - PROTOC_OPTIONS "--cpp_out=${CMAKE_CURRENT_BINARY_DIR}/protobuf" # Needed to generate C++ source + PLUGIN ${PROTOC_WPILIB_PLUGIN} PROTOC_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf" - GENERATE_EXTENSIONS ".pb.h" ".pb.cc" # Enables CMake to add the generated sources to the target - LANGUAGE wpilib # Adds a --wpilib_out arg to let our plugin modify the generated protobuf code - APPEND_PATH ) if(MSVC)