diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..137069a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,263 @@ +# CMakeLists.txt for the phaser project +# +# Builds the phaser runtime library, the protoc-gen-phaser protoc plugin, and +# provides phaser_add_library() to generate a C++ library from .proto files. +# +# A parent project that already provides Abseil (absl::*), cpp_toolbelt +# (toolbelt) and protobuf (protobuf::libprotoc, protobuf::protoc) targets is +# used as is. Missing dependencies are fetched with FetchContent. +# +# When cross-compiling, the plugin must run on the build host, so it is not +# built. Build it for the host separately and pass its path in +# PHASER_PLUGIN_EXECUTABLE. + +cmake_minimum_required(VERSION 3.15) +project(phaser LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if(CMAKE_CROSSCOMPILING) + set(PHASER_BUILD_COMPILER_DEFAULT OFF) +else() + set(PHASER_BUILD_COMPILER_DEFAULT ON) +endif() +option(PHASER_BUILD_COMPILER "Build the protoc-gen-phaser plugin" + ${PHASER_BUILD_COMPILER_DEFAULT}) +set(PHASER_PLUGIN_EXECUTABLE "" CACHE FILEPATH + "Host protoc-gen-phaser used when the plugin is not built here") + +include(FetchContent) + +if(NOT TARGET absl::base) + set(ABSL_PROPAGATE_CXX_STD ON) + # protobuf's install rules export targets that link Abseil. + set(ABSL_ENABLE_INSTALL ON) + FetchContent_Declare( + abseil + GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git + GIT_TAG 20250814.1 + ) + FetchContent_MakeAvailable(abseil) +endif() + +if(NOT TARGET toolbelt) + # Matches the cpp_toolbelt git_override in MODULE.bazel. + FetchContent_Declare( + cpp_toolbelt + GIT_REPOSITORY https://github.com/dallison/cpp_toolbelt.git + GIT_TAG 86b45cdd3da46a97a4476be2f2a61909677284a2 + ) + FetchContent_MakeAvailable(cpp_toolbelt) +endif() + +if(PHASER_BUILD_COMPILER AND NOT TARGET protobuf::libprotoc) + set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "") + FetchContent_Declare( + protobuf + GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git + GIT_TAG v34.1 + ) + FetchContent_MakeAvailable(protobuf) +endif() + +# --- Runtime library --- +add_library(phaser_runtime STATIC + phaser/runtime/md5.cc + phaser/runtime/message.cc + phaser/runtime/phaser_bank.cc +) +add_library(phaser::runtime ALIAS phaser_runtime) +target_include_directories(phaser_runtime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(phaser_runtime PUBLIC + absl::flat_hash_map + absl::status + absl::statusor + absl::strings + absl::str_format + absl::span + toolbelt +) + +# --- protoc plugin --- +if(PHASER_BUILD_COMPILER) + if(DEFINED protobuf_SOURCE_DIR) + set(PHASER_PROTOBUF_IMPORT_DIR "${protobuf_SOURCE_DIR}/src" CACHE PATH + "Directory containing google/protobuf/*.proto") + else() + set(PHASER_PROTOBUF_IMPORT_DIR "" CACHE PATH + "Directory containing google/protobuf/*.proto") + endif() + if(NOT PHASER_PROTOBUF_IMPORT_DIR) + message(FATAL_ERROR + "Set PHASER_PROTOBUF_IMPORT_DIR to the directory containing " + "google/protobuf/descriptor.proto") + endif() + + set(PHASER_OPTIONS_SRC "${CMAKE_CURRENT_BINARY_DIR}/phaser/options.pb.cc") + set(PHASER_OPTIONS_HDR "${CMAKE_CURRENT_BINARY_DIR}/phaser/options.pb.h") + add_custom_command( + OUTPUT ${PHASER_OPTIONS_SRC} ${PHASER_OPTIONS_HDR} + COMMAND $ + ARGS --cpp_out=${CMAKE_CURRENT_BINARY_DIR} + --proto_path=${CMAKE_CURRENT_SOURCE_DIR} + --proto_path=${PHASER_PROTOBUF_IMPORT_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/phaser/options.proto + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/phaser/options.proto protobuf::protoc + COMMENT "Generating C++ code from phaser/options.proto" + ) + + add_executable(protoc-gen-phaser + phaser/compiler/enum_gen.cc + phaser/compiler/gen.cc + phaser/compiler/main.cc + phaser/compiler/message_gen.cc + ${PHASER_OPTIONS_SRC} + ) + target_include_directories(protoc-gen-phaser PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) + target_link_libraries(protoc-gen-phaser PRIVATE + absl::flat_hash_map + absl::flat_hash_set + absl::status + absl::statusor + absl::strings + absl::str_format + protobuf::libprotoc + protobuf::libprotobuf + ) +endif() + +# phaser_add_library( +# PROTOS ... +# IMPORT_DIRS ... +# [IMPORTS ...] +# [PACKAGE ] +# [ADD_NAMESPACE ] +# [FRONTEND protobuf|ros] +# [PROTOC ] +# [PLUGIN ] +# [COMPILE_OPTIONS