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
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ configure_file(${CMAKE_SOURCE_DIR}/cmake/CDTMacros.cmake.in ${CMAKE_BINARY_DIR}/
configure_file(${CMAKE_SOURCE_DIR}/cmake/CDTWasmToolchain.cmake.in ${CMAKE_BINARY_DIR}/cmake/CDTWasmToolchainPackage.cmake @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/cmake/cdt-config.cmake.in ${CMAKE_BINARY_DIR}/cmake/cdt-config.cmake.package @ONLY)

# Find zpp_bits header (from vcpkg) for contract compilation
find_path(ZPP_BITS_INCLUDE_DIR zpp_bits.h
HINTS ${CMAKE_PREFIX_PATH}/include ${VCPKG_INSTALLED_DIR}/x64-linux/include
REQUIRED)


include(cmake/LibrariesExternalProject.cmake)

include(cmake/InstallCDT.cmake)
Expand Down
114 changes: 114 additions & 0 deletions cmake/CDTMacros.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ macro(add_contract CONTRACT_NAME TARGET)
set_cdt_include_directories(${TARGET})
endif()
endmacro()
# Properties for protobuf support
define_property(TARGET PROPERTY PROTOBUF_FILES BRIEF_DOCS "protobuf files" FULL_DOCS "protobuf files used by the contract")
define_property(TARGET PROPERTY PROTOBUF_DIR BRIEF_DOCS "protobuf root directory" FULL_DOCS "protobuf root directory")

# Sets the Ricardian contract directory for a target
# @param TARGET The target to set Ricardian directory for
# @param DIR The directory containing Ricardian contract files
Expand Down Expand Up @@ -198,3 +202,113 @@ macro(add_contract_native CONTRACT_NAME TARGET)
endif()
target_compile_options(${TARGET} PRIVATE -Wno-unknown-attributes)
endmacro()

# Generate C++ headers for protobuf files and tie to a given target
#
# target_add_protobuf(target
# INPUT_DIRECTORY input_dir
# OUTPUT_DIRECTORY output_dir
# FILES file [file1 ...])
#
# Given a list of .proto files, this function generates the corresponding C++ headers
# using cdt-protoc-gen-zpp, and sets the generated files as sources for the specified target.
#
# If the input_dir is not specified, the default is ${CMAKE_CURRENT_SOURCE_DIR} and
# the files specified must be relative paths to the input_dir.
#
function(target_add_protobuf TARGET)
cmake_parse_arguments(ADD_PROTOBUF "" "INPUT_DIRECTORY;OUTPUT_DIRECTORY" "FILES" ${ARGN})

if (ADD_PROTOBUF_OUTPUT_DIRECTORY AND IS_ABSOLUTE ${ADD_PROTOBUF_OUTPUT_DIRECTORY})
message(FATAL_ERROR "The OUTPUT_DIRECTORY for function target_add_protobuf must be a relative directory")
endif()

if (ADD_PROTOBUF_OUTPUT_DIRECTORY)
set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${ADD_PROTOBUF_OUTPUT_DIRECTORY})
else()
set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()

foreach (protofile ${ADD_PROTOBUF_FILES})
if(IS_ABSOLUTE ${protofile})
message(FATAL_ERROR "The FILES parameters for function target_add_protobuf must be relative paths, illegal path `${protofile}`")
endif()
cmake_path(GET protofile EXTENSION LAST_ONLY proto_ext)
if (NOT proto_ext STREQUAL ".proto")
message(FATAL_ERROR "The illegal parameter `${protofile}` for function target_add_protobuf")
endif()
cmake_path(REPLACE_EXTENSION protofile LAST_ONLY ".pb.hpp" OUTPUT_VARIABLE hdr)
list(APPEND OUTPUT_HDRS ${OUTPUT_DIR}/${hdr})
if (ADD_PROTOBUF_INPUT_DIRECTORY)
list(APPEND INPUT_FILES ${ADD_PROTOBUF_INPUT_DIRECTORY}/${protofile})
else()
list(APPEND INPUT_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${protofile})
endif()
endforeach()

