From 458aee62645e79c256735176e4cd22b2ffd2386e Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Thu, 14 Nov 2024 18:34:53 -0600 Subject: [PATCH 1/2] [Runtimes] Merge 'compile_commands.json' files from runtimes build Summary: When building a project in a runtime mode, the compilation database is a separate CMake invocation. So its `compile_commands.json` file will be placed elsewhere in the `runtimes/runtime-bins` directory. This is somewhat annoying for ongoing development when a runtimes build is necessary. This patch adds some CMake magic to merge the two files. --- llvm/utils/merge-json.py | 46 ++++++++++++++++++++++++++++++++++++++++ runtimes/CMakeLists.txt | 15 +++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 llvm/utils/merge-json.py diff --git a/llvm/utils/merge-json.py b/llvm/utils/merge-json.py new file mode 100644 index 00000000000000..d1d48601fbb68d --- /dev/null +++ b/llvm/utils/merge-json.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +"""A command line utility to merge two JSON files. + +This is a python program that merges two JSON files into a single one. The +intended use for this is to combine generated 'compile_commands.json' files +created by CMake when performing an LLVM runtime build. +""" + +import argparse +import json + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "-o", + type=str, + help="The output file to write JSON data to", + default=None, + nargs="?", + ) + parser.add_argument( + "json_files", type=str, nargs="+", help="Input JSON files to merge" + ) + args = parser.parse_args() + + merged_data = [] + + for json_file in args.json_files: + try: + with open(json_file, "r") as f: + data = json.load(f) + merged_data.extend(data) + except (IOError, json.JSONDecodeError): + continue + + # Deduplicate by converting each entry to a tuple of sorted key-value pairs + unique_data = list({json.dumps(entry, sort_keys=True) for entry in merged_data}) + unique_data = [json.loads(entry) for entry in unique_data] + + with open(args.o, "w") as f: + json.dump(unique_data, f, indent=2) + + +if __name__ == "__main__": + main() diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index 832a7d0c193592..f9c1704d864515 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -313,3 +313,18 @@ if(SUB_COMPONENTS) ${LLVM_BINARY_DIR}/runtimes/Components.cmake) endif() endif() + +# If the user requested 'compile_commands.json' we merge the generated JSON from +# the created directories. +if(CMAKE_EXPORT_COMPILE_COMMANDS) + file(TO_NATIVE_PATH "${LLVM_MAIN_SRC_DIR}/utils/merge-json.py" MERGE_JSON_PATH) + add_custom_command(OUTPUT ${LLVM_BINARY_DIR}/compile_commands.json + COMMAND ${CMAKE_COMMAND} -E touch ${LLVM_BINARY_DIR}/compile_commands.json + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/compile_commands.json + COMMAND ${Python3_EXECUTABLE} ${MERGE_JSON_PATH} + ${LLVM_BINARY_DIR}/compile_commands.json + ${CMAKE_BINARY_DIR}/compile_commands.json + -o ${LLVM_BINARY_DIR}/compile_commands.json + DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json) + add_custom_target(merge_runtime_commands ALL DEPENDS ${LLVM_BINARY_DIR}/compile_commands.json) +endif() From d36eabc7aa0b37a4eea8d5d94aac3f575863d247 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Thu, 14 Nov 2024 18:44:02 -0600 Subject: [PATCH 2/2] warning --- llvm/utils/merge-json.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/utils/merge-json.py b/llvm/utils/merge-json.py index d1d48601fbb68d..5a1046dd6d2dd0 100644 --- a/llvm/utils/merge-json.py +++ b/llvm/utils/merge-json.py @@ -31,7 +31,8 @@ def main(): with open(json_file, "r") as f: data = json.load(f) merged_data.extend(data) - except (IOError, json.JSONDecodeError): + except (IOError, json.JSONDecodeError) as e: + print("Failed to parse {json_file}: {e}", file=sys.stderr) continue # Deduplicate by converting each entry to a tuple of sorted key-value pairs