Skip to content

Commit

Permalink
Add cpp language support
Browse files Browse the repository at this point in the history
Signed-off-by: Simone Orru <simone.orru@secomind.com>
  • Loading branch information
sorru94 committed Dec 24, 2024
1 parent 5ff0672 commit c8f5b65
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/check-code-generation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ jobs:
- name: Check the Python generated code
run: |
git --no-pager diff --no-index -- ./python-dist ./python/astarteplatform
- name: Check the C++ generated code
run: |
git --no-pager diff --no-index -- ./cpp-dist ./cpp/astarteplatform
5 changes: 4 additions & 1 deletion .github/workflows/code-generation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ jobs:
rust-code-generation:
needs: [ reuse ]
uses: ./.github/workflows/rust-code-generation.yaml
cpp-code-generation:
needs: [ reuse ]
uses: ./.github/workflows/cpp-code-generation.yaml
check-codegen:
needs: [ python-code-generation, rust-code-generation ]
needs: [ python-code-generation, rust-code-generation, cpp-code-generation ]
uses: ./.github/workflows/check-code-generation.yaml
rust-code-check:
needs: [ check-codegen ]
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/cpp-code-generation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This file is part of Astarte.
#
# Copyright 2023 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

name: C++ code generation

permissions:
contents: read

on:
workflow_call:

env:
PB_REL: https://github.com/protocolbuffers/protobuf/releases
PB_VER: '26.1'

jobs:
python-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install protoc
run: |
curl -LO $PB_REL/download/v$PB_VER/protoc-$PB_VER-linux-x86_64.zip
unzip protoc-$PB_VER-linux-x86_64.zip -d $HOME/.local
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install gRPC
run: |
export MY_INSTALL_DIR=$HOME/.local
sudo apt install -y build-essential autoconf libtool pkg-config
git clone --recurse-submodules --depth 1 --shallow-submodules -b v1.66.1 https://github.com/grpc/grpc
mkdir -p cmake/build
pushd cmake/build
cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR ../..
make -j 4
make install
popd
- name: Remove old code
working-directory: ./cpp
run: (! test -d ./astarteplatform) || rm -r ./astarteplatform
- name: Generate code
working-directory: ./cpp
run: |
mkdir -p ./cmake/build
pushd ./cmake/build
cmake ../..
make
popd
- name: Upload artifact with generated code
uses: actions/upload-artifact@v4
with:
name: cpp-dist
path: ./cpp/astarteplatform
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ target/
output/

.pre-commit-config.yaml

# CMake build directory
cmake/
22 changes: 21 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ CANONICAL_CURDIR = $(realpath $(CURDIR))
PROTO_DIR = $(CANONICAL_CURDIR)/proto
RUST_LANG_DIR = $(CANONICAL_CURDIR)/rust
PYTHON_LANG_DIR = $(CANONICAL_CURDIR)/python
CPP_LANG_DIR = $(CANONICAL_CURDIR)/cpp

BASE_DIR := $(CANONICAL_O)
$(if $(BASE_DIR),, $(error output directory "$(O)" does not exist))
Expand All @@ -39,6 +40,7 @@ DL_DIR := $(shell mkdir -p $(BASE_DIR)/dl >/dev/null 2>&1)$(BASE_DIR)/dl
BUILD_DIR := $(BASE_DIR)/build
RUST_BUILD_DIR := $(BUILD_DIR)/rust
PYTHON_BUILD_DIR := $(BUILD_DIR)/python
CPP_BUILD_DIR := $(BUILD_DIR)/python

