blob: f1686e8f57b6518b65a09da1d2cae23669b24164 [file] [log] [blame]
Ben Claytonde2686e2023-11-16 12:39:06 +00001# Copyright 2023 The Dawn & Tint Authors
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are met:
5#
6# 1. Redistributions of source code must retain the above copyright notice, this
7# list of conditions and the following disclaimer.
8#
9# 2. Redistributions in binary form must reproduce the above copyright notice,
10# this list of conditions and the following disclaimer in the documentation
11# and/or other materials provided with the distribution.
12#
13# 3. Neither the name of the copyright holder nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28set(protobuf_INSTALL OFF CACHE BOOL "Install protobuf binaries and files" FORCE)
29set(protobuf_BUILD_CONFORMANCE OFF CACHE BOOL "Build conformance tests" FORCE)
30set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "Build examples" FORCE)
31set(protobuf_BUILD_LIBPROTOC OFF CACHE BOOL "Build libprotoc" FORCE)
32set(protobuf_BUILD_TESTS OFF CACHE BOOL "Controls whether protobuf tests are built" FORCE)
33set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Controls whether a protobuf static runtime is built" FORCE)
34
35set(protobuf_BUILD_PROTOC_BINARIES ON CACHE BOOL "Build libprotoc and protoc compiler" FORCE)
36set(protobuf_DISABLE_RTTI ON CACHE BOOL "Remove runtime type information in the binaries" FORCE)
37
Ben Claytonfb07fa92023-11-17 18:48:59 +000038add_subdirectory("${DAWN_PROTOBUF_DIR}/cmake")
Ben Claytonde2686e2023-11-16 12:39:06 +000039
40target_compile_definitions(libprotobuf PUBLIC "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0")
41
42# A simplified version of protobuf_generate()
43function(generate_protos)
44 set(OPTIONS APPEND_PATH)
45 set(SINGLE_ARGS TARGET LANGUAGE EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS)
46 set(MULTI_ARGS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
47 cmake_parse_arguments(ARGS "${OPTIONS}" "${SINGLE_ARGS}" "${MULTI_ARGS}" "${ARGN}")
48
49 if(NOT ARGS_TARGET)
50 message(FATAL_ERROR "generate_protos called without a target")
51 endif()
52
53 if(NOT ARGS_LANGUAGE)
54 set(ARGS_LANGUAGE cpp)
55 endif()
56 string(TOLOWER ${ARGS_LANGUAGE} ARGS_LANGUAGE)
57
58 if(NOT ARGS_PROTOC_OUT_DIR)
59 set(ARGS_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
60 endif()
61
62 foreach(OPTION ${ARGS_PLUGIN_OPTIONS})
63 # append comma - not using CMake lists and string replacement as users
64 # might have semicolons in options
65 if(PLUGIN_OPTIONS)
66 set( PLUGIN_OPTIONS "${PLUGIN_OPTIONS},")
67 endif()
68 set(PLUGIN_OPTIONS "${PLUGIN_OPTIONS}${OPTION}")
69 endforeach()
70
71 if(ARGS_PLUGIN)
72 set(_plugin "--plugin=${ARGS_PLUGIN}")
73 endif()
74
75 if(NOT ARGS_GENERATE_EXTENSIONS)
76 if(ARGS_LANGUAGE STREQUAL cpp)
77 set(ARGS_GENERATE_EXTENSIONS .pb.h .pb.cc)
78 elseif(ARGS_LANGUAGE STREQUAL python)
79 set(ARGS_GENERATE_EXTENSIONS _pb2.py)
80 else()
81 message(FATAL_ERROR "generate_protos given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS")
82 endif()
83 endif()
84
85 if(ARGS_TARGET)
86 get_target_property(SOURCE_LIST ${ARGS_TARGET} SOURCES)
87 foreach(FILE ${SOURCE_LIST})
88 if(FILE MATCHES ".proto$")
89 list(APPEND PROTO_FILES ${FILE})
90 endif()
91 endforeach()
92 endif()
93
94 if(NOT PROTO_FILES)
95 message(FATAL_ERROR "generate_protos could not find any .proto files")
96 endif()
97
98 if(ARGS_APPEND_PATH)
99 # Create an include path for each file specified
100 foreach(FILE ${PROTO_FILES})
101 get_filename_component(ABS_FILE ${FILE} ABSOLUTE)
102 get_filename_component(ABS_PATH ${ABS_FILE} PATH)
103 list(FIND PROTOBUF_INCLUDE_PATH ${ABS_PATH} FOUND)
104 if(${FOUND} EQUAL -1)
105 list(APPEND PROTOBUF_INCLUDE_PATH -I ${ABS_PATH})
106 endif()
107 endforeach()
108 endif()
109
110 foreach(DIR ${ARGS_IMPORT_DIRS})
111 get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
112 list(FIND PROTOBUF_INCLUDE_PATH ${ABS_PATH} FOUND)
113 if(${FOUND} EQUAL -1)
114 list(APPEND PROTOBUF_INCLUDE_PATH -I ${ABS_PATH})
115 endif()
116 endforeach()
117
118 if(NOT PROTOBUF_INCLUDE_PATH)
119 set(PROTOBUF_INCLUDE_PATH -I ${CMAKE_CURRENT_SOURCE_DIR})
120 endif()
121
122 set(ALL_GENERATED_SRCS)
123 foreach(PROTO_FILE ${PROTO_FILES})
124 get_filename_component(ABS_FILE ${PROTO_FILE} ABSOLUTE)
125 get_filename_component(ABS_DIR ${ABS_FILE} DIRECTORY)
126
127 get_filename_component(FILE_FULL_NAME ${PROTO_FILE} NAME)
128 string(FIND "${FILE_FULL_NAME}" "." FILE_LAST_EXT_POS REVERSE)
129 string(SUBSTRING "${FILE_FULL_NAME}" 0 ${FILE_LAST_EXT_POS} BASENAME)
130
131 set(SUITABLE_INCLUDE_FOUND FALSE)
132 foreach(DIR ${PROTOBUF_INCLUDE_PATH})
133 if(NOT DIR STREQUAL "-I")
134 file(RELATIVE_PATH REL_DIR ${DIR} ${ABS_DIR})
135 string(FIND "${REL_DIR}" "../" IS_IN_PARENT_FOLDER)
136 if (NOT ${IS_IN_PARENT_FOLDER} EQUAL 0)
137 set(SUITABLE_INCLUDE_FOUND TRUE)
138 break()
139 endif()
140 endif()
141 endforeach()
142
143 if(NOT SUITABLE_INCLUDE_FOUND)
144 message(FATAL_ERROR "generate_protos could not find any correct proto include directory.")
145 endif()
146
147 set(GENERATED_SRCS)
148 foreach(EXT ${ARGS_GENERATE_EXTENSIONS})
149 list(APPEND GENERATED_SRCS "${ARGS_PROTOC_OUT_DIR}/${REL_DIR}/${BASENAME}${EXT}")
150 endforeach()
151 list(APPEND ALL_GENERATED_SRCS ${GENERATED_SRCS})
152
153 set(COMMENT "Running ${ARGS_LANGUAGE} protocol buffer compiler on ${PROTO_FILE}")
154 if(ARGS_PROTOC_OPTIONS)
155 set(COMMENT "${COMMENT}, protoc-options: ${ARGS_PROTOC_OPTIONS}")
156 endif()
157 if(PLUGIN_OPTIONS)
158 set(COMMENT "${COMMENT}, plugin-options: ${PLUGIN_OPTIONS}")
159 endif()
160
Ben Clayton90c7cc22023-12-01 11:16:00 +0000161 file(MAKE_DIRECTORY "${ARGS_PROTOC_OUT_DIR}/${REL_DIR}")
162
Ben Claytonde2686e2023-11-16 12:39:06 +0000163 add_custom_command(
164 OUTPUT ${GENERATED_SRCS}
165 COMMAND protobuf::protoc
166 ARGS ${ARGS_PROTOC_OPTIONS} --${ARGS_LANGUAGE}_out ${_plugin_options}:${ARGS_PROTOC_OUT_DIR} ${_plugin} ${PROTOBUF_INCLUDE_PATH} ${ABS_FILE}
167 DEPENDS ${ABS_FILE} protobuf::protoc
168 COMMENT ${COMMENT}
169 VERBATIM)
170 endforeach()
171
172 set_source_files_properties(${ALL_GENERATED_SRCS} PROPERTIES GENERATED TRUE)
173 if(ARGS_TARGET)
174 target_sources(${ARGS_TARGET} PRIVATE ${ALL_GENERATED_SRCS})
175 endif()
176endfunction()