Skip to content

Allow linker to perform deadcode elimination for programs using kingpin - #365

Merged
alecthomas merged 1 commit into
alecthomas:masterfrom
rosstimothy:tross/dead_code
Apr 16, 2026
Merged

Allow linker to perform deadcode elimination for programs using kingpin#365
alecthomas merged 1 commit into
alecthomas:masterfrom
rosstimothy:tross/dead_code

Conversation

@rosstimothy

Copy link
Copy Markdown
Contributor

This was largely inspired by spf13/cobra#1956.

The usage rendering relied on text/template which in turn relied on reflect.MethodByName. As a result, Go's deadcode elimination is prevented from running, and thus means any downstream consumers of kingpin also cannot take advantage of deadcode elimination.

This changes the usage rendering of kingpin such that text/template is not used by default. The existing templates were converted into pure Go functions, and an extensive test suite was added to ensure equality with the legacy templates. Default applications now use the pure Go equivalent of kingpin.DefaultUsageTemplate. The existing UsageTemplate and UsageFuncs APIs remain intact to preserve compatibility. Any use of either API will result in text/template rendering usage and preventing deadcode elimination.

The basic app used in TestDeadCodeElimination was tested before and after this change. The usage text remained the same, but the binary size shrunk from ~5MB to ~2MB.

This was largely inspired by spf13/cobra#1956.

The usage rendering relied on text/template which in turn relied on
reflect.MethodByName. As a result, Go's deadcode elimination is
prevented from running, and thus means any downstream consumers of
kingpin also cannot take advantage of deadcode elimination.

This changes the usage rendering of kingpin such that text/template
is not used by default. The existing templates were converted into
pure Go functions, and an extensive test suite was added to ensure
equality with the legacy templates. Default applications now use
the pure Go equivalent of kingpin.DefaultUsageTemplate. The existing
UsageTemplate and UsageFuncs APIs remain intact to preserve compatibility.
Any use of either API will result in text/template rendering usage
and preventing deadcode elimination.

The basic app used in TestDeadCodeElimination was tested before and
after this change. The usage text remained the same, but the binary
size shrunk from ~5MB to ~2MB.
@rosstimothy

Copy link
Copy Markdown
Contributor Author

@alecthomas I know this is a larger change but I would really appreciate your review. Being able to leverage DCE can result in a tremendous binary size reduction for consumers of kingpin. I've seen ~40% reduction in larger projects. Datadog published https://www.datadoghq.com/blog/engineering/agent-go-binaries where they saw >70% reduction in binary sizes with DCE.

@alecthomas alecthomas left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me, thanks!

@alecthomas
alecthomas merged commit 09e9322 into alecthomas:master Apr 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants