C++ multi-file merge & code golf / minifier tool
Project description
CPPGolf
cppgolf is a C/C++ multi-file merge and code-golf/minifier tool.
Install
pip install cppgolf
libclang-backed features such as symbol renaming, type renaming, and static deduplication are optional at runtime. The base CLI and text transforms work without clang.cindex.
CLI
cppgolf solution.cpp
cppgolf solution.cpp -o golf.cpp
cppgolf solution.cpp --merge-only -I include/
cppgolf solution.cpp -DDEBUG=1 --inject-define --merge-only
cppgolf solution.cpp -I include/ --rename-functions --stats
cppgolf solution.cpp -DBOTZONE_PIKAFISH_STANDALONE=1 -DZSTD_DISABLE_ASM
cppgolf solution.cpp --no-rename
cppgolf solution.cpp --config cppgolf.toml --flatten-cfg
Common options
| Option | Meaning |
|---|---|
-o FILE |
Write output to a file instead of stdout. |
-I DIR |
Add an include search directory. Can be repeated. |
-D MACRO[=VALUE] |
Pass a macro definition to libclang-backed optional passes. Can be repeated. |
--inject-define |
Write -D macro definitions into the generated source code. |
--merge-only |
Only merge files. Skip all later transforms and compression passes. |
--no-merge |
Skip inlining #include "...". |
--no-strip-comments |
Keep comments. |
--no-compress-ws |
Keep whitespace formatting. |
--no-std-ns |
Do not add using namespace std;. |
--no-typedefs |
Do not add shortcuts such as ll / ld. |
--no-rename |
Disable symbol renaming. |
--no-win-lean |
Do not inject Windows header conflict guards. |
--keep-main-return |
Keep the trailing return 0; in main. |
--keep-endl |
Keep endl. |
--keep-inline |
Keep inline. |
--dedup-statics |
Deduplicate merged static definitions with libclang. |
--aggressive |
Remove braces from single-statement if / for / while. |
--shortcuts |
Insert #define shortcuts for frequent cout / cin. |
--rename-functions |
Also rename user-defined functions and methods. |
--rename-type |
Add typedef aliases for long user-defined type names. |
--config PATH |
Read cppgolf options from a TOML config file. |
--cfg-helper PATH |
Explicitly use the required cppgolf-cfg-helper executable for CFG flattening. |
--cfg-helper-include PATH |
Add a system/cross-platform header directory used only by the CFG helper parser. Can be repeated. |
--flatten-cfg |
Flatten configured function bodies into a switch-based state machine. |
--flatten-cfg-function NAME |
Add an exact function name for control-flow flattening. |
--flower |
Insert both dead-code and declaration flowers. |
--flower-dead-code |
Insert only complex always-false dead-code blocks in function bodies. |
--flower-decls |
Insert only inert global/namespace/class declarations. |
--flower-function NAME |
Limit dead-code flower insertion to an exact function name. Can be repeated. |
--flower-seed N |
Set the deterministic flower seed. |
--flower-dead-blocks N |
Maximum dead-code flower blocks per function. |
--flower-decl-count N |
Maximum inert declarations to insert. |
--stats |
Print size reduction statistics to stderr. |
Configuration
Control-flow flattening is an obfuscation pass and can increase code size. It is disabled by default and only touches configured functions.
[flatten_cfg]
enabled = true
helper = "build/cfg-helper/cppgolf-cfg-helper.exe"
helper_includes = ["C:/msys64/usr/include"]
functions = [
"evaluate",
"Stockfish::Search::Worker::search",
"Stockfish::Tablebases::probe",
]
exclude = ["main"]
Flower insertion is also disabled by default. It uses the same cppgolf-cfg-helper parser as CFG flattening to find safe insertion points.
[flower]
enabled = true
dead_code = true
declarations = true
functions = ["target", "N::Box::run"]
exclude = ["main"]
seed = 1
dead_blocks_per_function = 1
declaration_count = 24
When --flatten-cfg, [flatten_cfg].enabled, --flower, or [flower].enabled is active, cppgolf-cfg-helper is required. cppgolf searches for it in this order: explicit --cfg-helper / Python API path, TOML flatten_cfg.helper, CPPGOLF_CFG_HELPER, build/cfg-helper/cppgolf-cfg-helper(.exe) under the current working directory, the same path under the package repository root, then PATH.
For cross-platform flattening, pass target headers to the helper parser with --cfg-helper-include or flatten_cfg.helper_includes. When an MSYS /usr/include directory such as C:/msys64/usr/include is provided, cppgolf automatically uses the matching MSYS GCC include bundle and x86_64-pc-msys target for helper parsing.
Build the helper with normal LLVM/Clang CMake package discovery:
cmake -S tools/cfg-helper -B build/cfg-helper -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_DIR=/path/to/llvm/lib/cmake/llvm \
-DClang_DIR=/path/to/llvm/lib/cmake/clang
cmake --build build/cfg-helper --config Release
If LLVM is installed in a standard prefix, CMAKE_PREFIX_PATH=/path/to/llvm or llvm-config --cmakedir can also be used to locate the packages.
Python API
from pathlib import Path
from cppgolf import process
result, merged_size = process(
Path("solution.cpp"),
include_dirs=[],
defines=["BOTZONE_PIKAFISH_STANDALONE=1"],
inject_defines=False,
merge_only=False,
rename_symbols=False,
flatten_cfg=False,
flatten_cfg_functions=[],
flower=False,
flower_seed=1,
cfg_helper_path=None,
)
print(merged_size)
print(result)
Individual passes can also be used directly:
from cppgolf import compress_whitespace, strip_comments
from cppgolf.transforms import golf_typedefs
code = Path("a.cpp").read_text()
code = strip_comments(code)
code = golf_typedefs(code)
code = compress_whitespace(code)
Features
- Merge local
#include "..."files recursively and deduplicate top-level system headers. - Strip comments while preserving strings, character literals, and raw strings.
- Apply safe default text transforms such as
std::removal, typedef shortcuts,endlreplacement,inlineremoval, and trailingreturn 0;removal inmain. - Compress whitespace at token granularity while preserving preprocessor line structure.
- Optionally rename symbols and user-defined types with libclang.
- Optionally flatten configured function bodies with the required Clang CFG helper.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cppgolf-0.1.10.tar.gz.
File metadata
- Download URL: cppgolf-0.1.10.tar.gz
- Upload date:
- Size: 77.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bddbb79a0b0e79bd84487e04a0ddee950b9973a7adffbfe5dd5bc7c3349dc038
|
|
| MD5 |
35ae45a17d3c9cfb0be203a2d551c398
|
|
| BLAKE2b-256 |
9bbf1c8557df2182c517dfc37bf094b9773e6f87eb0850f9f57e9d4953a1cd30
|
File details
Details for the file cppgolf-0.1.10-py3-none-any.whl.
File metadata
- Download URL: cppgolf-0.1.10-py3-none-any.whl
- Upload date:
- Size: 61.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6c15b8254fa15ca32acf5959b175a997e4fa80b26f68a4a4cfc3af531da3044
|
|
| MD5 |
e6bdbc946c5dba381074b4655d8f21ac
|
|
| BLAKE2b-256 |
d9c3d4eaad7a18fc997ff37852b0fbff0246d6cc27cfd6ef44e64cfd55ed9d62
|