Introducing Codman: A Deep Dive into U-Boot Build Analysis

U-Boot is a massive project. With thousands of files, nearly endless configuration possibilities, and complex Kconfig dependencies, a single board configuration often only compiles a small fraction of the total source tree.
For developers and maintainers, this complexity often leads to difficult questions:
- “I just enabled
CONFIG_CMD_NET; how much code did that actually add?” - “How much bloat would I remove by disabling
CONFIG_CMDLINE?” - “Which specific lines of this driver are active for my board?”
Simply searching for CONFIG_ macros or header inclusions is rarely enough. The build logic takes many forms—Makefile rules, #ifdefs, IS_ENABLED(), and static inlines—making static analysis tricky.
Enter Codman (Code Manager), a new tool designed to cut through this complexity by analysing the actual build artefacts generated by the compiler.
What is Codman?
Codman is a Python-based tool located in tools/codman/. It works out exactly which source files and lines of code are compiled and used for a specific board. It works by:
- Building the specified board (or using an existing build).
- Parsing
.cmdfiles to find which source files were compiled. - Analysing the source code (using a specialized
unifdef) or object files (using DWARF tables) to figure out exactly which lines made it into the final binary.
Feature Highlight: Impact Analysis
One of Codman’s most powerful features is Impact Analysis. This allows you to explore “what if” scenarios without manually editing defconfig files or running menuconfig.
Using the -a (adjust) flag, you can modify the Kconfig configuration on the fly before the analysis runs. This is perfect for seeing exactly how much code a specific feature adds.
Example: Checking the impact of USB To enable the USB subsystem on the sandbox board and see how the code stats change:
./tools/codman/codman.py -b sandbox -a CMD_USB stats
Example: Disabling Networking To see what code remains active when networking is explicitly disabled:
./tools/codman/codman.py -b sandbox -a ~NET,NO_NET stats
Visualising the Build
Codman provides several ways to view your build data.
1. High-Level Statistics The stats command gives you a bird’s-eye view of your build size.
$ codman -b qemu-x86 stats ====================================================================== FILE-LEVEL STATISTICS ====================================================================== Total source files: 14114 Used source files: 1046 (7.4%) Unused source files: 13083 (92.7%) Total lines of code: 3646331 Used lines of code: 192543 (5.3%)
2. Directory Breakdown Use dirs to see which subsystems are contributing the most weight to your board.
$ codman dirs BREAKDOWN BY TOP-LEVEL DIRECTORY Directory Files Used %Used %Code kLOC Used ------------------------------------------------------------- arch 234 156 67 72 12.3 8.9 board 123 45 37 25 5.6 1.4 cmd 89 67 75 81 3.4 2.8 ...
You can also break down the information by showing subdirectories (-s) or even individual files (-f).
$ codman -n -b qemu-x86 dirs --subdirs -f ======================================================================================= BREAKDOWN BY TOP-LEVEL DIRECTORY ======================================================================================= Directory Files Used %Used %Code kLOC Used --------------------------------------------------------------------------------------- arch/x86/cpu 20 15 75 85 3.8 3.2 start.S 318 190 59.7 128 cpu.c 399 353 88.5 46 mp_init.c 902 877 97.2 25 turbo.c 103 92 89.3 11 lapic.c 158 156 98.7 2 resetvec.S 18 18 100.0 0 pci.c 100 100 100.0 0 mtrr.c 455 455 100.0 0 start16.S 123 123 100.0 0 sipi_vector.S 215 215 100.0 0 ioapic.c 36 36 100.0 0 call32.S 61 61 100.0 0 qfw_cpu.c 86 86 100.0 0 irq.c 366 366 100.0 0 cpu_x86.c 99 99 100.0 0 arch/x86/cpu/i386 4 4 100 98 1.4 1.4 cpu.c 649 630 97.1 19 interrupt.c 630 622 98.7 8 call64.S 92 92 100.0 0 setjmp.S 65 65 100.0 0 arch/x86/cpu/intel_common 18 6 33 23 3.3 0.8 microcode.c 187 183 97.9 4 pch.c 23 23 100.0 0 lpc.c 100 100 100.0 0
3. Line-by-Line Detail Perhaps the most useful feature for debugging configuration issues is the detail view. It shows you exactly which lines are active or inactive within a file.
$ codman -b qemu-x86 detail common/main.c
...
24 | static void run_preboot_environment_command(void)
25 | {
26 | char *p;
27 |
28 | p = env_get("preboot");
29 | if (p != NULL) {
30 | int prev = 0;
31 |
- 32 | if (IS_ENABLED(CONFIG_AUTOBOOT_KEYED))
- 33 | prev = disable_ctrlc(1); /* disable Ctrl-C checking */
34 |
35 | run_command_list(p, -1, 0);
36 |
- 37 | if (IS_ENABLED(CONFIG_AUTOBOOT_KEYED))
- 38 | disable_ctrlc(prev); /* restore Ctrl-C checking */
39 | }
40 | }
41 |
...
(Lines marked with - are not included in the build and show in a different colour)
Under the Hood: Unifdef vs. DWARF
Codman supports two methods for analysis:
- Unifdef (Default): Simulates the C preprocessor to determine which lines are active based on
CONFIG_settings. It is fast (leveraging multiprocessing) and provides a great preprocessor-level view. It uses a patched version ofunifdefthat supports U-Boot’sIS_ENABLED()macros. - DWARF (
-w): Rebuilds the project with debug info and analyses the DWARF line number tables. This is highly accurate for executable code but won’t count declarations or comments.
Getting Started
# Basic stats for sandbox ./tools/codman/codman.py -b sandbox stats # Find unused files ./tools/codman/codman.py -b sandbox unused # Extract only used sources to a new directory (great for minimal distributions) ./tools/codman/codman.py -b sandbox copy-used /tmp/minimal-tree
Check the documentation for more details!