Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_protobuf_compiler / proto.cmake
1 # Copyright 2020 The Pigweed Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 # use this file except in compliance with the License. You may obtain a copy of
5 # the License at
6 #
7 #     https://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations under
13 # the License.
14 include_guard(GLOBAL)
15
16 # Declares a protocol buffers library. This function creates a library for each
17 # supported protocol buffer implementation:
18 #
19 #   ${NAME}.pwpb - pw_protobuf generated code
20 #   ${NAME}.nanopb - Nanopb generated code (requires Nanopb)
21 #
22 # This function also creates libraries for generating pw_rpc code:
23 #
24 #   ${NAME}.nanopb_rpc - generates Nanopb pw_rpc code
25 #   ${NAME}.raw_rpc - generates raw pw_rpc (no protobuf library) code
26 #   ${NAME}.pwpb_rpc - (Not implemented) generates pw_protobuf pw_rpc code
27 #
28 # Args:
29 #
30 #   NAME - the base name of the libraries to create
31 #   SOURCES - .proto source files
32 #   DEPS - dependencies on other pw_proto_library targets
33 #
34 function(pw_proto_library NAME)
35   cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "SOURCES;DEPS")
36
37   set(out_dir "${CMAKE_CURRENT_BINARY_DIR}/protos")
38
39   # Use INTERFACE libraries to track the proto include paths that are passed to
40   # protoc.
41   set(include_deps "${arg_DEPS}")
42   list(TRANSFORM include_deps APPEND ._includes)
43
44   add_library("${NAME}._includes" INTERFACE)
45   target_include_directories("${NAME}._includes" INTERFACE ".")
46   target_link_libraries("${NAME}._includes" INTERFACE ${include_deps})
47
48   # Generate a file with all include paths needed by protoc.
49   set(include_file "${out_dir}/${NAME}.include_paths.txt")
50   file(GENERATE OUTPUT "${include_file}"
51      CONTENT
52        "$<TARGET_PROPERTY:${NAME}._includes,INTERFACE_INCLUDE_DIRECTORIES>")
53
54   # Create a protobuf target for each supported protobuf library.
55   _pw_pwpb_library(
56       "${NAME}" "${arg_SOURCES}" "${arg_DEPS}" "${include_file}" "${out_dir}")
57   _pw_raw_rpc_library(
58       "${NAME}" "${arg_SOURCES}" "${arg_DEPS}" "${include_file}" "${out_dir}")
59   _pw_nanopb_library(
60       "${NAME}" "${arg_SOURCES}" "${arg_DEPS}" "${include_file}" "${out_dir}")
61   _pw_nanopb_rpc_library(
62       "${NAME}" "${arg_SOURCES}" "${arg_DEPS}" "${include_file}" "${out_dir}")
63 endfunction(pw_proto_library)
64
65 # Internal function that invokes protoc through generate_protos.py.
66 function(_pw_generate_protos
67       TARGET LANGUAGE PLUGIN OUTPUT_EXTS INCLUDE_FILE OUT_DIR SOURCES DEPS)
68   # Determine the names of the output files.
69   foreach(extension IN LISTS OUTPUT_EXTS)
70     foreach(source_file IN LISTS SOURCES)
71       get_filename_component(dir "${source_file}" DIRECTORY)
72       get_filename_component(name "${source_file}" NAME_WE)
73       list(APPEND outputs "${OUT_DIR}/${dir}/${name}${extension}")
74     endforeach()
75   endforeach()
76
77   # Export the output files to the caller's scope so it can use them if needed.
78   set(generated_outputs "${outputs}" PARENT_SCOPE)
79
80   if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
81       get_filename_component(dir "${source_file}" DIRECTORY)
82       get_filename_component(name "${source_file}" NAME_WE)
83       set(PLUGIN "${dir}/${name}.bat")
84   endif()
85
86   set(script "$ENV{PW_ROOT}/pw_protobuf_compiler/py/pw_protobuf_compiler/generate_protos.py")
87   add_custom_command(
88     COMMAND
89       python
90       "${script}"
91       --language "${LANGUAGE}"
92       --plugin-path "${PLUGIN}"
93       --include-path "${CMAKE_CURRENT_SOURCE_DIR}"
94       --include-file "${INCLUDE_FILE}"
95       --out-dir "${OUT_DIR}"
96       ${ARGN}
97       ${SOURCES}
98     DEPENDS
99       ${SOURCES}
100       ${script}
101       ${DEPS}
102     OUTPUT
103       ${outputs}
104   )
105   add_custom_target("${TARGET}" DEPENDS ${outputs})
106 endfunction(_pw_generate_protos)
107
108 # Internal function that creates a pwpb proto library.
109 function(_pw_pwpb_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
110   list(TRANSFORM DEPS APPEND .pwpb)
111
112   _pw_generate_protos("${NAME}.generate.pwpb"
113       pwpb
114       "$ENV{PW_ROOT}/pw_protobuf/py/pw_protobuf/plugin.py"
115       ".pwpb.h"
116       "${INCLUDE_FILE}"
117       "${OUT_DIR}"
118       "${SOURCES}"
119       "${DEPS}"
120   )
121
122   # Create the library with the generated source files.
123   add_library("${NAME}.pwpb" INTERFACE)
124   target_include_directories("${NAME}.pwpb" INTERFACE "${OUT_DIR}")
125   target_link_libraries("${NAME}.pwpb" INTERFACE pw_protobuf ${DEPS})
126   add_dependencies("${NAME}.pwpb" "${NAME}.generate.pwpb")
127 endfunction(_pw_pwpb_library)
128
129 # Internal function that creates a raw_rpc proto library.
130 function(_pw_raw_rpc_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
131   list(TRANSFORM DEPS APPEND .raw_rpc)
132
133   _pw_generate_protos("${NAME}.generate.raw_rpc"
134       raw_rpc
135       "$ENV{PW_ROOT}/pw_rpc/py/pw_rpc/plugin_raw.py"
136       ".raw_rpc.pb.h"
137       "${INCLUDE_FILE}"
138       "${OUT_DIR}"
139       "${SOURCES}"
140       "${DEPS}"
141   )
142
143   # Create the library with the generated source files.
144   add_library("${NAME}.raw_rpc" INTERFACE)
145   target_include_directories("${NAME}.raw_rpc" INTERFACE "${OUT_DIR}")
146   target_link_libraries("${NAME}.raw_rpc"
147     INTERFACE
148       pw_rpc.raw
149       pw_rpc.server
150       ${DEPS}
151   )
152   add_dependencies("${NAME}.raw_rpc" "${NAME}.generate.raw_rpc")
153 endfunction(_pw_raw_rpc_library)
154
155 # Internal function that creates a nanopb proto library.
156 function(_pw_nanopb_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
157   list(TRANSFORM DEPS APPEND .nanopb)
158
159   set(nanopb_dir "$<TARGET_PROPERTY:$<IF:$<TARGET_EXISTS:protobuf-nanopb-static>,protobuf-nanopb-static,pw_build.empty>,SOURCE_DIR>")
160   set(nanopb_plugin
161       "$<IF:$<TARGET_EXISTS:protobuf-nanopb-static>,${nanopb_dir}/generator/protoc-gen-nanopb,COULD_NOT_FIND_protobuf-nanopb-static_TARGET_PLEASE_SET_UP_NANOPB>")
162
163   _pw_generate_protos("${NAME}.generate.nanopb"
164       nanopb
165       "${nanopb_plugin}"
166       ".pb.h;.pb.c"
167       "${INCLUDE_FILE}"
168       "${OUT_DIR}"
169       "${SOURCES}"
170       "${DEPS}"
171   )
172
173   # Create the library with the generated source files.
174   add_library("${NAME}.nanopb" EXCLUDE_FROM_ALL ${generated_outputs})
175   target_include_directories("${NAME}.nanopb" PUBLIC "${OUT_DIR}")
176   target_link_libraries("${NAME}.nanopb" PUBLIC pw_third_party.nanopb ${DEPS})
177   add_dependencies("${NAME}.nanopb" "${NAME}.generate.nanopb")
178 endfunction(_pw_nanopb_library)
179
180 # Internal function that creates a nanopb_rpc library.
181 function(_pw_nanopb_rpc_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
182   # Determine the names of the output files.
183   list(TRANSFORM DEPS APPEND .nanopb_rpc)
184
185   _pw_generate_protos("${NAME}.generate.nanopb_rpc"
186       nanopb_rpc
187       "$ENV{PW_ROOT}/pw_rpc/py/pw_rpc/plugin_nanopb.py"
188       ".rpc.pb.h"
189       "${INCLUDE_FILE}"
190       "${OUT_DIR}"
191       "${SOURCES}"
192       "${DEPS}"
193   )
194
195   # Create the library with the generated source files.
196   add_library("${NAME}.nanopb_rpc" INTERFACE)
197   target_include_directories("${NAME}.nanopb_rpc" INTERFACE "${OUT_DIR}")
198   target_link_libraries("${NAME}.nanopb_rpc"
199     INTERFACE
200       "${NAME}.nanopb"
201       pw_rpc.nanopb.method_union
202       pw_rpc.server
203       ${DEPS}
204   )
205   add_dependencies("${NAME}.nanopb_rpc" "${NAME}.generate.nanopb_rpc")
206 endfunction(_pw_nanopb_rpc_library)