From 0336770801c53543f4b1f3ebfd28dfc65e331c5c Mon Sep 17 00:00:00 2001 From: Walter Gray Date: Tue, 30 May 2017 16:49:18 -0700 Subject: add protobuf_generate function, allows use of target_sources where available --- cmake/protobuf-config.cmake.in | 99 ++++++++++++++++++++++++++++++++++++++++++ cmake/protobuf-module.cmake.in | 85 ++++++++---------------------------- examples/CMakeLists.txt | 17 +------- 3 files changed, 117 insertions(+), 84 deletions(-) diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in index a044fe5c..83213547 100644 --- a/cmake/protobuf-config.cmake.in +++ b/cmake/protobuf-config.cmake.in @@ -7,6 +7,105 @@ include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake") # Imported targets include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake") +function(protobuf_generate) + include(CMakeParseArguments) + set(_singleargs LANGUAGE OUT_VAR) + if(COMMAND target_sources) + list(APPEND _singleargs TARGET) + endif() + + cmake_parse_arguments(protobuf_generate "APPEND_PATH" "${_singleargs}" "PROTOS IMPORT_DIRS GENERATE_EXTENSIONS" "${ARGN}") + + if(protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET) + message(SEND_ERROR "Error: protobuf_generate called without any targets or source files") + return() + endif() + + if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET) + message(SEND_ERROR "Error: protobuf_generate called without a target or output variable") + return() + endif() + + if(NOT protobuf_generate_LANGUAGE) + set(protobuf_generate_LANGUAGE cpp) + endif() + string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE) + + if(NOT protobuf_GENERATE_EXTENSIONS) + if(protobuf_generate_LANGUAGE STREQUAL cpp) + set(protobuf_GENERATE_EXTENSIONS .pb.h .pb.cc) + elseif(protobuf_generate_LANGUAGE STREQUAL python) + set(protobuf_GENERATE_EXTENSIONS _pb2.py) + else() + message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS") + return() + endif() + endif() + + if(protobuf_generate_APPEND_PATH) + # Create an include path for each file specified + foreach(_file ${ARGN}) + get_filename_component(_abs_file ${_file} ABSOLUTE) + get_filename_component(_abs_path ${_abs_file} PATH) + list(FIND _protobuf_include_path ${_abs_path} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${_abs_path}) + endif() + endforeach() + else() + set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + foreach(DIR ${protobuf_generate_IMPORT_DIRS}) + get_filename_component(ABS_PATH ${DIR} ABSOLUTE) + list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + + if(protobuf_generate_TARGET) + get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES) + foreach(_file ${_source_list}) + if(_file MATCHES "proto$") + list(APPEND protobuf_generate_PROTOS ${_file}) + endif() + endforeach() + endif() + + if(NOT protobuf_generate_PROTOS) + message(SEND_ERROR "Error: protobuf_generate could not find any .proto files") + return() + endif() + + set(_generated_srcs) + foreach(_proto ${protobuf_generate_PROTOS}) + get_filename_component(_abs_file ${_proto} ABSOLUTE) + get_filename_component(_basename ${_proto} NAME_WE) + + foreach(_ext ${_output_extensions}) + list(APPEND _generated_srcs "${CMAKE_CURRENT_BINARY_DIR}/${_basename}${_ext}") + endforeach() + + add_custom_command( + OUTPUT ${_generated_srcs} + COMMAND protobuf::protoc + ARGS --${protobuf_generate_LANGUAGE}_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${_abs_file} + DEPENDS ${ABS_FIL} protobuf::protoc + COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" + VERBATIM ) + endforeach() + + set_source_files_properties(${_generated_srcs} PROPERTIES GENERATED TRUE) + if(protobuf_generate_OUT_VAR) + set(${protobuf_generate_OUT_VAR} ${_generated_srcs} PARENT_SCOPE) + endif() + if(protobuf_generate_TARGET) + target_sources(${protobuf_generate_TARGET} PUBLIC ${_generated_srcs}) + endif() + +endfunction() + # CMake FindProtobuf module compatible file if(protobuf_MODULE_COMPATIBLE) include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake") diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in index 614e4c04..8e4920aa 100644 --- a/cmake/protobuf-module.cmake.in +++ b/cmake/protobuf-module.cmake.in @@ -1,3 +1,4 @@ +# This file contains backwards compatibility patches for various legacy functions and variables # Functions function(PROTOBUF_GENERATE_CPP SRCS HDRS) @@ -7,49 +8,25 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) endif() if(PROTOBUF_GENERATE_CPP_APPEND_PATH) - # Create an include path for each file specified - foreach(FIL ${ARGN}) - get_filename_component(ABS_FIL ${FIL} ABSOLUTE) - get_filename_component(ABS_PATH ${ABS_FIL} PATH) - list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() - else() - set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + set(_append_arg APPEND_PATH) endif() if(DEFINED Protobuf_IMPORT_DIRS) - foreach(DIR ${Protobuf_IMPORT_DIRS}) - get_filename_component(ABS_PATH ${DIR} ABSOLUTE) - list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() + set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS}) endif() + set(_outvar) + protobuf_generate(${append_arg} LANGUAGE cpp OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN}) + set(${SRCS}) set(${HDRS}) - foreach(FIL ${ARGN}) - get_filename_component(ABS_FIL ${FIL} ABSOLUTE) - get_filename_component(FIL_WE ${FIL} NAME_WE) - - list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc") - list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h") - - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc" - "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" - COMMAND ${Protobuf_PROTOC_EXECUTABLE} - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} - DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE} - COMMENT "Running C++ protocol buffer compiler on ${FIL}" - VERBATIM ) + foreach(_file ${_outvar}) + if(_file MATCHES "cc$") + list(APPEND ${SRCS} ${_file}) + else() + list(APPEND ${HDRS} ${_file}) + endif() endforeach() - - set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) set(${SRCS} ${${SRCS}} PARENT_SCOPE) set(${HDRS} ${${HDRS}} PARENT_SCOPE) endfunction() @@ -61,44 +38,16 @@ function(PROTOBUF_GENERATE_PYTHON SRCS) endif() if(PROTOBUF_GENERATE_CPP_APPEND_PATH) - # Create an include path for each file specified - foreach(FIL ${ARGN}) - get_filename_component(ABS_FIL ${FIL} ABSOLUTE) - get_filename_component(ABS_PATH ${ABS_FIL} PATH) - list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() - else() - set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + set(_append_arg APPEND_PATH) endif() if(DEFINED Protobuf_IMPORT_DIRS) - foreach(DIR ${Protobuf_IMPORT_DIRS}) - get_filename_component(ABS_PATH ${DIR} ABSOLUTE) - list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() + set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS}) endif() - set(${SRCS}) - foreach(FIL ${ARGN}) - get_filename_component(ABS_FIL ${FIL} ABSOLUTE) - get_filename_component(FIL_WE ${FIL} NAME_WE) - - list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py") - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py" - COMMAND ${Protobuf_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} - DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE} - COMMENT "Running Python protocol buffer compiler on ${FIL}" - VERBATIM ) - endforeach() - - set(${SRCS} ${${SRCS}} PARENT_SCOPE) + set(_outvar) + protobuf_generate(${append_arg} LANGUAGE cpp OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN}) + set(${SRCS} ${_outvar} PARENT_SCOPE) endfunction() # Environment diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2cd2acc0..3e8e6541 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,22 +32,6 @@ foreach(example add_person list_people) if(protobuf_MODULE_COMPATIBLE) #Legacy Support protobuf_generate_cpp(${example}_PROTO_SRCS ${example}_PROTO_HDRS ${${example}_PROTOS}) list(APPEND ${example}_SRCS ${${example}_PROTO_SRCS} ${${example}_PROTO_HDRS}) - else() - - foreach(proto_file ${${example}_PROTOS}) - get_filename_component(proto_file_abs ${proto_file} ABSOLUTE) - get_filename_component(basename ${proto_file} NAME_WE) - set(generated_files ${basename}.pb.cc ${basename}.pb.h) - list(APPEND ${example}_SRCS ${generated_files}) - - add_custom_command( - OUTPUT ${generated_files} - COMMAND protobuf::protoc - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_file_abs} - COMMENT "Generating ${generated_files} from ${proto_file}" - VERBATIM - ) - endforeach() endif() #Executable setup @@ -58,6 +42,7 @@ foreach(example add_person list_people) target_link_libraries(${executable_name} ${PROTOBUF_LIBRARIES}) else() target_link_libraries(${executable_name} protobuf::libprotobuf) + protobuf_generate(TARGET ${executable_name}) endif() endforeach() -- cgit v1.2.3