FILES=$(wildcard proto/astarteplatform/msghub/*.proto)

Expand All @@ -50,9 +52,12 @@ RUST_CODEGEN_SCRIPT=$(CANONICAL_CURDIR)/scripts/rust_codegen.sh
PYTHON_LANG=$(PYTHON_BUILD_DIR)/astarteplatform
PYTHON_CODEGEN_SCRIPT=$(CANONICAL_CURDIR)/scripts/python_codegen.sh

CPP_LANG=$(CPP_BUILD_DIR)/astarteplatform
CPP_CODEGEN_SCRIPT=$(CANONICAL_CURDIR)/scripts/cpp_codegen.sh

# This is our default rule, so must come first
.PHONY: all
all : $(RUST_LANG) $(PYTHON_LANG)
all : $(RUST_LANG) $(PYTHON_LANG) $(CPP_LANG)

$(RUST_LANG): $(FILES) $(RUST_CODEGEN_SCRIPT)
mkdir -p $(RUST_BUILD_DIR)
Expand All @@ -62,6 +67,10 @@ $(PYTHON_LANG): $(FILES) $(PYTHON_CODEGEN_SCRIPT)
mkdir -p $(PYTHON_BUILD_DIR)
$(PYTHON_CODEGEN_SCRIPT) codegen $(PROTO_DIR) $(PYTHON_LANG_DIR) $(PYTHON_BUILD_DIR) $(DL_DIR)

$(CPP_LANG): $(FILES) $(CPP_CODEGEN_SCRIPT)
mkdir -p $(CPP_BUILD_DIR)
$(CPP_CODEGEN_SCRIPT) codegen $(PROTO_DIR) $(CPP_LANG_DIR) $(CPP_BUILD_DIR)

.PHONY: protoc-check
protoc-check: $(PROTOC_CHECK_SCRIPT)
$(PROTOC_CHECK_SCRIPT)
Expand All @@ -72,6 +81,9 @@ rust: protoc-check $(RUST_LANG)
.PHONY: python
python: protoc-check $(PYTHON_LANG)

.PHONY: cpp
cpp: protoc-check $(CPP_LANG)

.PHONY: rust-install
rust-install: $(RUST_LANG)
$(RUST_CODEGEN_SCRIPT) install_code $(RUST_BUILD_DIR) $(RUST_LANG_DIR)
Expand All @@ -80,6 +92,10 @@ rust-install: $(RUST_LANG)
python-install: $(PYTHON_LANG)
$(PYTHON_CODEGEN_SCRIPT) install_code $(PYTHON_BUILD_DIR) $(PYTHON_LANG_DIR)

.PHONY: cpp-install
cpp-install: $(CPP_LANG)
$(CPP_CODEGEN_SCRIPT) install_code $(CPP_BUILD_DIR) $(CPP_LANG_DIR)

.PHONY: install
install: rust-install python-install

Expand All @@ -95,6 +111,10 @@ rust-dirclean:
python-dirclean:
rm -rf $(PYTHON_BUILD_DIR)

.PHONY: cpp-dirclean
cpp-dirclean:
rm -rf $(CPP_BUILD_DIR)

.PHONY: help
help:
@echo 'Cleaning:'
Expand Down
75 changes: 75 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

# Minimum CMake required
cmake_minimum_required(VERSION 3.15)

# Project
project(astarte-msg-hub-proto)

# Protobuf
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${protobuf_VERSION}")

# Protobuf-compiler
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)

# gRPC
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(_GRPC_GRPCPP gRPC::grpc++)
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)

# Output directory
if(NOT EXISTS "${OUT_FOLDER}")
set(OUT_FOLDER "${CMAKE_CURRENT_LIST_DIR}")
endif()


# Directory containing proto files
get_filename_component(proto_inc_path "${CMAKE_CURRENT_LIST_DIR}/../proto" ABSOLUTE)
# Collect all .proto files
file(GLOB_RECURSE proto_files "${proto_inc_path}/astarteplatform/msghub/*.proto")

# Prepare the list of generated source and header files
set(proto_srcs)
set(proto_hdrs)
set(grpc_srcs)
set(grpc_hdrs)

foreach(proto_file ${proto_files})
get_filename_component(proto_name ${proto_file} NAME_WE)

# Output paths
set(out_proto_src "${OUT_FOLDER}/astarteplatform/msghub/${proto_name}.pb.cc")
set(out_proto_hdr "${OUT_FOLDER}/astarteplatform/msghub/${proto_name}.pb.h")
set(out_grpc_src "${OUT_FOLDER}/astarteplatform/msghub/${proto_name}.grpc.pb.cc")
set(out_grpc_hdr "${OUT_FOLDER}/astarteplatform/msghub/${proto_name}.grpc.pb.h")

# Add generated files to the lists
list(APPEND proto_srcs "${out_proto_src}")
list(APPEND proto_hdrs "${out_proto_hdr}")
list(APPEND grpc_srcs "${out_grpc_src}")
list(APPEND grpc_hdrs "${out_grpc_hdr}")

# Generated sources
add_custom_command(
OUTPUT "${out_proto_src}" "${out_proto_hdr}" "${out_grpc_src}" "${out_grpc_hdr}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${OUT_FOLDER}"
--cpp_out "${OUT_FOLDER}"
-I "${proto_inc_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${proto_file}"
DEPENDS "${proto_file}")
endforeach()

# Add the generated files to the build
add_library(astarte_message_hub_proto SHARED ${proto_srcs} ${proto_hdrs} ${grpc_srcs} ${grpc_hdrs})
# Include generated *.pb.h files
target_include_directories(astarte_message_hub_proto PUBLIC ${OUT_FOLDER})
# Link the libraries together
target_link_libraries(astarte_message_hub_proto
absl::check
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
18 changes: 18 additions & 0 deletions cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated proto files for C++

## Installing gRPC

Follow the [online guide](https://grpc.io/docs/languages/cpp/quickstart/#install-grpc) to install
gRPC.

## Compilation of the .proto files

The CMake scripts in this folder make it possible to generate the C++ classes and structures
starting from the .proto files.
```sh
mkdir -p ./cmake/build
pushd ./cmake/build
cmake ../..
make
popd
```
43 changes: 43 additions & 0 deletions scripts/cpp_codegen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash

# Copyright 2024 SECO Mind Srl
# SPDX-License-Identifier: Apache-2.0

set -eEuo pipefail

codegen () {
PROTO_DIR=$1
PROJECT_DIR=$2
OUT_DIR=$3

# Remove old code
if [ -d "$OUT_DIR/astarteplatform" ]; then
rm -r "$OUT_DIR/astarteplatform"
fi

mkdir -p $PROJECT_DIR/cmake/build
pushd $PROJECT_DIR/cmake/build
cmake -DOUT_FOLDER:STRING=$OUT_DIR ../..
make
popd

}

install_code (){
OUT_DIR=$1
INSTALL_DIR=$2

# Check if the directory exists and is not empty
if [ -d "$INSTALL_DIR"/astarteplatform/msghub ] && [ "$(ls -A "$INSTALL_DIR"/astarteplatform/msghub)" ]; then
rm -v "$INSTALL_DIR"/astarteplatform/msghub/*
fi

install -d "$INSTALL_DIR"/astarteplatform/msghub
install -m 644 "$OUT_DIR"/astarteplatform/msghub/* "$INSTALL_DIR"/astarteplatform/msghub
}

if [ "$1" = "codegen" ]; then
codegen "$2" "$3" "$4"
elif [ "$1" = "install_code" ]; then
install_code "$2" "$3"
fi

0 comments on commit c8f5b65

Please sign in to comment.