diff options
-rw-r--r-- | .editorconfig | 2 | ||||
-rw-r--r-- | libmisc/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | libmisc/wrap-cc | 73 |
3 files changed, 75 insertions, 1 deletions
diff --git a/.editorconfig b/.editorconfig index dedd350..b7ad057 100644 --- a/.editorconfig +++ b/.editorconfig @@ -51,7 +51,7 @@ _mode = sh [{build-aux/lint-{src,bin},build-aux/gcov-prune,libusb/include/libusb/tusb_helpers.h.gen}] _mode = bash -[build-aux/stack.c.gen] +[{build-aux/stack.c.gen,libmisc/wrap-cc}] _mode = python3 indent_style = space indent_size = 4 diff --git a/libmisc/CMakeLists.txt b/libmisc/CMakeLists.txt index 7ee307e..07f154b 100644 --- a/libmisc/CMakeLists.txt +++ b/libmisc/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(libmisc INTERFACE target_compile_options(libmisc INTERFACE -no-integrated-cpp + -wrapper "${CMAKE_CURRENT_SOURCE_DIR}/wrap-cc" ) add_lib_test(libmisc test_assert) diff --git a/libmisc/wrap-cc b/libmisc/wrap-cc new file mode 100755 index 0000000..5124689 --- /dev/null +++ b/libmisc/wrap-cc @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# libmisc/wrap-cc - Wrapper around GCC to enhance the preprocessor +# +# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +import os +import sys +import typing + + +def preprocess(all_args: list[str]) -> typing.NoReturn: + _args = all_args + + def shift(n: int) -> list[str]: + nonlocal _args + ret = _args[:n] + _args = _args[n:] + return ret + + arg0 = shift(1)[0] + flags: list[str] = [] + positional: list[str] = [] + while _args: + if len(_args[0]) > 2 and _args[0][0] == "-" and _args[0][1] in "IDU": + _args = [_args[0][:2], _args[0][2:], *_args[1:]] + match _args[0]: + # Mode + case "-E" | "-quiet" | "-lang-asm": + flags += shift(1) + # Search path + case "-I" | "-imultilib" | "-isystem": + flags += shift(2) + # Define/Undefine + case "-D" | "-U": + flags += shift(2) + # Optimization + case "-O0" | "-O1" | "-O2" | "-O3" | "-Os" | "-Ofast" | "-Og" | "-Oz": + flags += shift(1) + case "-g": + flags += shift(1) + # Output files + case "-MD" | "-MF" | "-MT" | "-dumpbase" | "-dumpbase-ext": + flags += shift(2) + case "-o": + flags += shift(2) + # Other + case _: + if _args[0].startswith("-"): + if _args[0].startswith("-std="): + flags += shift(1) + elif _args[0].startswith("-m"): + flags += shift(1) + elif _args[0].startswith("-f"): + flags += shift(1) + elif _args[0].startswith("-W"): + flags += shift(1) + else: + raise ValueError(f"unknown flag: {_args!r}") + else: + positional += shift(1) + os.execvp(arg0, [arg0, *flags, *positional]) + + +def main(all_args: list[str]) -> typing.NoReturn: + if len(all_args) >= 2 and all_args[0].endswith("cc1") and all_args[1] == "-E": + preprocess(all_args) + else: + os.execvp(all_args[0], all_args) + + +if __name__ == "__main__": + main(sys.argv[1:]) |