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)