From 9edf5db9899eec7a592e1ea2df7a7c1f20ef1c47 Mon Sep 17 00:00:00 2001 From: VioletXF Date: Tue, 12 Mar 2024 15:11:59 +0900 Subject: [PATCH] Implement amalgamator --- .github/workflows/publish_amal.yml | 21 ++--------- Makefile | 6 ++++ example/.gitignore | 1 + example/main.cpp | 5 ++- scripts/amalgamate.py | 56 ++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 example/.gitignore create mode 100644 scripts/amalgamate.py diff --git a/.github/workflows/publish_amal.yml b/.github/workflows/publish_amal.yml index 7e0ccae..c8c89d7 100644 --- a/.github/workflows/publish_amal.yml +++ b/.github/workflows/publish_amal.yml @@ -13,27 +13,10 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Cache cpp-amalgamate - uses: actions/cache@v2 - with: - path: | - ~/.cargo/bin/cpp-amalgamate - ~/.cargo/.crates.toml - ~/.cargo/.crates2.json - key: ${{ runner.os }}-cpp-amalgamate-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cpp-amalgamate- - - - name: Install cpp-amalgamate if not cached - run: | - if ! command -v cpp-amalgamate &> /dev/null - then - cargo install cpp-amalgamate - fi - - name: cpp-amalgamate + - name: amalgamate run: | rm -f bms_parser.hpp - cpp-amalgamate ./src/** >> bms_parser.hpp + python3 scripts/amalgamate.py bms_parser.hpp src/** # create new release - name: Create Release id: create_release diff --git a/Makefile b/Makefile index ea7ffe2..d41a52b 100644 --- a/Makefile +++ b/Makefile @@ -17,5 +17,11 @@ example/sqlite3.o: example/sqlite3.c gcc -c -o example/sqlite3.o example/sqlite3.c example: all example/sqlite3.o $(BUILD_PATH) $(CC) $(CCFLAGS) -o $(BUILD_PATH)/main example/main.cpp example/sqlite3.o $(OBJ_FILES) +amalgamate: + python3 scripts/amalgamate.py $(BUILD_PATH)/bms_parser.hpp $(SRC_FILES) +test_amalgamation: amalgamate example/sqlite3.o $(BUILD_PATH) + @cp $(BUILD_PATH)/bms_parser.hpp example/ + $(CC) $(CCFLAGS) -DWITH_AMALGAMATION=1 -o $(BUILD_PATH)/test_amalgamation example/main.cpp example/sqlite3.o + ./$(BUILD_PATH)/test_amalgamation example/example.bme clean: @rm -rf $(OBJ_PATH) $(BUILD_PATH) diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..a6032fe --- /dev/null +++ b/example/.gitignore @@ -0,0 +1 @@ +bms_parser.hpp \ No newline at end of file diff --git a/example/main.cpp b/example/main.cpp index 5ca9e3c..5f0de70 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -13,9 +13,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - +#if WITH_AMALGAMATION +#include "bms_parser.hpp" +#else #include "../src/Parser.h" #include "../src/Chart.h" +#endif #include #include #include diff --git a/scripts/amalgamate.py b/scripts/amalgamate.py new file mode 100644 index 0000000..ff190fc --- /dev/null +++ b/scripts/amalgamate.py @@ -0,0 +1,56 @@ +# C++ amalgamator +# Copyright (C) 2024 VioletXF +# This script is used to generate a single C++ file from a set of C++ files. +# This implementation doesn't follow the standard C++ include resolution, it +# simply concatenates the files in the order they are given, to preserve the +# copyright notice. + +import os +import re + +def amalgamate(paths: [str], out: str): + visited = set() + content = "#pragma once\n" + files = [] + + def dfs(path): + nonlocal content + if path in visited: + return + visited.add(path) + with open(path, "r") as f: + for line in f: + if line.strip().startswith("#include"): + m = re.match(r'#include\s+"(.*)"', line) + if m: + include = m.group(1) + include_path = os.path.join(os.path.dirname(path), include) + dfs(include_path) + files.append(path) + + for path in paths: + dfs(path) + for path in files: + with open(path, "r") as f: + for line in f: + if line.strip().startswith("#pragma once"): + continue + m = re.match(r'#include\s+<(.*)>', line) + if not line.strip().startswith("#include") or m: + content += line + + with open(out, "w") as f: + f.write(content) + + +if __name__ == "__main__": + # glob to get all files + import sys + if len(sys.argv) < 3: + print("Usage: python amalgamate.py ...") + sys.exit(1) + out = sys.argv[1] + ins = sys.argv[2:] + print("Amalgamating", ins, "into", out) + amalgamate(ins, out) +