QtPreParseProtoFile.cmake 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. cmake_minimum_required(VERSION 3.16)
  2. function(extract_proto_keys out_var regex file_content)
  3. cmake_parse_arguments(arg "SINGLE_VALUE" "" "" ${ARGN})
  4. endfunction()
  5. if(NOT PROTO_FILE OR NOT EXISTS "${PROTO_FILE}")
  6. message(FATAL_ERROR "Unable to scan '${PROTO_FILE}': file doesn't exist.")
  7. endif()
  8. file(READ "${PROTO_FILE}" file_content)
  9. if(NOT file_content)
  10. message(FATAL_ERROR "Unable to read ${PROTO_FILE}.")
  11. endif()
  12. STRING(REPLACE ";" "\\\\;" file_content "${file_content}")
  13. STRING(REPLACE "\n" ";" file_content "${file_content}")
  14. set(proto_key_common_regex "[\t ]+([a-zA-Z0-9_]+)")
  15. set(unclosed_braces 0)
  16. set(in_message_scope FALSE)
  17. foreach(item IN LISTS file_content)
  18. if(item MATCHES "^[\t ]*package[\t ]+([a-zA-Z0-9_\.\-]+)")
  19. set(proto_package "${CMAKE_MATCH_1}")
  20. elseif(item MATCHES "^[\t ]*message${proto_key_common_regex}")
  21. # Skip adding nested messages to the list.
  22. # Multi-file generator puts the nested messages to the same file as the parent one. So
  23. # generated
  24. if(unclosed_braces EQUAL 0)
  25. list(APPEND proto_messages "${CMAKE_MATCH_1}")
  26. set(in_message_scope TRUE)
  27. endif()
  28. elseif(item MATCHES "^[\t ]*service${proto_key_common_regex}")
  29. list(APPEND proto_services "${CMAKE_MATCH_1}")
  30. elseif(item MATCHES "^[\t ]*enum${proto_key_common_regex}")
  31. list(APPEND proto_enums "${CMAKE_MATCH_1}")
  32. endif()
  33. if(in_message_scope)
  34. if(item MATCHES "[^/]*\\{")
  35. math(EXPR unclosed_braces "${unclosed_braces} + 1")
  36. endif()
  37. if(item MATCHES "[^/]*\\}")
  38. math(EXPR unclosed_braces "${unclosed_braces} - 1")
  39. if(unclosed_braces EQUAL 0)
  40. set(in_message_scope FALSE)
  41. endif()
  42. endif()
  43. endif()
  44. endforeach()
  45. unset(output_files)
  46. string(REPLACE "." "/" package_full_path "${proto_package}")
  47. if(MULTI)
  48. foreach(item IN LISTS proto_messages)
  49. string(TOLOWER "${item}" item)
  50. list(APPEND output_files
  51. "${package_full_path}/${item}.h"
  52. "${package_full_path}/${item}.cpp"
  53. )
  54. endforeach()
  55. foreach(item IN LISTS proto_services)
  56. string(TOLOWER "${item}" item)
  57. list(APPEND output_files
  58. "${package_full_path}/${item}client.h"
  59. "${package_full_path}/${item}client.cpp"
  60. # TODO: Generating of a server side code is not supported yet.
  61. # "${package_full_path}/${item}server.h"
  62. # "${package_full_path}/${item}server.cpp"
  63. )
  64. endforeach()
  65. else()
  66. get_filename_component(basename "${PROTO_FILE}" NAME_WLE)
  67. list(LENGTH proto_messages message_count)
  68. list(LENGTH proto_enums enum_count)
  69. list(LENGTH proto_services service_count)
  70. set(folder_path "")
  71. if(FOLDER)
  72. set(folder_path "${package_full_path}/")
  73. endif()
  74. if(proto_messages OR proto_enums)
  75. list(APPEND output_files
  76. "${folder_path}${basename}.qpb.h"
  77. "${folder_path}${basename}.qpb.cpp"
  78. )
  79. endif()
  80. if(proto_services)
  81. list(APPEND output_files
  82. "${folder_path}${basename}_grpc.qpb.h"
  83. "${folder_path}${basename}_grpc.qpb.cpp"
  84. )
  85. endif()
  86. endif()
  87. message("${output_files}")