diff --git a/llvm/utils/merge-json.py b/llvm/utils/merge-json.py new file mode 100644 index 00000000000000..bf0d651fe5f52b --- /dev/null +++ b/llvm/utils/merge-json.py @@ -0,0 +1,48 @@ +#!/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 +import sys + + +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) 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 + 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 ef8ec171a1657d..17badc3ff96d14 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -346,3 +346,21 @@ if(SUB_COMPONENTS) ${CMAKE_CURRENT_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) + # Make a dependency so that we don't error if the file gets deleted somehow. + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/compile_commands.json + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/compile_commands.json) + + 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 ${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()