if (NOT ADD_PROTOBUF_INPUT_DIRECTORY)
set(ADD_PROTOBUF_INPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()

find_program(PROTOC cdt-protoc
HINTS ${CMAKE_FIND_ROOT_PATH}/bin
REQUIRED)

if (CMAKE_GENERATOR STREQUAL "Unix Makefiles" AND NOT EXISTS ${OUTPUT_DIR})
file(MAKE_DIRECTORY ${OUTPUT_DIR})
endif()

add_custom_command(
COMMENT "Generating ${OUTPUT_HDRS} from ${INPUT_FILES}"
OUTPUT ${OUTPUT_HDRS}
COMMAND ${PROTOC} -I ${ADD_PROTOBUF_INPUT_DIRECTORY} -I ${CMAKE_FIND_ROOT_PATH}/include --plugin=protoc-gen-zpp=${CMAKE_FIND_ROOT_PATH}/bin/cdt-protoc-gen-zpp --zpp_out ${OUTPUT_DIR} ${ADD_PROTOBUF_FILES}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

DEPENDS ${CMAKE_FIND_ROOT_PATH}/bin/cdt-protoc-gen-zpp ${INPUT_FILES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(${TARGET}.protos ALL
DEPENDS ${OUTPUT_HDRS}
)

get_target_property(type ${TARGET} TYPE)
if ("${type}" STREQUAL "INTERFACE_LIBRARY")
target_sources(${TARGET} INTERFACE ${OUTPUT_HDRS})
target_include_directories(${TARGET} INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
else()
target_sources(${TARGET} PRIVATE ${OUTPUT_HDRS})
target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(${TARGET} ${TARGET}.protos)
endif()

set_target_properties(${TARGET} PROPERTIES
PROTOBUF_DIR "${ADD_PROTOBUF_INPUT_DIRECTORY}"
PROTOBUF_FILES "${ADD_PROTOBUF_FILES}")
endfunction()

# Link a contract target to protobuf definitions for ABI generation
#
# contract_use_protobuf(contract_target protobuf_target)
#
function(contract_use_protobuf CONTRACT_TARGET PROTOBUF_TARGET)
get_target_property(PROTO_DIR ${PROTOBUF_TARGET} PROTOBUF_DIR)
get_target_property(PROTO_FILES ${PROTOBUF_TARGET} PROTOBUF_FILES)
set_target_properties(${CONTRACT_TARGET} PROPERTIES
PROTOBUF_DIR ${PROTO_DIR}
PROTOBUF_FILES "${PROTO_FILES}"
)
# Propagate include directories from protobuf target for generated headers
get_target_property(PROTO_INCLUDES ${PROTOBUF_TARGET} INTERFACE_INCLUDE_DIRECTORIES)
if (PROTO_INCLUDES)
target_include_directories(${CONTRACT_TARGET} PUBLIC ${PROTO_INCLUDES})
endif()
# Ensure protobuf headers are generated before the contract is compiled
if (TARGET ${PROTOBUF_TARGET}.protos)
add_dependencies(${CONTRACT_TARGET} ${PROTOBUF_TARGET}.protos)
endif()
# Pass protobuf info to cdt-codegen via compile options (picked up by cdt-cpp)
string(REPLACE ";" "$<SEMICOLON>" PROTO_FILES_ESCAPED "${PROTO_FILES}")
target_compile_options(${CONTRACT_TARGET} PUBLIC
--protobuf-dir ${PROTO_DIR}
--protobuf-files "${PROTO_FILES_ESCAPED}"
)
endfunction()
19 changes: 19 additions & 0 deletions cmake/InstallCDT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ cdt_tool_install_and_symlink(cdt-ld cdt-ld)
cdt_tool_install_and_symlink(cdt-abidiff cdt-abidiff)
cdt_tool_install_and_symlink(cdt-init cdt-init)
cdt_tool_install_and_symlink(cdt-codegen cdt-codegen)
cdt_tool_install_and_symlink(cdt-protoc-gen-zpp cdt-protoc-gen-zpp)

# Install cdt-protoc (protoc from vcpkg, copied during tools build)
add_custom_command( TARGET CDTTools POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tools/bin/cdt-protoc ${CMAKE_BINARY_DIR}/bin/ )
install(PROGRAMS ${CMAKE_BINARY_DIR}/tools/bin/cdt-protoc
DESTINATION ${CDT_INSTALL_PREFIX}/bin)

# Sysio plugins (built by tools project)
foreach(plugin sysio_attrs sysio_codegen)
Expand All @@ -71,4 +77,17 @@ cdt_cmake_install_and_symlink(cdt-config.cmake cdt-config.cmake)
cdt_cmake_install_and_symlink(CDTWasmToolchain.cmake CDTWasmToolchain.cmake)
cdt_cmake_install_and_symlink(CDTMacros.cmake CDTMacros.cmake)

# Copy protobuf support files to main include dir for contract compilation
add_custom_command( TARGET CDTTools POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include
COMMAND ${CMAKE_COMMAND} -E copy ${ZPP_BITS_INCLUDE_DIR}/zpp_bits.h ${CMAKE_BINARY_DIR}/include/
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/zpp
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tools/include/zpp/zpp_options.proto ${CMAKE_BINARY_DIR}/include/zpp/
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/google/protobuf
COMMAND ${CMAKE_COMMAND} -E copy ${ZPP_BITS_INCLUDE_DIR}/google/protobuf/descriptor.proto ${CMAKE_BINARY_DIR}/include/google/protobuf/ )
install(FILES ${CMAKE_BINARY_DIR}/tools/include/zpp/zpp_options.proto
DESTINATION ${CDT_INSTALL_PREFIX}/include/zpp)
install(FILES ${ZPP_BITS_INCLUDE_DIR}/google/protobuf/descriptor.proto
DESTINATION ${CDT_INSTALL_PREFIX}/include/google/protobuf)

cdt_libraries_install()
Loading
Loading