-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Michael Carroll <[email protected]>
- Loading branch information
Showing
3 changed files
with
359 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
################################################## | ||
# A function that calls protoc on a protobuf file | ||
# Options: | ||
# One value arguments: | ||
# FACTORY_GEN_SCRIPT - Location of the factory generator script | ||
# PROTO_PACKAGE - Protobuf package the file belongs to (e.g. ".gz.msgs") | ||
# PROTOC_EXEC - Path to protoc | ||
# INPUT_PROTO - Path to the input .proto file | ||
# OUTPUT_CPP_DIR - Path where C++ files are saved | ||
# OUTPUT_INCLUDES - A CMake variable name containing a list that the C++ header path should be appended to | ||
# OUTPUT_CPP_HH_VAR - A CMake variable name containing a list that the C++ header path should be appended to | ||
# OUTPUT_CPP_CC_VAR - A Cmake variable name containing a list that the C++ source path should be appended to | ||
# Multi value arguments | ||
# INPUT_PROTOS - Passed to protoc --proto_path | ||
# PROTO_PATH - Passed to protoc --proto_path | ||
function(gz_msgs_factory) | ||
set(options "") | ||
set(oneValueArgs | ||
FACTORY_GEN_SCRIPT | ||
PROTO_PACKAGE | ||
OUTPUT_CPP_DIR | ||
OUTPUT_CPP_HH_VAR | ||
OUTPUT_CPP_CC_VAR) | ||
set(multiValueArgs INPUT_PROTOS PROTO_PATH) | ||
|
||
cmake_parse_arguments(gz_msgs_factory "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||
|
||
set(proto_package_dir ".") | ||
if(gz_msgs_factory_PROTO_PACKAGE) | ||
string(REPLACE "." "/" proto_package_dir ${gz_msgs_factory_PROTO_PACKAGE}) | ||
endif() | ||
|
||
set(output_header "${gz_msgs_factory_OUTPUT_CPP_DIR}/${proto_package_dir}/MessageTypes.hh") | ||
set(output_source "${gz_msgs_factory_OUTPUT_CPP_DIR}/${proto_package_dir}/register.cc") | ||
|
||
list(APPEND ${gz_msgs_factory_OUTPUT_CPP_HH_VAR} ${output_header}) | ||
list(APPEND ${gz_msgs_factory_OUTPUT_CPP_CC_VAR} ${output_source}) | ||
|
||
list(APPEND output_files ${output_header}) | ||
list(APPEND output_files ${output_source}) | ||
|
||
set(${gz_msgs_factory_OUTPUT_CPP_HH_VAR} ${${gz_msgs_factory_OUTPUT_CPP_HH_VAR}} PARENT_SCOPE) | ||
set(${gz_msgs_factory_OUTPUT_CPP_CC_VAR} ${${gz_msgs_factory_OUTPUT_CPP_CC_VAR}} PARENT_SCOPE) | ||
|
||
set(depends_index) | ||
|
||
# Full path to an index file, which contains all defined message types for that proto file | ||
foreach(proto_file ${generate_messages_MSGS_PROTOS}) | ||
get_filename_component(FIL_WE ${proto_file} NAME_WE) | ||
string(REPLACE "." "_" PACKAGE_UNDER ${gz_msgs_factory_PROTO_PACKAGE}) | ||
string(REPLACE "." "_" MESSAGE_UNDER ${FIL_WE}) | ||
set(input_index "${gz_msgs_factory_OUTPUT_CPP_DIR}/${PACKAGE_UNDER}_${MESSAGE_UNDER}.pb_index") | ||
list(APPEND depends_index ${input_index}) | ||
endforeach() | ||
|
||
|
||
set(GENERATE_ARGS | ||
--output-cpp-path "${gz_msgs_factory_OUTPUT_CPP_DIR}" | ||
--proto-package "${gz_msgs_factory_PROTO_PACKAGE}" | ||
--proto-path "${gz_msgs_factory_PROTO_PATH}" | ||
--protos "${gz_msgs_factory_INPUT_PROTOS}" | ||
) | ||
|
||
add_custom_command( | ||
OUTPUT ${output_files} | ||
COMMAND Python3::Interpreter | ||
ARGS ${gz_msgs_factory_FACTORY_GEN_SCRIPT} ${GENERATE_ARGS} | ||
DEPENDS | ||
${depends_index} | ||
# While the script is executed in the source directory, it does not write | ||
# to the source tree. All outputs are stored in the build directory. | ||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} | ||
COMMENT "Running factory generator" | ||
VERBATIM | ||
) | ||
|
||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
################################################## | ||
# A function that calls protoc on a protobuf file | ||
# Options: | ||
# GENERATE_CPP - generates c++ code for the message if specified | ||
# One value arguments: | ||
# PROTO_PACKAGE - Protobuf package the file belongs to (e.g. ".gz.msgs") | ||
# PROTOC_EXEC - Path to protoc | ||
# INPUT_PROTO - Path to the input .proto file | ||
# OUTPUT_CPP_DIR - Path where C++ files are saved | ||
# OUTPUT_INCLUDES - A CMake variable name containing a list that the C++ header path should be appended to | ||
# OUTPUT_CPP_HH_VAR - A CMake variable name containing a list that the C++ header path should be appended to | ||
# OUTPUT_CPP_CC_VAR - A Cmake variable name containing a list that the C++ source path should be appended to | ||
# Multi value arguments | ||
# PROTO_PATH - Passed to protoc --proto_path | ||
function(gz_msgs_protoc) | ||
set(options GENERATE_CPP) | ||
set(oneValueArgs | ||
MSGS_GEN_SCRIPT | ||
PROTO_PACKAGE | ||
PROTOC_EXEC | ||
GZ_PROTOC_PLUGIN | ||
INPUT_PROTO | ||
OUTPUT_CPP_DIR | ||
OUTPUT_INCLUDES | ||
OUTPUT_CPP_HH_VAR | ||
OUTPUT_DETAIL_CPP_HH_VAR | ||
OUTPUT_CPP_CC_VAR) | ||
set(multiValueArgs PROTO_PATH DEPENDENCY_PROTO_PATHS) | ||
|
||
cmake_parse_arguments(gz_msgs_protoc "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||
|
||
get_filename_component(ABS_FIL ${gz_msgs_protoc_INPUT_PROTO} ABSOLUTE) | ||
get_filename_component(FIL_WE ${gz_msgs_protoc_INPUT_PROTO} NAME_WE) | ||
|
||
set(protoc_args) | ||
set(output_files) | ||
|
||
set(proto_package_dir ".") | ||
if(gz_msgs_protoc_PROTO_PACKAGE) | ||
string(REPLACE "." "/" proto_package_dir ${gz_msgs_protoc_PROTO_PACKAGE}) | ||
endif() | ||
|
||
if(gz_msgs_protoc_GENERATE_CPP) | ||
# Full path to generated header (${PROJECT_BINARY_DIR}/include/gz/msgs/foo.pb.h) | ||
set(output_header "${gz_msgs_protoc_OUTPUT_CPP_DIR}/${proto_package_dir}/${FIL_WE}.pb.h") | ||
# Full path to generated detail header (${PROJECT_BINARY_DIR}/include/gz/msgs/details/foo.pb.h) | ||
set(output_detail_header "${gz_msgs_protoc_OUTPUT_CPP_DIR}/${proto_package_dir}/details/${FIL_WE}.pb.h") | ||
# Full path to generated ignition header (${PROJECT_BINARY_DIR}/include/foo.pb.cc) | ||
set(output_source "${gz_msgs_protoc_OUTPUT_CPP_DIR}/${proto_package_dir}/${FIL_WE}.pb.cc") | ||
|
||
# Full path to an index file, which contains all defined message types for that proto file | ||
string(REPLACE "." "_" PACKAGE_UNDER ${gz_msgs_protoc_PROTO_PACKAGE}) | ||
string(REPLACE "." "_" MESSAGE_UNDER ${FIL_WE}) | ||
set(output_index "${gz_msgs_protoc_OUTPUT_CPP_DIR}/${PACKAGE_UNDER}_${MESSAGE_UNDER}.pb_index") | ||
|
||
# Generate a clean relative path (gz/msgs/foo.pb.h) | ||
string(REPLACE "${PROJECT_BINARY_DIR}/include/" "" output_include ${output_header}) | ||
list(APPEND ${gz_msgs_protoc_OUTPUT_INCLUDES} "${output_include}") | ||
|
||
list(APPEND ${gz_msgs_protoc_OUTPUT_CPP_HH_VAR} ${output_header}) | ||
list(APPEND ${gz_msgs_protoc_OUTPUT_CPP_CC_VAR} ${output_source}) | ||
list(APPEND ${gz_msgs_protoc_OUTPUT_DETAIL_CPP_HH_VAR} ${output_detail_header}) | ||
|
||
list(APPEND output_files ${output_header}) | ||
list(APPEND output_files ${output_detail_header}) | ||
list(APPEND output_files ${output_source}) | ||
list(APPEND output_files ${output_index}) | ||
|
||
set(${gz_msgs_protoc_OUTPUT_INCLUDES} ${${gz_msgs_protoc_OUTPUT_INCLUDES}} PARENT_SCOPE) | ||
set(${gz_msgs_protoc_OUTPUT_DETAIL_CPP_HH_VAR} ${${gz_msgs_protoc_OUTPUT_DETAIL_CPP_HH_VAR}} PARENT_SCOPE) | ||
set(${gz_msgs_protoc_OUTPUT_CPP_HH_VAR} ${${gz_msgs_protoc_OUTPUT_CPP_HH_VAR}} PARENT_SCOPE) | ||
set(${gz_msgs_protoc_OUTPUT_CPP_CC_VAR} ${${gz_msgs_protoc_OUTPUT_CPP_CC_VAR}} PARENT_SCOPE) | ||
endif() | ||
|
||
set(GENERATE_ARGS | ||
--protoc-exec "$<TARGET_FILE:${gz_msgs_protoc_PROTOC_EXEC}>" | ||
--gz-generator-bin "${gz_msgs_protoc_GZ_PROTOC_PLUGIN}" | ||
--proto-path "${gz_msgs_protoc_PROTO_PATH}" | ||
--input-path "${ABS_FIL}" | ||
) | ||
|
||
if(gz_msgs_protoc_DEPENDENCY_PROTO_PATHS) | ||
list(APPEND GENERATE_ARGS | ||
--dependency-proto-paths "${gz_msgs_protoc_DEPENDENCY_PROTO_PATHS}" | ||
) | ||
endif() | ||
|
||
if(${gz_msgs_protoc_GENERATE_CPP}) | ||
list(APPEND GENERATE_ARGS | ||
--generate-cpp | ||
--output-cpp-path "${gz_msgs_protoc_OUTPUT_CPP_DIR}") | ||
endif() | ||
|
||
add_custom_command( | ||
OUTPUT ${output_files} | ||
COMMAND Python3::Interpreter | ||
ARGS ${gz_msgs_protoc_MSGS_GEN_SCRIPT} ${GENERATE_ARGS} | ||
DEPENDS | ||
${ABS_FIL} | ||
# While the script is executed in the source directory, it does not write | ||
# to the source tree. All outputs are stored in the build directory. | ||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} | ||
COMMENT "Running protoc on ${gz_msgs_protoc_INPUT_PROTO}" | ||
VERBATIM | ||
) | ||
|
||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
# Copyright 2023 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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. | ||
|
||
# copied from gz-msgs/gz-msgs-extras.cmake | ||
|
||
find_package(Python3 REQUIRED COMPONENTS Interpreter) | ||
|
||
include(${@PROJECT_NAME@_DIR}/gz_msgs_protoc.cmake) | ||
include(${@PROJECT_NAME@_DIR}/gz_msgs_factory.cmake) | ||
|
||
set(@PROJECT_NAME@_INSTALL_PATH "${@PROJECT_NAME@_DIR}/../../..") | ||
cmake_path(NORMAL_PATH @PROJECT_NAME@_INSTALL_PATH OUTPUT_VARIABLE @PROJECT_NAME@_INSTALL_PATH) | ||
set(PROTOC_NAME "@PROJECT_NAME@_protoc_plugin") | ||
set(PROTO_SCRIPT_NAME "@PROJECT_NAME@_generate.py") | ||
set(FACTORY_SCRIPT_NAME "@PROJECT_NAME@_generate_factory.py") | ||
|
||
set(@PROJECT_NAME@_PROTO_PATH ${@PROJECT_NAME@_INSTALL_PATH}/share/protos) | ||
set(@PROJECT_NAME@_PROTO_GENERATOR_PLUGIN ${@PROJECT_NAME@_INSTALL_PATH}/bin/${PROTOC_NAME}) | ||
set(@PROJECT_NAME@_PROTO_GENERATOR_SCRIPT ${@PROJECT_NAME@_INSTALL_PATH}/bin/${PROTO_SCRIPT_NAME}) | ||
set(@PROJECT_NAME@_FACTORY_GENERATOR_SCRIPT ${@PROJECT_NAME@_INSTALL_PATH}/bin/${FACTORY_SCRIPT_NAME}) | ||
|
||
function(get_installed_messages) | ||
set(options "") | ||
set(oneValueArgs MESSAGES_PATH_VARIABLE MESSAGES_PROTOS_VARIABLE) | ||
set(multiValueArgs DEPENDS) | ||
|
||
cmake_parse_arguments(get_installed_messages "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||
|
||
set(@PROJECT_NAME@_INSTALL_PATH "${@PROJECT_NAME@_DIR}/../../..") | ||
cmake_path(NORMAL_PATH @PROJECT_NAME@_INSTALL_PATH OUTPUT_VARIABLE @PROJECT_NAME@_INSTALL_PATH) | ||
|
||
set(@PROJECT_NAME@_PROTO_PATH ${@PROJECT_NAME@_INSTALL_PATH}/share/protos) | ||
file (GLOB protos ${@PROJECT_NAME@_PROTO_PATH}/gz/msgs/*.proto) | ||
set(${get_installed_messages_MESSAGES_PROTOS_VARIABLE} ${protos} PARENT_SCOPE) | ||
set(${get_installed_messages_MESSAGES_PATH_VARIABLE} ${@PROJECT_NAME@_PROTO_PATH} PARENT_SCOPE) | ||
endfunction() | ||
|
||
function(generate_messages) | ||
set(options "") | ||
set(oneValueArgs MSGS_PATH TARGET PROTO_PACKAGE) | ||
set(multiValueArgs MSGS_PROTOS DEPENDENCIES) | ||
|
||
cmake_parse_arguments(generate_messages "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||
string(REPLACE "." "_" gen_dir ${generate_messages_PROTO_PACKAGE}) | ||
|
||
set(depends_proto_paths) | ||
set(depends_includes) | ||
foreach(dep ${generate_messages_DEPENDENCIES}) | ||
get_target_property(dep_proto_path ${dep} PROTO_DIR) | ||
get_target_property(dep_proto_include_path ${dep} PROTO_INCLUDE_DIR) | ||
list(APPEND depends_proto_paths ${dep_proto_path}) | ||
list(APPEND depends_includes ${dep_proto_include_path}) | ||
endforeach() | ||
|
||
foreach(proto_file ${generate_messages_MSGS_PROTOS}) | ||
gz_msgs_protoc( | ||
MSGS_GEN_SCRIPT | ||
${@PROJECT_NAME@_PROTO_GENERATOR_SCRIPT} | ||
PROTO_PACKAGE | ||
${generate_messages_PROTO_PACKAGE} | ||
GENERATE_CPP | ||
INPUT_PROTO | ||
${proto_file} | ||
PROTOC_EXEC | ||
protobuf::protoc | ||
GZ_PROTOC_PLUGIN | ||
${@PROJECT_NAME@_PROTO_GENERATOR_PLUGIN} | ||
OUTPUT_CPP_DIR | ||
"${PROJECT_BINARY_DIR}/${gen_dir}_gen" | ||
OUTPUT_INCLUDES | ||
gen_includes | ||
OUTPUT_CPP_HH_VAR | ||
gen_headers | ||
OUTPUT_DETAIL_CPP_HH_VAR | ||
gen_detail_headers | ||
OUTPUT_CPP_CC_VAR | ||
gen_sources | ||
PROTO_PATH | ||
${generate_messages_MSGS_PATH} | ||
DEPENDENCY_PROTO_PATHS | ||
${depends_proto_paths} | ||
) | ||
endforeach() | ||
|
||
gz_msgs_factory( | ||
FACTORY_GEN_SCRIPT | ||
${@PROJECT_NAME@_FACTORY_GENERATOR_SCRIPT} | ||
PROTO_PACKAGE | ||
${generate_messages_PROTO_PACKAGE} | ||
INPUT_PROTOS | ||
${generate_messages_MSGS_PROTOS} | ||
OUTPUT_CPP_DIR | ||
"${PROJECT_BINARY_DIR}/${gen_dir}_gen" | ||
OUTPUT_CPP_HH_VAR | ||
gen_factory_headers | ||
OUTPUT_CPP_CC_VAR | ||
gen_factory_sources | ||
PROTO_PATH | ||
${generate_messages_MSGS_PATH} | ||
) | ||
|
||
set_source_files_properties( | ||
${gen_headers} | ||
${gen_detail_headers} | ||
${gen_sources} | ||
${gen_factory_headers} | ||
${gen_factory_sources} | ||
PROPERTIES GENERATED TRUE) | ||
|
||
if(WIN32) | ||
set_source_files_properties(${gen_sources} | ||
COMPILE_FLAGS "/wd4100 /wd4512 /wd4127 /wd4068 /wd4244 /wd4267 /wd4251 /wd4146") | ||
endif() | ||
|
||
add_library(${generate_messages_TARGET} ${gen_sources} ${gen_factory_sources}) | ||
|
||
# Export the messages path and dependency messages paths for potential dependent message libs | ||
set(PROTO_DIR) | ||
list(APPEND PROTO_DIR ${generate_messages_MSGS_PATH}) | ||
list(APPEND PROTO_DIR ${depends_proto_paths}) | ||
|
||
set(PROTO_INCLUDE_DIR) | ||
list(APPEND PROTO_INCLUDE_DIR ${PROJECT_BINARY_DIR}/${gen_dir}_gen) | ||
list(APPEND PROTO_INCLUDE_DIR ${depends_includes}) | ||
|
||
set_target_properties(${generate_messages_TARGET} PROPERTIES PROTO_DIR "${PROTO_DIR}") | ||
set_target_properties(${generate_messages_TARGET} PROPERTIES PROTO_INCLUDE_DIR "${PROTO_INCLUDE_DIR}") | ||
|
||
target_link_libraries(${generate_messages_TARGET} PUBLIC protobuf::libprotobuf gz-msgs10::gz-msgs10) | ||
target_include_directories(${generate_messages_TARGET} PUBLIC ${PROJECT_BINARY_DIR}/${gen_dir}_gen ${depends_includes}) | ||
endfunction() | ||
|
||
function(target_link_messages) | ||
set(options PUBLIC PRIVATE) | ||
set(oneValueArgs TARGET) | ||
set(multiValueArgs MSG_TARGETS) | ||
|
||
cmake_parse_arguments(target_link_messages "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||
|
||
if (target_link_messages_PUBLIC) | ||
set(VISIBILITY PUBLIC) | ||
elseif (target_link_messages_PRIVATE) | ||
set(VISIBILITY PRIVATE) | ||
endif() | ||
|
||
|
||
foreach(message_lib ${target_link_messages_MSG_TARGETS}) | ||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||
# MSVC link flag doesn't work with generator expressions | ||
# TODO(mjcarroll) When CMake 3.24 is genrally available, use | ||
# linking generator expressions as described here: | ||
# https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#genex:LINK_LIBRARY | ||
target_link_libraries(${target_link_messages_TARGET} ${VISIBILITY} -WHOLEARCHIVE:$<TARGET_FILE:${message_lib}>) | ||
else() | ||
target_link_libraries(${target_link_messages_TARGET} PRIVATE | ||
$<$<CXX_COMPILER_ID:GNU>:-Wl,--whole-archive> | ||
$<$<CXX_COMPILER_ID:Clang>:-force_load> | ||
$<$<CXX_COMPILER_ID:AppleClang>:-force_load> ${message_lib} | ||
$<$<CXX_COMPILER_ID:GNU>:-Wl,--no-whole-archive>) | ||
endif() | ||
endforeach() | ||
|
||
|
||
endfunction() |