Skip to main content

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, endl replacement, inline removal, and trailing return 0; removal in main.
  • 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.

Release files for cppgolf 0.1.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cppgolf 0.1.10
File Size Uploaded
cppgolf-0.1.10.tar.gz 77.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cppgolf 0.1.10
File Interpreter ABI Platform
cppgolf-0.1.10-py3-none-any.whl Python 3 none any Details

Total release size: 139.1 kB

Release files / cppgolf-0.1.10.tar.gz

Download URL cppgolf-0.1.10.tar.gz
Size 77.4 kB
Tags Source
SHA-256 checksum
How to use checksums
bddbb79a0b0e79bd84487e04a0ddee950b9973a7adffbfe5dd5bc7c3349dc038
BLAKE2b-256 checksum
How to use checksums
9bbf1c8557df2182c517dfc37bf094b9773e6f87eb0850f9f57e9d4953a1cd30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / cppgolf-0.1.10-py3-none-any.whl

Download URL cppgolf-0.1.10-py3-none-any.whl
Size 61.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6c15b8254fa15ca32acf5959b175a997e4fa80b26f68a4a4cfc3af531da3044
BLAKE2b-256 checksum
How to use checksums
d9c3d4eaad7a18fc997ff37852b0fbff0246d6cc27cfd6ef44e64cfd55ed9d62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release history Release notifications | RSS feed

This release

0.1.10 This release

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page