From 3212034ee6e75d54cbf91b65cc659772166442f4 Mon Sep 17 00:00:00 2001
From: code <wbphub@gmail.com>
Date: Mon, 30 Sep 2024 03:08:03 +0800
Subject: [PATCH] compdb add the compdb support to the proxy_wasm_cpp_host
 (#419)

* compdb add the compdb support to the proxy_wasm_cpp_host

Signed-off-by: wangbaiping <wbphub@gmail.com>
---
 .gitignore                        |  3 ++
 CONTRIBUTING.md                   |  4 ++
 DEVELOPMENT.md                    | 11 +++++
 README.md                         |  4 ++
 bazel/repositories.bzl            |  9 ++++
 tools/gen_compilation_database.py | 79 +++++++++++++++++++++++++++++++
 6 files changed, 110 insertions(+)
 create mode 100644 DEVELOPMENT.md
 create mode 100755 tools/gen_compilation_database.py

diff --git a/.gitignore b/.gitignore
index a6ef824c..54c8a3b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
 /bazel-*
+/external
+/compile_commands.json
+/.cache/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 654a0716..d3f60f57 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,3 +26,7 @@ information on using pull requests.
 
 This project follows [Google's Open Source Community
 Guidelines](https://opensource.google/conduct/).
+
+## Development
+
+See the [Development Guidelines](DEVELOPMENT.md).
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
new file mode 100644
index 00000000..791fe23a
--- /dev/null
+++ b/DEVELOPMENT.md
@@ -0,0 +1,11 @@
+# Development guidelines
+
+## Generate compilation database
+
+[JSON Compilation Database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) files can be used by [clangd](https://clangd.llvm.org/) or similar tools to add source code cross-references and code completion functionality to editors.
+
+The following command can be used to generate the `compile_commands.json` file:
+
+```
+BAZEL_BUILD_OPTION_LIST="--define=engine=multi" ./tools/gen_compilation_database.py --include_all //test/... //:lib
+```
diff --git a/README.md b/README.md
index 8cb5694e..bd198e72 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,5 @@
 # WebAssembly for Proxies (C++ host implementation)
+
+## How to Contribute
+
+See [CONTRIBUTING](CONTRIBUTING.md).
diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl
index 0bede220..908ffe49 100644
--- a/bazel/repositories.bzl
+++ b/bazel/repositories.bzl
@@ -135,6 +135,15 @@ def proxy_wasm_cpp_host_repositories():
         urls = ["https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/archive/95bb82ce45c41d9100fd1ec15d2ffc67f7f3ceee.tar.gz"],
     )
 
+    # Compile DB dependencies.
+    maybe(
+        http_archive,
+        name = "bazel_compdb",
+        sha256 = "acd2a9eaf49272bb1480c67d99b82662f005b596a8c11739046a4220ec73c4da",
+        strip_prefix = "bazel-compilation-database-40864791135333e1446a04553b63cbe744d358d0",
+        url = "https://github.com/grailbio/bazel-compilation-database/archive/40864791135333e1446a04553b63cbe744d358d0.tar.gz",
+    )
+
     # Test dependencies.
 
     maybe(
diff --git a/tools/gen_compilation_database.py b/tools/gen_compilation_database.py
new file mode 100755
index 00000000..bff3d82d
--- /dev/null
+++ b/tools/gen_compilation_database.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+
+# Copyright 2016-2019 Envoy Project Authors
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import json
+import os
+import shlex
+import subprocess
+from pathlib import Path
+
+# This is copied from https://github.com/envoyproxy/envoy and remove unnecessary code.
+
+# This method is equivalent to https://github.com/grailbio/bazel-compilation-database/blob/master/generate.py
+def generate_compilation_database(args):
+    # We need to download all remote outputs for generated source code. This option lives here to override those
+    # specified in bazelrc.
+    bazel_startup_options = shlex.split(os.environ.get("BAZEL_STARTUP_OPTION_LIST", ""))
+    bazel_options = shlex.split(os.environ.get("BAZEL_BUILD_OPTION_LIST", "")) + [
+        "--remote_download_outputs=all",
+    ]
+
+    source_dir_targets = args.bazel_targets
+
+    subprocess.check_call(["bazel", *bazel_startup_options, "build"] + bazel_options + [
+        "--aspects=@bazel_compdb//:aspects.bzl%compilation_database_aspect",
+        "--output_groups=compdb_files,header_files"
+    ] + source_dir_targets)
+
+    execroot = subprocess.check_output(
+        ["bazel", *bazel_startup_options, "info", *bazel_options,
+         "execution_root"]).decode().strip()
+
+    db_entries = []
+    for db in Path(execroot).glob('**/*.compile_commands.json'):
+        db_entries.extend(json.loads(db.read_text()))
+
+    def replace_execroot_marker(db_entry):
+        if 'directory' in db_entry and db_entry['directory'] == '__EXEC_ROOT__':
+            db_entry['directory'] = execroot
+        if 'command' in db_entry:
+            db_entry['command'] = (
+                db_entry['command'].replace('-isysroot __BAZEL_XCODE_SDKROOT__', ''))
+        return db_entry
+
+    return list(map(replace_execroot_marker, db_entries))
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Generate JSON compilation database')
+    parser.add_argument('--include_external', action='store_true')
+    parser.add_argument('--include_genfiles', action='store_true')
+    parser.add_argument('--include_headers', action='store_true')
+    parser.add_argument('--include_all', action='store_true')
+    parser.add_argument(
+        '--system-clang',
+        action='store_true',
+        help=
+        'Use `clang++` instead of the bazel wrapper for commands. This may help if `clangd` cannot find/run the tools.'
+    )
+    parser.add_argument('bazel_targets', nargs='*', default=[])
+
+    args = parser.parse_args()
+    db = generate_compilation_database(args)
+
+    with open("compile_commands.json", "w") as db_file:
+        json.dump(db, db_file, indent=2)