blob: 1966fc7d9c3ca93d5fe13514a54d2c2d56775222 [file] [log] [blame]
Wyatt Heplerc9e51d22020-10-29 09:12:37 -07001# 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.
14include_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#
34function(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}")
63endfunction(pw_proto_library)
64
65# Internal function that invokes protoc through generate_protos.py.
66function(_pw_generate_protos
67 TARGET LANGUAGE INCLUDE_FILE OUT_DIR SOURCES OUTPUTS DEPS)
68 set(script "$ENV{PW_ROOT}/pw_protobuf_compiler/py/pw_protobuf_compiler/generate_protos.py")
69 add_custom_command(
70 COMMAND
71 python
72 "${script}"
73 --language "${LANGUAGE}"
74 --module-path "${CMAKE_CURRENT_SOURCE_DIR}"
75 --include-file "${INCLUDE_FILE}"
76 --out-dir "${OUT_DIR}"
77 ${ARGN}
78 ${SOURCES}
79 DEPENDS
80 ${SOURCES}
81 ${script}
82 ${DEPS}
83 OUTPUT
84 ${outputs}
85 )
86 add_custom_target("${TARGET}" DEPENDS ${outputs})
87endfunction(_pw_generate_protos)
88
89# Internal function that creates a pwpb proto library.
90function(_pw_pwpb_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
91 # Determine the names of the output files.
92 set(outputs "${SOURCES}")
93 list(TRANSFORM outputs REPLACE "\.proto$" ".pwpb.h")
94 list(TRANSFORM outputs PREPEND "${OUT_DIR}/")
95
96 # Make the source paths absolute since they are passed to a script.
97 list(TRANSFORM SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
98
99 list(TRANSFORM DEPS APPEND .pwpb)
100
101 _pw_generate_protos("${NAME}.generate.pwpb"
102 cc
103 "${INCLUDE_FILE}"
104 "${OUT_DIR}"
105 "${SOURCES}"
106 "${outputs}"
107 "${DEPS}"
108 )
109
110 # Create the library with the generated source files.
111 add_library("${NAME}.pwpb" INTERFACE)
112 target_include_directories("${NAME}.pwpb" INTERFACE "${OUT_DIR}")
113 target_link_libraries("${NAME}.pwpb" INTERFACE pw_protobuf ${DEPS})
114 add_dependencies("${NAME}.pwpb" "${NAME}.generate.pwpb")
115endfunction(_pw_pwpb_library)
116
117# Internal function that creates a raw_rpc proto library.
118function(_pw_raw_rpc_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
119 # Determine the names of the output files.
120 set(outputs "${SOURCES}")
121 list(TRANSFORM outputs REPLACE "\.proto$" ".raw_rpc.pb.h")
122 list(TRANSFORM outputs PREPEND "${OUT_DIR}/")
123
124 # Make the source paths absolute since they are passed to a script.
125 list(TRANSFORM SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
126
127 list(TRANSFORM DEPS APPEND .raw_rpc)
128
129 _pw_generate_protos("${NAME}.generate.raw_rpc"
130 raw_rpc
131 "${INCLUDE_FILE}"
132 "${OUT_DIR}"
133 "${SOURCES}"
134 "${outputs}"
135 "${DEPS}"
136 )
137
138 # Create the library with the generated source files.
139 add_library("${NAME}.raw_rpc" INTERFACE)
140 target_include_directories("${NAME}.raw_rpc" INTERFACE "${OUT_DIR}")
141 target_link_libraries("${NAME}.raw_rpc"
142 INTERFACE
143 pw_rpc.raw
144 pw_rpc.server
145 ${DEPS}
146 )
147 add_dependencies("${NAME}.raw_rpc" "${NAME}.generate.raw_rpc")
148endfunction(_pw_raw_rpc_library)
149
150# Internal function that creates a nanopb proto library.
151function(_pw_nanopb_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
152 # Determine the names of the output files.
153 set(outputs_h "${SOURCES}")
154 list(TRANSFORM outputs_h REPLACE "\.proto$" ".pb.h")
155 list(TRANSFORM outputs_h PREPEND "${OUT_DIR}/")
156
157 set(outputs_c "${SOURCES}")
158 list(TRANSFORM outputs_c REPLACE "\.proto$" ".pb.c")
159 list(TRANSFORM outputs_c PREPEND "${OUT_DIR}/")
160
161 set(outputs ${outputs_c} ${outputs_h})
162
163 # Make the source paths absolute since they are passed to a script.
164 list(TRANSFORM SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
165
166 list(TRANSFORM DEPS APPEND .nanopb)
167
168 set(nanopb_dir "$<TARGET_PROPERTY:$<IF:$<TARGET_EXISTS:protobuf-nanopb-static>,protobuf-nanopb-static,pw_build.empty>,SOURCE_DIR>")
169 set(nanopb_plugin
170 "$<IF:$<TARGET_EXISTS:protobuf-nanopb-static>,${nanopb_dir}/generator/protoc-gen-nanopb,COULD_NOT_FIND_protobuf-nanopb-static_TARGET_PLEASE_SET_UP_NANOPB>")
171 if(WIN32)
172 set(nanopb_plugin "${nanopb_plugin}.bat")
173 endif()
174
175 _pw_generate_protos("${NAME}.generate.nanopb"
176 nanopb
177 "${INCLUDE_FILE}"
178 "${OUT_DIR}"
179 "${SOURCES}"
180 "${outputs}"
181 "${DEPS}"
182 --custom-plugin "${nanopb_plugin}"
183 --include-paths "${nanopb_dir}/generator/proto"
184 )
185
186 # Create the library with the generated source files.
187 add_library("${NAME}.nanopb" EXCLUDE_FROM_ALL ${outputs})
188 target_include_directories("${NAME}.nanopb" PUBLIC "${OUT_DIR}")
189 target_link_libraries("${NAME}.nanopb" PUBLIC pw_third_party.nanopb ${DEPS})
190 add_dependencies("${NAME}.nanopb" "${NAME}.generate.nanopb")
191endfunction(_pw_nanopb_library)
192
193# Internal function that creates a nanopb_rpc library.
194function(_pw_nanopb_rpc_library NAME SOURCES DEPS INCLUDE_FILE OUT_DIR)
195 # Determine the names of the output files.
196 set(outputs "${SOURCES}")
197 list(TRANSFORM outputs REPLACE "\.proto$" ".rpc.pb.h")
198 list(TRANSFORM outputs PREPEND "${OUT_DIR}/")
199
200 # Make the source paths absolute since they are passed to a script.
201 list(TRANSFORM SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
202
203 list(TRANSFORM DEPS APPEND .nanopb_rpc)
204
205 _pw_generate_protos("${NAME}.generate.nanopb_rpc"
206 nanopb_rpc
207 "${INCLUDE_FILE}"
208 "${OUT_DIR}"
209 "${SOURCES}"
210 "${outputs}"
211 "${DEPS}"
212 )
213
214 # Create the library with the generated source files.
215 add_library("${NAME}.nanopb_rpc" INTERFACE)
216 target_include_directories("${NAME}.nanopb_rpc" INTERFACE "${OUT_DIR}")
217 target_link_libraries("${NAME}.nanopb_rpc"
218 INTERFACE
219 "${NAME}.nanopb"
Wyatt Heplerdcfa92b2020-11-10 09:47:30 -0800220 pw_rpc.nanopb.method_union
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700221 pw_rpc.server
Wyatt Heplerc9e51d22020-10-29 09:12:37 -0700222 ${DEPS}
223 )
224 add_dependencies("${NAME}.nanopb_rpc" "${NAME}.generate.nanopb_rpc")
225endfunction(_pw_nanopb_rpc_library)