From 679f715994ff804997d3b33aeaeb0eeda45efdcc Mon Sep 17 00:00:00 2001 From: Rupayon Haldar Date: Fri, 12 Jun 2026 12:54:33 -0400 Subject: [PATCH 1/2] Document v3 binary size checks --- docs/v3/binary-size.md | 50 ++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 51 insertions(+) create mode 100644 docs/v3/binary-size.md diff --git a/docs/v3/binary-size.md b/docs/v3/binary-size.md new file mode 100644 index 0000000000..11fc783a01 --- /dev/null +++ b/docs/v3/binary-size.md @@ -0,0 +1,50 @@ +# Binary Size + +Go already removes unreachable code during compilation, so the first step is to +measure the binary you ship instead of assuming a specific feature is expensive. + +```sh +go build -trimpath -o myapp ./cmd/myapp +ls -lh myapp +``` + +Build the same command with stripped symbol and debug information to compare the +release artifact size: + +```sh +go build -trimpath -ldflags="-s -w" -o myapp ./cmd/myapp +ls -lh myapp +``` + +Use the Go toolchain to inspect what is in the binary: + +```sh +go version -m myapp +go tool nm -size myapp | sort -nr | head -40 +``` + +## Current v3 Build Tags + +The v3 module does not currently define build tags such as +`urfave_cli_no_docs`, `urfave_cli_no_completion`, or `urfave_cli_minimal`. +Documentation generation lives outside the core module in +[`urfave/cli-docs`](https://github.com/urfave/cli-docs), so applications that +only import `github.com/urfave/cli/v3` do not pull in that package. + +Shell completion support is part of the core package. Leave +`EnableShellCompletion` disabled unless the application needs shell completion, +then measure the result with the commands above. + +## Practical Checks + +- Build with `-trimpath` for reproducible paths. +- Use `-ldflags="-s -w"` for release builds when debug symbols are not needed. +- Keep optional integrations in separate packages when they bring large + dependencies. +- Avoid adding reflection-heavy dependencies to the main command package unless + they are required at runtime. +- Compare sizes from clean builds after each change. + +If a specific `urfave/cli` feature appears to keep unexpected code reachable, +open an issue with the Go version, build command, a minimal reproduction, and +the `go tool nm -size` output that shows the largest symbols. diff --git a/mkdocs.yml b/mkdocs.yml index e1eac95871..d762bfe7b6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,6 +20,7 @@ nav: - v3 Manual: - Getting Started: v3/getting-started.md - Migrating From Older Releases: v3/migrating-from-older-releases.md + - Binary Size: v3/binary-size.md - Examples: - Greet: v3/examples/greet.md - Flags: From 301fb0c41cbc9b9eff8bfa335adbe5404dcda72b Mon Sep 17 00:00:00 2001 From: Rupayon Haldar Date: Sat, 13 Jun 2026 10:23:45 -0400 Subject: [PATCH 2/2] Address binary size docs review --- docs/v3/binary-size.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/v3/binary-size.md b/docs/v3/binary-size.md index 11fc783a01..2a8e22a064 100644 --- a/docs/v3/binary-size.md +++ b/docs/v3/binary-size.md @@ -1,6 +1,6 @@ # Binary Size -Go already removes unreachable code during compilation, so the first step is to +Go removes unreachable code during compilation, so the first step is to measure the binary you ship instead of assuming a specific feature is expensive. ```sh @@ -8,8 +8,8 @@ go build -trimpath -o myapp ./cmd/myapp ls -lh myapp ``` -Build the same command with stripped symbol and debug information to compare the -release artifact size: +For a release-style build, combine reproducible paths with stripped symbol and +debug information: ```sh go build -trimpath -ldflags="-s -w" -o myapp ./cmd/myapp @@ -23,20 +23,10 @@ go version -m myapp go tool nm -size myapp | sort -nr | head -40 ``` -## Current v3 Build Tags - -The v3 module does not currently define build tags such as -`urfave_cli_no_docs`, `urfave_cli_no_completion`, or `urfave_cli_minimal`. -Documentation generation lives outside the core module in -[`urfave/cli-docs`](https://github.com/urfave/cli-docs), so applications that -only import `github.com/urfave/cli/v3` do not pull in that package. - -Shell completion support is part of the core package. Leave -`EnableShellCompletion` disabled unless the application needs shell completion, -then measure the result with the commands above. - ## Practical Checks +- Run `make check-binary-size` in this repository to compare the current package + contribution against the tracked binary-size budget. - Build with `-trimpath` for reproducible paths. - Use `-ldflags="-s -w"` for release builds when debug symbols are not needed. - Keep optional integrations in separate packages when they bring large @@ -46,5 +36,18 @@ then measure the result with the commands above. - Compare sizes from clean builds after each change. If a specific `urfave/cli` feature appears to keep unexpected code reachable, -open an issue with the Go version, build command, a minimal reproduction, and -the `go tool nm -size` output that shows the largest symbols. +[open an issue](https://github.com/urfave/cli/issues/new) with the Go version, +build command, a minimal reproduction, and the `go tool nm -size` output that +shows the largest symbols. + +## Current v3 Build Tags + +The v3 module does not currently define build tags such as +`urfave_cli_no_docs`, `urfave_cli_no_completion`, or `urfave_cli_minimal`. +Documentation generation lives outside the core module in +[`urfave/cli-docs`](https://github.com/urfave/cli-docs), so applications that +only import `github.com/urfave/cli/v3` do not pull in that package. + +Shell completion support is part of the core package. Leave +`EnableShellCompletion` disabled unless the application needs shell completion, +then measure the result with the commands above.