11cb0ef41Sopenharmony_ci#!/usr/bin/env python3 21cb0ef41Sopenharmony_ci# Copyright 2020 the V8 project authors. All rights reserved. 31cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 41cb0ef41Sopenharmony_ci# found in the LICENSE file. 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci"""\ 71cb0ef41Sopenharmony_ciCreates a "compile_commands.json" file for V8, for the needs of clangd and 81cb0ef41Sopenharmony_cisimilar code indexers. Also updates generated C++ sources, and compiles the 91cb0ef41Sopenharmony_ciTorque Language Server, for a complete code indexing experience. 101cb0ef41Sopenharmony_ci""" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciimport json 131cb0ef41Sopenharmony_ciimport os 141cb0ef41Sopenharmony_ciimport subprocess 151cb0ef41Sopenharmony_ciimport sys 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciPYLIB_PATH = 'tools/clang/pylib' 181cb0ef41Sopenharmony_ciGM_PATH = 'tools/dev' 191cb0ef41Sopenharmony_ciPYLIB_CHECK = os.path.join(PYLIB_PATH, 'clang', 'compile_db.py') 201cb0ef41Sopenharmony_ciGM_CHECK = os.path.join(GM_PATH, 'gm.py') 211cb0ef41Sopenharmony_cidef CheckRelativeImport(path): 221cb0ef41Sopenharmony_ci if not os.path.exists(path): 231cb0ef41Sopenharmony_ci print("Error: Please run this script from the root of a V8 checkout. %s " 241cb0ef41Sopenharmony_ci "must be a valid relative path." % path) 251cb0ef41Sopenharmony_ci sys.exit(1) 261cb0ef41Sopenharmony_ciCheckRelativeImport(PYLIB_CHECK) 271cb0ef41Sopenharmony_ciCheckRelativeImport(GM_CHECK) 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cisys.path.insert(0, PYLIB_PATH) 301cb0ef41Sopenharmony_cifrom clang import compile_db 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_cisys.path.insert(0, GM_PATH) 331cb0ef41Sopenharmony_ciimport gm 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_cidef _Call(cmd, silent=False): 361cb0ef41Sopenharmony_ci if not silent: print("# %s" % cmd) 371cb0ef41Sopenharmony_ci return subprocess.call(cmd, shell=True) 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_cidef _Write(filename, content): 401cb0ef41Sopenharmony_ci with open(filename, "w") as f: 411cb0ef41Sopenharmony_ci f.write(content) 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cidef PrepareBuildDir(arch, mode): 441cb0ef41Sopenharmony_ci build_dir = os.path.join("out", "%s.%s" % (arch, mode)) 451cb0ef41Sopenharmony_ci if not os.path.exists(build_dir): 461cb0ef41Sopenharmony_ci print("# mkdir -p %s" % build_dir) 471cb0ef41Sopenharmony_ci os.makedirs(build_dir) 481cb0ef41Sopenharmony_ci args_gn = os.path.join(build_dir, "args.gn") 491cb0ef41Sopenharmony_ci if not os.path.exists(args_gn): 501cb0ef41Sopenharmony_ci conf = gm.Config(arch, mode, []) 511cb0ef41Sopenharmony_ci _Write(args_gn, conf.GetGnArgs()) 521cb0ef41Sopenharmony_ci build_ninja = os.path.join(build_dir, "build.ninja") 531cb0ef41Sopenharmony_ci if not os.path.exists(build_ninja): 541cb0ef41Sopenharmony_ci code = _Call("gn gen %s" % build_dir) 551cb0ef41Sopenharmony_ci if code != 0: raise Error("gn gen failed") 561cb0ef41Sopenharmony_ci else: 571cb0ef41Sopenharmony_ci _Call("ninja -C %s build.ninja" % build_dir) 581cb0ef41Sopenharmony_ci return build_dir 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_cidef AddTargetsForArch(arch, combined): 611cb0ef41Sopenharmony_ci build_dir = PrepareBuildDir(arch, "debug") 621cb0ef41Sopenharmony_ci commands = compile_db.ProcessCompileDatabase( 631cb0ef41Sopenharmony_ci compile_db.GenerateWithNinja(build_dir, ["all"]), []) 641cb0ef41Sopenharmony_ci added = 0 651cb0ef41Sopenharmony_ci for c in commands: 661cb0ef41Sopenharmony_ci key = c["file"] 671cb0ef41Sopenharmony_ci if key not in combined: 681cb0ef41Sopenharmony_ci combined[key] = c 691cb0ef41Sopenharmony_ci added += 1 701cb0ef41Sopenharmony_ci print("%s: added %d compile commands" % (arch, added)) 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cidef UpdateCompileCommands(): 731cb0ef41Sopenharmony_ci print(">>> Updating compile_commands.json...") 741cb0ef41Sopenharmony_ci combined = {} 751cb0ef41Sopenharmony_ci AddTargetsForArch("x64", combined) 761cb0ef41Sopenharmony_ci AddTargetsForArch("ia32", combined) 771cb0ef41Sopenharmony_ci AddTargetsForArch("arm", combined) 781cb0ef41Sopenharmony_ci AddTargetsForArch("arm64", combined) 791cb0ef41Sopenharmony_ci commands = [] 801cb0ef41Sopenharmony_ci for key in combined: 811cb0ef41Sopenharmony_ci commands.append(combined[key]) 821cb0ef41Sopenharmony_ci _Write("compile_commands.json", json.dumps(commands, indent=2)) 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_cidef CompileLanguageServer(): 851cb0ef41Sopenharmony_ci print(">>> Compiling Torque Language Server...") 861cb0ef41Sopenharmony_ci PrepareBuildDir("x64", "release") 871cb0ef41Sopenharmony_ci _Call("autoninja -C out/x64.release torque-language-server") 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_cidef GenerateCCFiles(): 901cb0ef41Sopenharmony_ci print(">>> Generating generated C++ source files...") 911cb0ef41Sopenharmony_ci # This must be called after UpdateCompileCommands(). 921cb0ef41Sopenharmony_ci assert os.path.exists("out/x64.debug/build.ninja") 931cb0ef41Sopenharmony_ci _Call("autoninja -C out/x64.debug v8_generated_cc_files") 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_cidef StartGoma(): 961cb0ef41Sopenharmony_ci gomadir = gm.DetectGoma() 971cb0ef41Sopenharmony_ci if (gomadir is not None and 981cb0ef41Sopenharmony_ci _Call("ps -e | grep compiler_proxy > /dev/null", silent=True) != 0): 991cb0ef41Sopenharmony_ci _Call("%s/goma_ctl.py ensure_start" % gomadir) 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ciif __name__ == "__main__": 1021cb0ef41Sopenharmony_ci StartGoma() 1031cb0ef41Sopenharmony_ci CompileLanguageServer() 1041cb0ef41Sopenharmony_ci UpdateCompileCommands() 1051cb0ef41Sopenharmony_ci GenerateCCFiles() 106