From 5de72e75dfdbd000aded8f64277c94c02c80e6e9 Mon Sep 17 00:00:00 2001 From: SG Date: Thu, 12 May 2022 21:38:33 +1000 Subject: [PATCH] Compile commands generator (#1223) --- Makefile | 4 +++ make/rules.mk | 16 +++++++++ make/toolchain.mk | 2 +- scripts/compile_db.py | 77 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100755 scripts/compile_db.py diff --git a/Makefile b/Makefile index 13692347..5304cfa5 100644 --- a/Makefile +++ b/Makefile @@ -148,3 +148,7 @@ format: guruguru: @echo "ぐるぐる回る" @$(PROJECT_ROOT)/scripts/guruguru.py $(PROJECT_ROOT) + +.PHONY: generate_compile_db +generate_compile_db: + @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) generate_compile_db \ No newline at end of file diff --git a/make/rules.mk b/make/rules.mk index 32e525b6..bdf8a4af 100644 --- a/make/rules.mk +++ b/make/rules.mk @@ -155,6 +155,22 @@ generate_cscope_db: @cscope -b -k -i $(OBJ_DIR)/source.list -f $(OBJ_DIR)/cscope.out @rm -rf $(OBJ_DIR)/source.list $(OBJ_DIR)/source.list.p +.PHONY: generate_compile_db +generate_compile_db: + @echo "$(ASM_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/db.asm_source.list + @echo "$(C_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/db.c_source.list + @echo "$(CPP_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/db.cpp_source.list + @echo "$(AS)$(CFLAGS)" | tr ' ' '\n' > $(OBJ_DIR)/db.asm_flags.list + @echo "$(CC)$(CFLAGS)" | tr ' ' '\n' > $(OBJ_DIR)/db.c_flags.list + @echo "$(CPP)$(CFLAGS)$(CPPFLAGS)" | tr ' ' '\n' > $(OBJ_DIR)/db.cpp_flags.list + @$(PROJECT_ROOT)/scripts/compile_db.py generate -p $(OBJ_DIR) + @rm $(OBJ_DIR)/db.asm_source.list + @rm $(OBJ_DIR)/db.c_source.list + @rm $(OBJ_DIR)/db.cpp_source.list + @rm $(OBJ_DIR)/db.asm_flags.list + @rm $(OBJ_DIR)/db.c_flags.list + @rm $(OBJ_DIR)/db.cpp_flags.list + # Prevent make from searching targets for real files %.d: ; diff --git a/make/toolchain.mk b/make/toolchain.mk index 2946a2e2..f161d3d1 100644 --- a/make/toolchain.mk +++ b/make/toolchain.mk @@ -36,6 +36,6 @@ else CFLAGS += -DFURI_NDEBUG -DNDEBUG -Og -g endif -CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" +CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF "$(@:%.o=%.d)" CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -n diff --git a/scripts/compile_db.py b/scripts/compile_db.py new file mode 100755 index 00000000..76c445cf --- /dev/null +++ b/scripts/compile_db.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +from flipper.app import App +import json +import pathlib + + +class Main(App): + def init(self): + self.subparsers = self.parser.add_subparsers(help="sub-command help") + + # generate + self.parser_generate = self.subparsers.add_parser( + "generate", help="Check source code format and file names" + ) + self.parser_generate.add_argument("-p", dest="path", required=True) + self.parser_generate.set_defaults(func=self.generate) + + def parse_sources(self, path, source_path, flags_path): + flags = "" + with open(path + "/" + flags_path) as f: + for line in f: + if line.strip(): + flags += line.strip() + " " + + local_path = str(pathlib.Path().resolve()) + + data = [] + with open(path + "/" + source_path) as f: + for line in f: + if line.strip(): + file = line.strip() + data.append( + { + "directory": local_path, + "command": flags + "-c " + file, + "file": file, + } + ) + return data + + def generate(self): + DB_SOURCE = [ + { + "name": "ASM", + "source": "db.asm_source.list", + "flags": "db.asm_flags.list", + }, + {"name": "C", "source": "db.c_source.list", "flags": "db.c_flags.list"}, + { + "name": "CPP", + "source": "db.cpp_source.list", + "flags": "db.cpp_flags.list", + }, + ] + + path = self.args.path + out_data = [] + out_path = path + "/" + "compile_commands.json" + out_file = open(out_path, mode="w") + + for record in DB_SOURCE: + self.logger.info( + f"Processing {record['name']} ({record['source']}, {record['flags']})" + ) + data = self.parse_sources(path, record["source"], record["flags"]) + out_data += data + + self.logger.info(f"Saving") + json.dump(out_data, out_file, indent=2) + + self.logger.info(f"Compilation DB written to " + out_path) + return 0 + + +if __name__ == "__main__": + Main()()