blob: 6e552bafb6d39fbd3118778b6e1c1abdca8a1d43 [file] [log] [blame]
Joshua Habermane59d2c82021-04-05 10:47:53 -07001#!/usr/bin/python
2#
Joshua Haberman823eb092021-04-05 12:26:41 -07003# Copyright (c) 2009-2021, Google LLC
Joshua Habermane59d2c82021-04-05 10:47:53 -07004# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are met:
8# * Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10# * Redistributions in binary form must reproduce the above copyright
11# notice, this list of conditions and the following disclaimer in the
12# documentation and/or other materials provided with the distribution.
13# * Neither the name of Google LLC nor the
14# names of its contributors may be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20# DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
21# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Josh Haberman23fa64f2018-11-05 09:34:05 -080027
Joshua Habermana5243ff2022-03-30 14:20:07 -070028"""A tool to convert {WORKSPACE, BUILD} -> CMakeLists.txt.
Josh Haberman23fa64f2018-11-05 09:34:05 -080029
Joshua Habermana5243ff2022-03-30 14:20:07 -070030This tool is very upb-specific at the moment, and should not be seen as a
31generic Bazel -> CMake converter.
Josh Haberman23fa64f2018-11-05 09:34:05 -080032"""
33
34from __future__ import absolute_import
35from __future__ import division
36from __future__ import print_function
37
38import sys
39import textwrap
Joshua Haberman985145c2019-04-24 17:36:17 +000040import os
Josh Haberman23fa64f2018-11-05 09:34:05 -080041
Joshua Habermana5243ff2022-03-30 14:20:07 -070042def StripFirstChar(deps):
43 return [dep[1:] for dep in deps]
Josh Haberman23fa64f2018-11-05 09:34:05 -080044
45def IsSourceFile(name):
46 return name.endswith(".c") or name.endswith(".cc")
47
48class BuildFileFunctions(object):
49 def __init__(self, converter):
50 self.converter = converter
51
Joshua Haberman35fa3df2018-12-01 02:33:16 -080052 def _add_deps(self, kwargs, keyword=""):
Josh Haberman23fa64f2018-11-05 09:34:05 -080053 if "deps" not in kwargs:
54 return
Joshua Haberman35fa3df2018-12-01 02:33:16 -080055 self.converter.toplevel += "target_link_libraries(%s%s\n %s)\n" % (
Josh Haberman23fa64f2018-11-05 09:34:05 -080056 kwargs["name"],
Joshua Haberman35fa3df2018-12-01 02:33:16 -080057 keyword,
Joshua Habermana5243ff2022-03-30 14:20:07 -070058 "\n ".join(StripFirstChar(kwargs["deps"]))
Josh Haberman23fa64f2018-11-05 09:34:05 -080059 )
60
61 def load(self, *args):
62 pass
63
64 def cc_library(self, **kwargs):
Joshua Haberman543a0ce2020-05-26 22:30:50 -070065 if kwargs["name"].endswith("amalgamation"):
Josh Haberman23fa64f2018-11-05 09:34:05 -080066 return
Joshua Haberman543a0ce2020-05-26 22:30:50 -070067 if kwargs["name"] == "upbc_generator":
68 return
69 if kwargs["name"] == "lupb":
Joshua Haberman626ec4b2019-12-03 20:18:24 -080070 return
Joshua Haberman125db892022-06-30 09:07:48 -070071 if "testonly" in kwargs:
72 return
Josh Haberman23fa64f2018-11-05 09:34:05 -080073 files = kwargs.get("srcs", []) + kwargs.get("hdrs", [])
Joshua Haberman985145c2019-04-24 17:36:17 +000074 found_files = []
Joshua Haberman7ff16622022-04-01 12:07:07 -070075 pregenerated_files = [
76 "CMakeLists.txt", "descriptor.upb.h", "descriptor.upb.c"
77 ]
Joshua Haberman985145c2019-04-24 17:36:17 +000078 for file in files:
Joshua Haberman7ff16622022-04-01 12:07:07 -070079 if os.path.basename(file) in pregenerated_files:
80 found_files.append("../cmake/" + file)
81 else:
82 found_files.append("../" + file)
Josh Haberman23fa64f2018-11-05 09:34:05 -080083
Joshua Haberman493e9b22019-06-17 12:50:45 -070084 if list(filter(IsSourceFile, files)):
Joshua Haberman35fa3df2018-12-01 02:33:16 -080085 # Has sources, make this a normal library.
86 self.converter.toplevel += "add_library(%s\n %s)\n" % (
87 kwargs["name"],
Joshua Haberman985145c2019-04-24 17:36:17 +000088 "\n ".join(found_files)
Joshua Haberman35fa3df2018-12-01 02:33:16 -080089 )
90 self._add_deps(kwargs)
91 else:
92 # Header-only library, have to do a couple things differently.
93 # For some info, see:
94 # http://mariobadr.com/creating-a-header-only-library-with-cmake.html
95 self.converter.toplevel += "add_library(%s INTERFACE)\n" % (
96 kwargs["name"]
97 )
98 self._add_deps(kwargs, " INTERFACE")
Josh Haberman23fa64f2018-11-05 09:34:05 -080099
100 def cc_binary(self, **kwargs):
101 pass
102
103 def cc_test(self, **kwargs):
Josh Haberman549a8282018-12-17 18:21:26 -0800104 # Disable this until we properly support upb_proto_library().
105 # self.converter.toplevel += "add_executable(%s\n %s)\n" % (
106 # kwargs["name"],
107 # "\n ".join(kwargs["srcs"])
108 # )
109 # self.converter.toplevel += "add_test(NAME %s COMMAND %s)\n" % (
110 # kwargs["name"],
111 # kwargs["name"],
112 # )
Josh Haberman23fa64f2018-11-05 09:34:05 -0800113
Josh Haberman549a8282018-12-17 18:21:26 -0800114 # if "data" in kwargs:
115 # for data_dep in kwargs["data"]:
116 # self.converter.toplevel += textwrap.dedent("""\
117 # add_custom_command(
118 # TARGET %s POST_BUILD
119 # COMMAND ${CMAKE_COMMAND} -E copy
120 # ${CMAKE_SOURCE_DIR}/%s
121 # ${CMAKE_CURRENT_BINARY_DIR}/%s)\n""" % (
122 # kwargs["name"], data_dep, data_dep
123 # ))
Josh Haberman23fa64f2018-11-05 09:34:05 -0800124
Josh Haberman549a8282018-12-17 18:21:26 -0800125 # self._add_deps(kwargs)
126 pass
Josh Haberman23fa64f2018-11-05 09:34:05 -0800127
Joshua Haberman11b6df02022-02-15 19:55:44 -0800128 def cc_fuzz_test(self, **kwargs):
129 pass
130
Deanna Garcia6f17e812023-01-02 00:39:33 +0000131 def pkg_files(self, **kwargs):
132 pass
133
Josh Haberman23fa64f2018-11-05 09:34:05 -0800134 def py_library(self, **kwargs):
135 pass
136
137 def py_binary(self, **kwargs):
138 pass
139
Joshua Haberman4c57b1f2019-12-09 10:42:48 -0800140 def lua_proto_library(self, **kwargs):
Josh Haberman23fa64f2018-11-05 09:34:05 -0800141 pass
142
143 def sh_test(self, **kwargs):
144 pass
145
146 def make_shell_script(self, **kwargs):
147 pass
148
149 def exports_files(self, files, **kwargs):
150 pass
151
152 def proto_library(self, **kwargs):
153 pass
154
Joshua Habermanbdd1a512020-10-15 15:01:34 -0700155 def cc_proto_library(self, **kwargs):
156 pass
157
Adam Cozzette71895392022-09-29 20:46:08 +0000158 def staleness_test(self, **kwargs):
Josh Haberman23fa64f2018-11-05 09:34:05 -0800159 pass
160
161 def upb_amalgamation(self, **kwargs):
162 pass
163
164 def upb_proto_library(self, **kwargs):
165 pass
166
Joshua Habermana274ad72020-10-28 13:06:30 -0700167 def upb_proto_library_copts(self, **kwargs):
168 pass
169
Joshua Haberman377871f2018-12-16 14:32:14 -0800170 def upb_proto_reflection_library(self, **kwargs):
171 pass
172
Joshua Habermand6e466e2019-04-24 07:08:20 +0000173 def upb_proto_srcs(self, **kwargs):
174 pass
175
Josh Haberman23fa64f2018-11-05 09:34:05 -0800176 def genrule(self, **kwargs):
177 pass
178
Joshua Haberman15086482019-01-15 04:21:56 -0800179 def config_setting(self, **kwargs):
180 pass
181
Joshua Habermana345af92020-10-18 13:39:13 -0700182 def upb_fasttable_enabled(self, **kwargs):
183 pass
184
Joshua Haberman15086482019-01-15 04:21:56 -0800185 def select(self, arg_dict):
186 return []
187
Deanna Garcia68d3ae72023-01-02 00:51:13 +0000188 def glob(self, *args, **kwargs):
Josh Haberman23fa64f2018-11-05 09:34:05 -0800189 return []
190
Josh Habermanca5f9512019-01-24 12:19:08 -0800191 def licenses(self, *args):
Joshua Haberman7f9f7222019-01-23 17:10:22 -0800192 pass
193
Joshua Haberman985145c2019-04-24 17:36:17 +0000194 def filegroup(self, **kwargs):
195 pass
196
Josh Habermanca5f9512019-01-24 12:19:08 -0800197 def map_dep(self, arg):
198 return arg
199
Joshua Haberman6df55172022-05-24 11:41:56 -0700200 def package_group(self, **kwargs):
201 pass
202
Joshua Haberman143132f2023-01-03 16:20:37 -0800203 def bool_flag(self, **kwargs):
204 pass
205
Joshua Habermane41a2d72023-01-11 21:25:34 -0800206 def bootstrap_upb_proto_library(self, **kwargs):
207 pass
208
209 def bootstrap_cc_library(self, **kwargs):
210 pass
211
Josh Haberman23fa64f2018-11-05 09:34:05 -0800212
213class WorkspaceFileFunctions(object):
214 def __init__(self, converter):
215 self.converter = converter
216
Deanna Garcia92dbe4b2022-12-05 11:13:38 -0800217 def load(self, *args, **kwargs):
Josh Haberman23fa64f2018-11-05 09:34:05 -0800218 pass
219
220 def workspace(self, **kwargs):
221 self.converter.prelude += "project(%s)\n" % (kwargs["name"])
Joshua Haberman8f3ee802020-10-28 16:23:20 -0700222 self.converter.prelude += "set(CMAKE_C_STANDARD 99)\n"
Josh Haberman23fa64f2018-11-05 09:34:05 -0800223
Mike Kruskal40696492022-12-01 17:32:49 -0800224 def maybe(self, rule, **kwargs):
225 if kwargs["name"] == "utf8_range":
226 self.converter.utf8_range_commit = kwargs["commit"]
227 pass
228
Josh Haberman23fa64f2018-11-05 09:34:05 -0800229 def http_archive(self, **kwargs):
230 pass
231
232 def git_repository(self, **kwargs):
233 pass
234
Joshua Haberman43c207e2020-10-31 13:28:24 -0700235 def new_git_repository(self, **kwargs):
236 pass
237
Joshua Haberman0fea70b2019-05-13 10:07:06 -0700238 def bazel_version_repository(self, **kwargs):
239 pass
240
Joshua Haberman56c59c12022-02-19 13:28:39 -0800241 def protobuf_deps(self):
242 pass
243
Mike Kruskal3e078f52022-12-01 14:39:39 -0800244 def utf8_range_deps(self):
245 pass
246
Deanna Garcia92dbe4b2022-12-05 11:13:38 -0800247 def pip_parse(self, **kwargs):
Protobuf Team Bot04363f72022-10-07 11:49:51 -0700248 pass
249
Joshua Habermanf0982302021-08-14 10:52:36 -0700250 def rules_fuzzing_dependencies(self):
251 pass
252
253 def rules_fuzzing_init(self):
254 pass
255
Deanna Garcia98801362022-12-20 00:04:21 +0000256 def rules_pkg_dependencies(self):
257 pass
258
Joshua Haberman71837802021-08-24 07:58:37 -0700259 def system_python(self, **kwargs):
Joshua Haberman5d8c3db2021-08-18 15:16:30 -0700260 pass
261
Mike Kruskal248ed862022-11-30 19:54:51 -0800262 def register_system_python(self, **kwargs):
263 pass
264
Joshua Haberman3921e022021-12-27 18:29:39 -0800265 def register_toolchains(self, toolchain):
266 pass
267
Protobuf Teamee6b1ab2022-04-13 09:06:17 -0700268 def python_source_archive(self, **kwargs):
269 pass
270
271 def python_nuget_package(self, **kwargs):
272 pass
273
Deanna Garcia92dbe4b2022-12-05 11:13:38 -0800274 def install_deps(self):
275 pass
276
277 def fuzzing_py_install_deps(self):
278 pass
279
Deanna Garcia1043eee2023-03-16 13:50:11 -0700280 def googletest_deps(self):
281 pass
282
Josh Haberman23fa64f2018-11-05 09:34:05 -0800283
284class Converter(object):
285 def __init__(self):
286 self.prelude = ""
287 self.toplevel = ""
288 self.if_lua = ""
Mike Kruskal40696492022-12-01 17:32:49 -0800289 self.utf8_range_commit = ""
Josh Haberman23fa64f2018-11-05 09:34:05 -0800290
291 def convert(self):
292 return self.template % {
293 "prelude": converter.prelude,
294 "toplevel": converter.toplevel,
Mike Kruskal40696492022-12-01 17:32:49 -0800295 "utf8_range_commit": converter.utf8_range_commit,
Josh Haberman23fa64f2018-11-05 09:34:05 -0800296 }
297
298 template = textwrap.dedent("""\
299 # This file was generated from BUILD using tools/make_cmakelists.py.
300
301 cmake_minimum_required(VERSION 3.1)
302
303 if(${CMAKE_VERSION} VERSION_LESS 3.12)
304 cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
305 else()
306 cmake_policy(VERSION 3.12)
307 endif()
308
309 cmake_minimum_required (VERSION 3.0)
310 cmake_policy(SET CMP0048 NEW)
311
312 %(prelude)s
313
314 # Prevent CMake from setting -rdynamic on Linux (!!).
315 SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
316 SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
317
318 # Set default build type.
319 if(NOT CMAKE_BUILD_TYPE)
320 message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
321 set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
322 "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
323 FORCE)
324 endif()
325
326 # When using Ninja, compiler output won't be colorized without this.
327 include(CheckCXXCompilerFlag)
328 CHECK_CXX_COMPILER_FLAG(-fdiagnostics-color=always SUPPORTS_COLOR_ALWAYS)
329 if(SUPPORTS_COLOR_ALWAYS)
330 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
331 endif()
332
333 # Implement ASAN/UBSAN options
334 if(UPB_ENABLE_ASAN)
335 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
336 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
337 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
338 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
339 endif()
340
341 if(UPB_ENABLE_UBSAN)
342 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
343 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
344 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
345 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
346 endif()
347
Joshua Habermane3f41de2020-10-17 13:15:58 -0700348 include_directories(..)
349 include_directories(../cmake)
Josh Haberman23fa64f2018-11-05 09:34:05 -0800350 include_directories(${CMAKE_CURRENT_BINARY_DIR})
351
Mike Kruskalf4d045a2023-03-21 11:34:59 -0700352 if(NOT TARGET utf8_range)
353 if(EXISTS ../external/utf8_range)
354 # utf8_range is already installed
355 include_directories(../external/utf8_range)
356 else()
357 include(FetchContent)
358 FetchContent_Declare(
359 utf8_range
360 GIT_REPOSITORY "https://github.com/protocolbuffers/utf8_range.git"
361 GIT_TAG "%(utf8_range_commit)s"
362 )
363 FetchContent_GetProperties(utf8_range)
364 if(NOT utf8_range_POPULATED)
365 FetchContent_Populate(utf8_range)
366 include_directories(${utf8_range_SOURCE_DIR})
367 endif()
Mike Kruskal40696492022-12-01 17:32:49 -0800368 endif()
369 endif()
370
Josh Haberman23fa64f2018-11-05 09:34:05 -0800371 if(APPLE)
372 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup -flat_namespace")
373 elseif(UNIX)
374 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id")
375 endif()
376
377 enable_testing()
378
379 %(toplevel)s
380
381 """)
382
383data = {}
384converter = Converter()
385
386def GetDict(obj):
387 ret = {}
Joshua Habermane3f41de2020-10-17 13:15:58 -0700388 ret["UPB_DEFAULT_COPTS"] = [] # HACK
Joshua Haberman11b6df02022-02-15 19:55:44 -0800389 ret["UPB_DEFAULT_CPPOPTS"] = [] # HACK
Josh Haberman23fa64f2018-11-05 09:34:05 -0800390 for k in dir(obj):
391 if not k.startswith("_"):
392 ret[k] = getattr(obj, k);
393 return ret
394
395globs = GetDict(converter)
396
Mike Kruskal40696492022-12-01 17:32:49 -0800397workspace_dict = GetDict(WorkspaceFileFunctions(converter))
398exec(open("bazel/workspace_deps.bzl").read(), workspace_dict)
399exec(open("WORKSPACE").read(), workspace_dict)
Joshua Haberman493e9b22019-06-17 12:50:45 -0700400exec(open("BUILD").read(), GetDict(BuildFileFunctions(converter)))
Josh Haberman23fa64f2018-11-05 09:34:05 -0800401
402with open(sys.argv[1], "w") as f:
403 f.write(converter.convert())