2022-10-05 17:11:31 +00:00
|
|
|
# Copyright (C) 2022 The Qt Company Ltd.
|
|
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
|
|
|
|
set(__qt_protobuf_macros_module_base_dir "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "")
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
# List of the common protoc generator options.
|
|
|
|
macro(_qt_internal_get_protoc_common_options option_args single_args multi_args)
|
|
|
|
set(${option_args}
|
|
|
|
COPY_COMMENTS
|
|
|
|
GENERATE_PACKAGE_SUBFOLDERS
|
2023-03-30 16:38:28 +00:00
|
|
|
QML
|
2022-11-21 17:31:49 +00:00
|
|
|
)
|
|
|
|
set(${single_args}
|
|
|
|
EXTRA_NAMESPACE
|
|
|
|
EXPORT_MACRO
|
2023-05-11 10:36:38 +00:00
|
|
|
QML_URI
|
2022-11-21 17:31:49 +00:00
|
|
|
)
|
2022-10-05 17:11:31 +00:00
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
set(${multi_args} "")
|
|
|
|
endmacro()
|
|
|
|
|
|
|
|
# List of arguments common for the protoc generating functions.
|
|
|
|
macro(_qt_internal_get_protoc_generate_arguments option_args single_args multi_args)
|
|
|
|
set(${option_args} "")
|
|
|
|
set(${single_args}
|
2022-10-05 17:11:31 +00:00
|
|
|
OUTPUT_DIRECTORY
|
|
|
|
PROTO_FILES_BASE_DIR
|
2022-12-06 14:42:56 +00:00
|
|
|
OUTPUT_HEADERS
|
|
|
|
OUTPUT_TARGETS
|
2022-10-05 17:11:31 +00:00
|
|
|
)
|
2022-11-21 17:31:49 +00:00
|
|
|
set(${multi_args}
|
|
|
|
PROTO_FILES
|
|
|
|
PROTO_INCLUDES
|
|
|
|
)
|
|
|
|
endmacro()
|
|
|
|
|
|
|
|
# The macro collects options in protoc compatible format. Options are written into out_var.
|
|
|
|
# All input arguments are names of the lists containing the corresponding options.
|
|
|
|
macro(_qt_internal_get_protoc_options out_var prefix option single multi)
|
|
|
|
set(${out_var} "")
|
|
|
|
foreach(opt IN LISTS ${option})
|
|
|
|
if(${prefix}_${opt})
|
|
|
|
list(APPEND ${out_var} ${opt})
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
foreach(opt IN LISTS ${single} ${multi})
|
|
|
|
if(${prefix}_${opt})
|
|
|
|
list(APPEND ${out_var} "${opt}=${${prefix}_${opt}}")
|
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
endmacro()
|
|
|
|
|
|
|
|
# The base function that generates rules to call the protoc executable with the custom generator
|
|
|
|
# plugin.
|
|
|
|
# Multi-value Arguments:
|
|
|
|
# PROTO_FILES - list of the .proto file paths. Paths should be absolute for the correct work of
|
|
|
|
# this function.
|
|
|
|
# PROTO_INCLUDES - list of the protobuf include paths.
|
|
|
|
# GENERATED_FILES - list of files that are expected
|
|
|
|
# to be genreated by the custom generator plugin.
|
2023-05-31 08:04:05 +00:00
|
|
|
# OPTIONS - list of the generator-specific options.
|
2022-11-21 17:31:49 +00:00
|
|
|
function(_qt_internal_protoc_generate target generator output_directory)
|
2023-05-31 08:04:05 +00:00
|
|
|
cmake_parse_arguments(arg "" "" "PROTO_FILES;PROTO_INCLUDES;GENERATED_FILES;OPTIONS" ${ARGN})
|
2022-11-21 17:31:49 +00:00
|
|
|
|
|
|
|
if(NOT arg_PROTO_FILES)
|
|
|
|
message(FATAL_ERROR "PROTO_FILES list is empty.")
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2023-02-10 10:29:56 +00:00
|
|
|
set(proto_includes "")
|
2022-11-21 17:31:49 +00:00
|
|
|
if(arg_PROTO_INCLUDES)
|
|
|
|
set(proto_includes "${arg_PROTO_INCLUDES}")
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
if(NOT arg_GENERATED_FILES)
|
|
|
|
message(FATAL_ERROR
|
|
|
|
"List of generated sources for target '${target}' is empty")
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2023-05-31 08:04:05 +00:00
|
|
|
set(generated_files "${arg_GENERATED_FILES}")
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
get_filename_component(output_directory "${output_directory}" REALPATH)
|
2023-01-04 09:54:16 +00:00
|
|
|
get_target_property(is_generator_imported ${QT_CMAKE_EXPORT_NAMESPACE}::${generator} IMPORTED)
|
|
|
|
if(QT_INTERNAL_AVOID_USING_PROTOBUF_TMP_OUTPUT_DIR OR is_generator_imported)
|
|
|
|
set(tmp_output_directory "${output_directory}")
|
|
|
|
else()
|
|
|
|
set(tmp_output_directory "${output_directory}/.tmp")
|
|
|
|
endif()
|
|
|
|
file(MAKE_DIRECTORY ${tmp_output_directory})
|
2022-10-05 17:11:31 +00:00
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
unset(num_deps)
|
|
|
|
if(TARGET ${target})
|
|
|
|
get_target_property(num_deps ${target} _qt_${generator}_deps_num)
|
|
|
|
endif()
|
|
|
|
if(NOT num_deps)
|
|
|
|
set(num_deps 0)
|
|
|
|
endif()
|
|
|
|
set(deps_target ${target}_${generator}_deps_${num_deps})
|
|
|
|
math(EXPR num_deps "${num_deps} + 1")
|
|
|
|
|
|
|
|
set(generator_file $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::${generator}>)
|
2022-10-05 17:11:31 +00:00
|
|
|
|
2023-02-10 10:29:56 +00:00
|
|
|
set(proto_includes_string "")
|
2022-11-21 17:31:49 +00:00
|
|
|
if(proto_includes)
|
2023-02-10 10:29:56 +00:00
|
|
|
list(JOIN proto_includes "$<SEMICOLON>" proto_includes)
|
|
|
|
set(proto_includes_genex "$<GENEX_EVAL:${proto_includes}>")
|
|
|
|
set(proto_includes_condition "$<BOOL:${proto_includes_genex}>")
|
|
|
|
string(JOIN "" proto_includes_string
|
|
|
|
"$<${proto_includes_condition}:"
|
|
|
|
"-I$<JOIN:${proto_includes_genex},\\$<SEMICOLON>-I>"
|
|
|
|
">"
|
|
|
|
)
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
2022-11-21 17:31:49 +00:00
|
|
|
list(JOIN arg_PROTO_FILES "\\$<SEMICOLON>" proto_files_string)
|
2023-05-31 08:04:05 +00:00
|
|
|
if(arg_OPTIONS)
|
|
|
|
list(JOIN arg_OPTIONS "\\\\$<SEMICOLON>" generation_options_string)
|
|
|
|
else()
|
|
|
|
set(generation_options_string "")
|
|
|
|
endif()
|
2022-11-21 17:31:49 +00:00
|
|
|
string(JOIN "\\$<SEMICOLON>" protoc_arguments
|
|
|
|
"--plugin=protoc-gen-${generator}=${generator_file}"
|
2023-01-04 09:54:16 +00:00
|
|
|
"--${generator}_out=${tmp_output_directory}"
|
2022-11-21 17:31:49 +00:00
|
|
|
"--${generator}_opt=${generation_options_string}"
|
|
|
|
"${proto_files_string}"
|
|
|
|
"${proto_includes_string}"
|
|
|
|
)
|
2023-01-04 09:54:16 +00:00
|
|
|
|
|
|
|
unset(extra_copy_commands)
|
|
|
|
if(NOT tmp_output_directory STREQUAL output_directory)
|
|
|
|
foreach(f IN LISTS generated_files)
|
|
|
|
get_filename_component(filename "${f}" NAME)
|
|
|
|
if(IS_ABSOLUTE "${f}")
|
|
|
|
file(RELATIVE_PATH f_rel "${output_directory}" "${f}")
|
|
|
|
else()
|
|
|
|
message(AUTHOR_WARNING
|
|
|
|
"Path to the generated file ${f} should be absolute, when \
|
|
|
|
calling _qt_internal_protoc_generate"
|
|
|
|
)
|
|
|
|
endif()
|
|
|
|
list(APPEND extra_copy_commands COMMAND
|
|
|
|
${CMAKE_COMMAND} -E copy_if_different "${tmp_output_directory}/${f_rel}" "${f}")
|
|
|
|
endforeach()
|
|
|
|
endif()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
add_custom_command(OUTPUT ${generated_files}
|
|
|
|
COMMAND ${CMAKE_COMMAND}
|
|
|
|
-DPROTOC_EXECUTABLE=$<TARGET_FILE:WrapProtoc::WrapProtoc>
|
2023-08-25 16:27:40 +00:00
|
|
|
"-DPROTOC_ARGS=${protoc_arguments}"
|
2022-11-21 17:31:49 +00:00
|
|
|
-DWORKING_DIRECTORY=${output_directory}
|
|
|
|
-DGENERATOR_NAME=${generator}
|
|
|
|
-P
|
|
|
|
${__qt_protobuf_macros_module_base_dir}/QtProtocCommandWrapper.cmake
|
2023-01-04 09:54:16 +00:00
|
|
|
${extra_copy_commands}
|
2022-11-21 17:31:49 +00:00
|
|
|
WORKING_DIRECTORY ${output_directory}
|
|
|
|
DEPENDS
|
|
|
|
${QT_CMAKE_EXPORT_NAMESPACE}::${generator}
|
|
|
|
${proto_files}
|
|
|
|
COMMENT "Generating QtProtobuf ${target} sources for ${generator}..."
|
|
|
|
COMMAND_EXPAND_LISTS
|
|
|
|
VERBATIM
|
|
|
|
)
|
|
|
|
add_custom_target(${deps_target} DEPENDS ${generated_files})
|
|
|
|
set_property(TARGET ${target} APPEND PROPERTY
|
|
|
|
AUTOGEN_TARGET_DEPENDS "${deps_target}")
|
|
|
|
set_property(TARGET ${target} PROPERTY _qt_${generator}_deps_num "${num_deps}")
|
|
|
|
set_source_files_properties(${generated_files} PROPERTIES
|
|
|
|
GENERATED TRUE
|
|
|
|
)
|
|
|
|
|
|
|
|
target_include_directories(${target} PUBLIC "$<BUILD_INTERFACE:${output_directory}>")
|
|
|
|
endfunction()
|
|
|
|
|
2023-05-30 15:49:22 +00:00
|
|
|
# The function looks for the enum and message definitions inside provided proto files and returns
|
|
|
|
# list of the absolute .proto file paths, protobuf include paths and packages found here.
|
|
|
|
function(_qt_internal_protobuf_preparse_proto_files target base_dir
|
|
|
|
out_proto_files out_proto_includes out_proto_packages)
|
|
|
|
|
|
|
|
set(proto_files "")
|
|
|
|
set(proto_includes "")
|
2023-05-11 10:36:38 +00:00
|
|
|
set(proto_packages "")
|
2023-05-30 15:49:22 +00:00
|
|
|
foreach(f IN LISTS ARGN)
|
2022-11-21 17:31:49 +00:00
|
|
|
if(NOT IS_ABSOLUTE "${f}")
|
|
|
|
set(f "${base_dir}/${f}")
|
|
|
|
get_filename_component(f "${f}" ABSOLUTE)
|
|
|
|
endif()
|
|
|
|
get_filename_component(f "${f}" REALPATH)
|
2023-05-30 15:49:22 +00:00
|
|
|
|
|
|
|
if("${f}" IN_LIST proto_files)
|
|
|
|
message(WARNING "The .proto file ${f} is listed twice for ${target}."
|
|
|
|
" Skip processing for the second time.")
|
|
|
|
continue()
|
|
|
|
endif()
|
2022-11-21 17:31:49 +00:00
|
|
|
|
|
|
|
_qt_internal_preparse_proto_file_common(result proto_package "${f}" "message;enum")
|
|
|
|
if(NOT result)
|
|
|
|
message(STATUS "No messages or enums found in ${f}. Skipping.")
|
2023-05-30 15:49:22 +00:00
|
|
|
continue()
|
2022-11-21 17:31:49 +00:00
|
|
|
endif()
|
|
|
|
|
|
|
|
get_filename_component(proto_file_base_dir "${f}" DIRECTORY)
|
2023-05-30 15:49:22 +00:00
|
|
|
list(APPEND proto_files "${f}")
|
|
|
|
list(APPEND proto_includes "${proto_file_base_dir}")
|
|
|
|
list(APPEND proto_packages "${proto_package}")
|
2022-11-21 17:31:49 +00:00
|
|
|
endforeach()
|
2023-05-11 10:36:38 +00:00
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
set(${out_proto_files} "${proto_files}" PARENT_SCOPE)
|
|
|
|
set(${out_proto_includes} "${proto_includes}" PARENT_SCOPE)
|
2023-05-30 15:49:22 +00:00
|
|
|
set(${out_proto_packages} "${proto_packages}" PARENT_SCOPE)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(_qt_internal_protobuf_package_qml_uri out_uri)
|
|
|
|
list(REMOVE_DUPLICATES ARGN)
|
|
|
|
list(LENGTH ARGN length)
|
|
|
|
if(NOT length EQUAL 1)
|
|
|
|
string(JOIN "\n" proto_packages_string "${ARGN}")
|
|
|
|
message(FATAL_ERROR "All *.proto files must have single package name,"
|
|
|
|
" that will be used for QML plugin registration."
|
|
|
|
"\nThe following packages found in the .proto files for ${target}:"
|
|
|
|
"\n${proto_packages_string}."
|
|
|
|
" Please split the ${target} target per package."
|
|
|
|
)
|
|
|
|
endif()
|
|
|
|
list(GET ARGN 0 qml_uri)
|
|
|
|
set(${out_uri} ${qml_uri} PARENT_SCOPE)
|
2022-11-21 17:31:49 +00:00
|
|
|
endfunction()
|
|
|
|
|
|
|
|
# TODO Qt6:
|
|
|
|
# - Collect PROTO_INCLUDES from the LINK_LIBRARIES property of TARGET
|
|
|
|
# - Collect proto files from the source files of the ${TARGET}
|
|
|
|
|
|
|
|
# This function is currently in Technical Preview
|
|
|
|
# Its signature and behavior might change.
|
|
|
|
function(qt6_add_protobuf target)
|
|
|
|
_qt_internal_get_protoc_common_options(protoc_option_opt protoc_single_opt protoc_multi_opt)
|
|
|
|
_qt_internal_get_protoc_generate_arguments(protoc_option_arg protoc_single_arg protoc_multi_arg)
|
|
|
|
|
|
|
|
set(option_args
|
|
|
|
${protoc_option_opt}
|
|
|
|
${protoc_option_arg}
|
|
|
|
)
|
|
|
|
|
|
|
|
set(single_args
|
|
|
|
${protoc_single_opt}
|
|
|
|
${protoc_single_arg}
|
|
|
|
)
|
2022-10-05 17:11:31 +00:00
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
set(multi_args
|
|
|
|
${protoc_multi_opt}
|
|
|
|
${protoc_multi_arg}
|
|
|
|
)
|
|
|
|
cmake_parse_arguments(arg "${option_args}" "${single_args}" "${multi_args}" ${ARGN})
|
|
|
|
|
|
|
|
_qt_internal_get_protoc_options(generation_options arg
|
|
|
|
protoc_option_opt protoc_single_opt protoc_multi_opt)
|
|
|
|
|
2023-05-11 10:36:38 +00:00
|
|
|
if(arg_QML_URI AND NOT arg_QML)
|
|
|
|
message(FATAL_ERROR "QML_URI requires the QML option set, "
|
|
|
|
"but the QML argument is not provided.")
|
|
|
|
endif()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
if(arg_PROTO_FILES_BASE_DIR)
|
|
|
|
set(base_dir "${arg_PROTO_FILES_BASE_DIR}")
|
|
|
|
else()
|
|
|
|
set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
|
|
endif()
|
2023-05-30 15:49:22 +00:00
|
|
|
|
|
|
|
_qt_internal_protobuf_preparse_proto_files(${target}
|
|
|
|
"${base_dir}"
|
|
|
|
proto_files proto_includes proto_packages
|
|
|
|
${arg_PROTO_FILES}
|
|
|
|
)
|
|
|
|
|
|
|
|
set(output_directory "${CMAKE_CURRENT_BINARY_DIR}")
|
|
|
|
if(DEFINED arg_OUTPUT_DIRECTORY)
|
|
|
|
set(output_directory "${arg_OUTPUT_DIRECTORY}")
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
2023-04-06 14:02:29 +00:00
|
|
|
|
2023-07-25 10:42:21 +00:00
|
|
|
set(extra_include_directories "")
|
2023-05-30 15:49:22 +00:00
|
|
|
set(cpp_sources "")
|
|
|
|
set(idx 0)
|
|
|
|
foreach(f IN LISTS proto_files)
|
|
|
|
if(arg_GENERATE_PACKAGE_SUBFOLDERS)
|
|
|
|
if(proto_packages)
|
|
|
|
list(GET proto_packages ${idx} package)
|
|
|
|
else()
|
|
|
|
set(package "")
|
|
|
|
endif()
|
|
|
|
string(REPLACE "." "/" package_full_path "${package}/")
|
|
|
|
math(EXPR idx "${idx} + 1")
|
2023-07-25 10:42:21 +00:00
|
|
|
list(APPEND extra_include_directories
|
|
|
|
"$<BUILD_INTERFACE:${output_directory}/${package_full_path}>")
|
2023-05-30 15:49:22 +00:00
|
|
|
else()
|
|
|
|
set(package_full_path "")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
get_filename_component(basename "${f}" NAME_WLE)
|
|
|
|
list(APPEND cpp_sources
|
|
|
|
"${output_directory}/${package_full_path}${basename}.qpb.h"
|
|
|
|
"${output_directory}/${package_full_path}${basename}.qpb.cpp"
|
|
|
|
)
|
|
|
|
|
|
|
|
list(APPEND type_registrations
|
|
|
|
"${output_directory}/${package_full_path}${basename}_protobuftyperegistrations.cpp")
|
|
|
|
endforeach()
|
|
|
|
|
|
|
|
set(qml_sources "")
|
2023-04-06 14:02:29 +00:00
|
|
|
if(arg_QML)
|
2023-05-30 15:49:22 +00:00
|
|
|
if(arg_QML_URI)
|
|
|
|
set(qml_uri "${arg_QML_URI}")
|
|
|
|
elseif(proto_packages)
|
|
|
|
_qt_internal_protobuf_package_qml_uri(qml_uri ${proto_packages})
|
|
|
|
else()
|
|
|
|
message(FATAL_ERROR ".proto files of ${target} don't specify a package."
|
|
|
|
" Please, set QML_URI when using .proto without package name."
|
|
|
|
)
|
|
|
|
endif()
|
|
|
|
list(APPEND generation_options "QML_URI=${qml_uri}")
|
2023-04-06 14:02:29 +00:00
|
|
|
endif()
|
2023-05-30 15:49:22 +00:00
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
if(arg_PROTO_INCLUDES)
|
|
|
|
list(APPEND proto_includes ${arg_PROTO_INCLUDES})
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2023-07-06 15:19:38 +00:00
|
|
|
if(NOT TARGET ${target})
|
2022-11-21 17:31:49 +00:00
|
|
|
_qt_internal_add_library(${target})
|
|
|
|
if(DEFINED arg_OUTPUT_TARGETS)
|
|
|
|
list(APPEND ${arg_OUTPUT_TARGETS} "${target}")
|
|
|
|
endif()
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2023-07-26 14:05:22 +00:00
|
|
|
foreach(f ${proto_files})
|
|
|
|
_qt_internal_expose_source_file_to_ide(${target} ${f})
|
|
|
|
endforeach()
|
|
|
|
|
2023-07-06 15:19:38 +00:00
|
|
|
set(is_shared FALSE)
|
|
|
|
set(is_static FALSE)
|
|
|
|
set(is_executable FALSE)
|
|
|
|
get_target_property(target_type ${target} TYPE)
|
|
|
|
if(target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY")
|
|
|
|
set(is_shared TRUE)
|
|
|
|
elseif(target_type STREQUAL "STATIC_LIBRARY")
|
|
|
|
set(is_static TRUE)
|
|
|
|
elseif(target_type STREQUAL "EXECUTABLE")
|
|
|
|
set(is_executable TRUE)
|
|
|
|
else()
|
|
|
|
message(FATAL_ERROR "Unsupported target type '${target_type}'.")
|
|
|
|
endif()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
if(is_static OR is_shared)
|
|
|
|
# Add EXPORT_MACRO if the target is, or we will create, a shared library
|
|
|
|
string(TOUPPER "${target}" target_upper)
|
2023-10-10 17:36:57 +00:00
|
|
|
string(TOLOWER "${target}" target_lower)
|
2022-11-21 17:31:49 +00:00
|
|
|
if (is_shared)
|
|
|
|
list(APPEND generation_options "EXPORT_MACRO=${target_upper}")
|
2023-10-10 17:36:57 +00:00
|
|
|
get_target_property(export_name ${target} _qt_internal_protobuf_export_file)
|
|
|
|
if(NOT export_name)
|
|
|
|
set(export_name "${output_directory}/${target_lower}_exports.qpb.h")
|
|
|
|
get_property(existing_exports GLOBAL PROPERTY
|
|
|
|
_qt_internal_existing_protobuf_exports)
|
|
|
|
if("${export_name}" IN_LIST existing_exports)
|
|
|
|
message(FATAL_ERROR "The export file ${export_name} is generated by multiple
|
|
|
|
targets, which is prohibited, please make sure that you have unique target
|
|
|
|
names.")
|
|
|
|
endif()
|
|
|
|
set_property(GLOBAL APPEND PROPERTY _qt_internal_existing_protobuf_exports
|
|
|
|
"${export_name}")
|
|
|
|
set_target_properties(${target} PROPERTIES _qt_internal_protobuf_export_file
|
|
|
|
"${export_name}")
|
|
|
|
list(APPEND cpp_sources ${export_name})
|
|
|
|
endif()
|
2022-11-21 17:31:49 +00:00
|
|
|
endif()
|
|
|
|
# Define this so we can conditionally set the export macro
|
|
|
|
target_compile_definitions(${target}
|
|
|
|
PRIVATE "QT_BUILD_${target_upper}_LIB")
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
_qt_internal_protoc_generate(${target} qtprotobufgen "${output_directory}"
|
|
|
|
PROTO_FILES ${proto_files}
|
|
|
|
PROTO_INCLUDES ${proto_includes}
|
2023-05-30 15:49:22 +00:00
|
|
|
GENERATED_FILES ${cpp_sources} ${qml_sources} ${type_registrations}
|
2023-05-31 08:04:05 +00:00
|
|
|
OPTIONS ${generation_options}
|
2022-10-05 17:11:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# Filter generated headers
|
|
|
|
unset(generated_headers)
|
2023-05-30 15:49:22 +00:00
|
|
|
foreach(generated_file IN LISTS cpp_sources)
|
2022-10-05 17:11:31 +00:00
|
|
|
get_filename_component(extension "${generated_file}" LAST_EXT)
|
|
|
|
if(extension STREQUAL ".h")
|
|
|
|
list(APPEND generated_headers "${generated_file}")
|
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
|
2023-05-30 15:49:22 +00:00
|
|
|
target_sources(${target} PRIVATE ${cpp_sources} ${qml_sources})
|
2022-10-05 17:11:31 +00:00
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
if(is_static OR is_shared)
|
|
|
|
set_target_properties(${target}
|
|
|
|
PROPERTIES
|
|
|
|
AUTOMOC ON
|
|
|
|
)
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
|
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
|
|
target_compile_options(${target}
|
|
|
|
PRIVATE "/Zc:__cplusplus" "/permissive-" "/bigobj")
|
|
|
|
endif()
|
|
|
|
|
2023-07-25 10:42:21 +00:00
|
|
|
# TODO: adding these include paths might cause the ambiguous include handling if
|
|
|
|
# two different packages contain messages with the same name. This should be fixed
|
|
|
|
# in moc and qmltypesregistar, see QTBUG-115499.
|
|
|
|
target_include_directories(${target} PRIVATE ${extra_include_directories})
|
2022-10-05 17:11:31 +00:00
|
|
|
target_link_libraries(${target} PRIVATE
|
|
|
|
${QT_CMAKE_EXPORT_NAMESPACE}::Protobuf
|
|
|
|
)
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
if(is_static OR (WIN32 AND NOT is_executable))
|
2022-10-05 17:11:31 +00:00
|
|
|
if(TARGET ${target}_protobuf_registration)
|
2023-05-30 15:49:22 +00:00
|
|
|
target_sources(${target}_protobuf_registration PRIVATE ${type_registrations})
|
2022-10-05 17:11:31 +00:00
|
|
|
else()
|
2023-05-30 15:49:22 +00:00
|
|
|
add_library(${target}_protobuf_registration OBJECT ${type_registrations})
|
2022-10-05 17:11:31 +00:00
|
|
|
target_link_libraries(${target}
|
|
|
|
INTERFACE "$<TARGET_OBJECTS:$<TARGET_NAME:${target}_protobuf_registration>>")
|
|
|
|
add_dependencies(${target} ${target}_protobuf_registration)
|
|
|
|
|
|
|
|
target_include_directories(${target}_protobuf_registration
|
2023-07-25 10:42:21 +00:00
|
|
|
PRIVATE "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>>")
|
2022-10-05 17:11:31 +00:00
|
|
|
target_link_libraries(${target}_protobuf_registration
|
|
|
|
PRIVATE
|
|
|
|
${QT_CMAKE_EXPORT_NAMESPACE}::Platform
|
|
|
|
${QT_CMAKE_EXPORT_NAMESPACE}::Protobuf
|
2023-06-28 14:24:11 +00:00
|
|
|
$<GENEX_EVAL:$<TARGET_PROPERTY:${target},LINK_LIBRARIES>>
|
2022-10-05 17:11:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
|
|
target_compile_options(${target}_protobuf_registration
|
|
|
|
PRIVATE "/Zc:__cplusplus" "/permissive-" "/bigobj")
|
|
|
|
endif()
|
|
|
|
endif()
|
2022-12-06 14:42:56 +00:00
|
|
|
if(DEFINED arg_OUTPUT_TARGETS)
|
|
|
|
list(APPEND ${arg_OUTPUT_TARGETS}
|
2022-10-05 17:11:31 +00:00
|
|
|
"${target}_protobuf_registration")
|
|
|
|
endif()
|
|
|
|
else()
|
2023-05-30 15:49:22 +00:00
|
|
|
target_sources(${target} PRIVATE ${type_registrations})
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
|
2023-05-11 10:36:38 +00:00
|
|
|
if(arg_QML)
|
2023-07-19 17:26:47 +00:00
|
|
|
string(REPLACE "." "/" qml_module_output_path "${qml_uri}")
|
|
|
|
set(qml_module_output_full_path "${CMAKE_CURRENT_BINARY_DIR}/${qml_module_output_path}")
|
|
|
|
|
2023-05-11 10:36:38 +00:00
|
|
|
qt_policy(SET QTP0001 NEW)
|
|
|
|
qt6_add_qml_module(${target}
|
|
|
|
URI ${qml_uri}
|
2023-07-19 17:26:47 +00:00
|
|
|
PLUGIN_TARGET "${target}plugin"
|
2023-05-11 10:36:38 +00:00
|
|
|
VERSION 1.0
|
2023-07-19 17:26:47 +00:00
|
|
|
OUTPUT_DIRECTORY "${qml_module_output_full_path}"
|
2023-05-11 10:36:38 +00:00
|
|
|
)
|
2023-07-19 17:26:47 +00:00
|
|
|
set_target_properties(${target}plugin
|
|
|
|
PROPERTIES
|
|
|
|
AUTOMOC ON
|
|
|
|
)
|
|
|
|
target_link_libraries(${target}plugin PRIVATE
|
|
|
|
${QT_CMAKE_EXPORT_NAMESPACE}::Protobuf
|
|
|
|
)
|
|
|
|
|
|
|
|
list(APPEND ${arg_OUTPUT_TARGETS} ${target}plugin)
|
|
|
|
endif()
|
|
|
|
|
|
|
|
if(DEFINED arg_OUTPUT_HEADERS)
|
|
|
|
set(${arg_OUTPUT_HEADERS} "${generated_headers}" PARENT_SCOPE)
|
|
|
|
endif()
|
|
|
|
|
|
|
|
if(DEFINED arg_OUTPUT_TARGETS)
|
|
|
|
set(${arg_OUTPUT_TARGETS} "${${arg_OUTPUT_TARGETS}}" PARENT_SCOPE)
|
2023-05-11 10:36:38 +00:00
|
|
|
endif()
|
2022-10-05 17:11:31 +00:00
|
|
|
endfunction()
|
|
|
|
|
|
|
|
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
|
|
|
function(qt_add_protobuf)
|
|
|
|
if(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
|
|
|
|
qt6_add_protobuf(${ARGN})
|
|
|
|
else()
|
|
|
|
message(FATAL_ERROR "qt6_add_protobuf() is only available in Qt 6. "
|
|
|
|
"Please check the protobuf documentation for alternatives.")
|
|
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
endif()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
# The common parsing function looking for the 'lookup_keys' definitions inside the 'proto_file'.
|
|
|
|
# The function sets the 'out_result' variable to true if one of 'lookup_keys' is found. Also the
|
|
|
|
# function writes to the 'out_package' variable the package name that the .proto file belongs to.
|
|
|
|
function(_qt_internal_preparse_proto_file_common out_result out_package proto_file lookup_keys)
|
2022-10-05 17:11:31 +00:00
|
|
|
if(NOT proto_file OR NOT EXISTS "${proto_file}")
|
|
|
|
message(FATAL_ERROR "Unable to scan '${proto_file}': file doesn't exist.")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
file(READ "${proto_file}" file_content)
|
|
|
|
if(NOT file_content)
|
|
|
|
message(FATAL_ERROR "Unable to read ${proto_file}, or file is empty.")
|
|
|
|
endif()
|
|
|
|
|
2023-08-18 10:55:46 +00:00
|
|
|
string(REPLACE "[" "" file_content "${file_content}")
|
|
|
|
string(REPLACE "]" "" file_content "${file_content}")
|
2022-10-05 17:11:31 +00:00
|
|
|
string(REPLACE ";" "[[;]]" file_content "${file_content}")
|
|
|
|
string(REGEX REPLACE "([^\t \n]+[\t ]*)}" "\\1;}" file_content "${file_content}")
|
|
|
|
string(REGEX REPLACE "{([\t ]*[^\t \n]+)" "{;\\1" file_content "${file_content}")
|
|
|
|
string(REPLACE "\n" ";" file_content "${file_content}")
|
|
|
|
set(proto_key_common_regex "[\t ]+([a-zA-Z0-9_]+)")
|
|
|
|
|
|
|
|
set(unclosed_braces 0)
|
|
|
|
set(in_message_scope FALSE)
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
set(found_key FALSE)
|
|
|
|
list(JOIN lookup_keys "|" lookup_keys_regex)
|
2022-10-05 17:11:31 +00:00
|
|
|
foreach(item IN LISTS file_content)
|
|
|
|
if(item MATCHES "^[\t ]*package[\t ]+([a-zA-Z0-9_.-]+)")
|
|
|
|
set(proto_package "${CMAKE_MATCH_1}")
|
2022-11-21 17:31:49 +00:00
|
|
|
elseif(item MATCHES "^[\t ]*(${lookup_keys_regex})${proto_key_common_regex}")
|
|
|
|
set(found_key TRUE)
|
|
|
|
break()
|
2022-10-05 17:11:31 +00:00
|
|
|
endif()
|
|
|
|
if(in_message_scope)
|
|
|
|
if(item MATCHES "[^/]*\\{")
|
|
|
|
math(EXPR unclosed_braces "${unclosed_braces} + 1")
|
|
|
|
endif()
|
|
|
|
if(item MATCHES "[^/]*\\}")
|
|
|
|
math(EXPR unclosed_braces "${unclosed_braces} - 1")
|
|
|
|
if(unclosed_braces EQUAL 0)
|
|
|
|
set(in_message_scope FALSE)
|
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
|
2022-11-21 17:31:49 +00:00
|
|
|
set(${out_package} "${proto_package}" PARENT_SCOPE)
|
|
|
|
set(${out_result} "${found_key}" PARENT_SCOPE)
|
2022-10-05 17:11:31 +00:00
|
|
|
endfunction()
|