Loading...
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
.. SPDX-License-Identifier: GPL-2.0+

===================
Codman code manager
===================

The codman tool analyses U-Boot builds to determine which source files and lines
of code are actually compiled and used.

U-Boot is a massive project with thousands of files and nearly endless
configuration possibilities. A single board configuration might only compile a
small fraction of the total source tree. Codman can help answer questions like:

* "I just enabled ``CONFIG_CMD_NET``, how much code did that actually add?"
* "How much code would I remove by disabling ``CONFIG_CMDLINE``?

Simply searching for ``CONFIG_`` macros or header inclusions is tricky because
the build logic takes many forms: Makefile rules, #ifdefs, IS_ENABLED(),
CONFIG_IS_ENABLED() and static inlines. The end result is board-specific in any
case.

Codman cuts through this complexity by analysing the actual build artifacts
generated by the compiler:

#. Builds the specified board
#. Parses the ``.cmd`` files to find which source file were compiled.
#. Analyses the source code (with unifdef) or the object files (dwarf tables)
   to figure out which files and lines were compiled.

Usage
=====

Basic usage, from within the U-Boot source tree::

  ./tools/codman/codman.py -b <board> [flags] <command> [command-flags]

Codman operations does out-of-tree builds, meaning that the object files end up
in a separate directory for each board. Use ``--build-base`` to set that. The
default is ``/tmp/b`` meaning that a sandbox build would end up in
``/tmp/b/sandbox``, for eaxmple.

Relationship to LSPs
====================

LSPs can allow you to see unused code in your IDE, which is very handy for
interactive use. Codman is more about getting a broader picture, although it
does allow individual files to be listed. Codman does include a ``--lsp`` option
but this doesn't work particularly well.

Commands
========

The basic functionality is accessed via these commands:

* ``stats`` - Show statistics (default if no command given)
* ``dirs`` - Show directory breakdown
* ``unused`` - List unused files
* ``used`` - List used files
* ``summary`` - Show per-file summary
* ``detail <file>...`` - Show line-by-line analysis of one or more files
* ``copy-used <dir>`` - Copy used source files to a directory


This will build the board and show statistics about source file usage.

Adjusting Configuration (-a)
============================

Sometimes you want to explore "what if" scenarios without manually editing
``defconfig`` files or running menuconfig. The ``-a`` (or ``--adjust``) option
allows you to modify the Kconfig configuration on the fly before the analysis
build runs.

This is particularly useful for **impact analysis**: seeing exactly how much
code a specific feature adds to the build.

Syntax
------

The `CONFIG_` prefix is optional.

* ``-a CONFIG_OPTION``: Enable a boolean option (sets to 'y').
* ``-a ~CONFIG_OPTION``: Disable an option.
* ``-a OPTION=val``: Set an option (``CONFIG_OPTION``) to a specific value.
* ``-a CONFIG_A,CONFIG_B``: Set multiple options (comma-separated).

Examples
--------

**Check the impact of USB:**

Enable the USB subsystem on the sandbox board and see how the code stats change::

  codman -b sandbox -a CMD_USB stats

**Disable Networking:**
See what code remains active when networking is explicitly disabled::

  codman -b sandbox -a ~NET,NO_NET stats

**Multiple Adjustments:**
Enable USB and USB storage together::

  codman -b sandbox -a CONFIG_CMD_USB -a CONFIG_USB_STORAGE stats

Common Options
==============

Building:

* ``-b, --board <board>`` - Board to build and analyse (default: sandbox, uses buildman)
* ``-B, --build-dir <dir>`` - Use existing build directory instead of building
* ``--build-base <dir>`` - Base directory for builds (default: /tmp/b)
* ``-n, --no-build`` - Skip building, use existing build directory
* ``-a, --adjust <config>`` - Adjust CONFIG options (see section above)

Line-level analysis:

* ``-w, --dwarf`` - Use DWARF debug info (most accurate, requires rebuild)
* ``-i, --include-headers`` - Include header files in unifdef analysis

Filtering:

* ``-f, --filter <pattern>`` - Filter files by wildcard pattern (e.g.,
  ``*acpi*``)

Output control:

* ``-v, --verbose`` - Show verbose output
* ``-D, --debug`` - Enable debug mode
* ``--top <N>`` - (for ``stats`` command) Show top N files with most inactive
  code (default: 20)

The ``dirs command`` has a few extra options:

* ``-s, --subdirs`` - Show a breakdown by subdirectory
* ``-f, --show-files`` - Show individual files within directories (with ``-s``)
* ``-e, --show-empty`` - Show directories/files with 0 lines used
* ``-k, --kloc`` - Show line counts in kilolines (kLOC) instead of raw lines
* ``--html <file>`` - Generate an HTML report with collapsible drill-down

Other:

* ``-j, --jobs <N>`` - Number of parallel jobs for line analysis

How to use commands
===================

The following commands show the different ways to use codman. Commands are
specified as positional arguments after the global options.

Basic Statistics (``stats``)
-----------------------------

Show overall statistics for sandbox build::

    $ codman -b qemu-x86 stats
    ======================================================================
    FILE-LEVEL STATISTICS
    ======================================================================
    Total source files:    15158
    Used source files:      1172 (7.7%)
    Unused source files:   14105 (93.1%)

    Total lines of code:  3724057
    Used lines of code:   243226 (6.5%)
    Unused lines of code: 3480831 (93.5%)
    ======================================================================

    ======================================================================
    LINE-LEVEL STATISTICS (within compiled files)
    ======================================================================
    Files analysed:              595
    Total lines in used files:261490
    Active lines:             243226 (93.0%)
    Inactive lines:            18264 (7.0%)
    ======================================================================

    TOP 20 FILES WITH MOST INACTIVE CODE:
    ----------------------------------------------------------------------
       2621 inactive lines (56.6%) - drivers/mtd/spi/spi-nor-core.c
        669 inactive lines (46.7%) - cmd/mem.c
        594 inactive lines (45.8%) - cmd/nvedit.c
        579 inactive lines (89.5%) - drivers/mtd/spi/spi-nor-ids.c
        488 inactive lines (27.4%) - net/net.c
    ...


Directory Breakdown (``dirs``)
------------------------------

See which top-level directories contribute code::

    codman dirs

Output shows breakdown by directory::

    =======================================================================================
    Directory                                  Files    Used  %Used  %Code    Lines    Used
    ---------------------------------------------------------------------------------------
    arch                                        3283     132      4      3   711047   19411
    board                                       1373       1      0      0   443368      35
    boot                                          81      45     56     67    35432   23748
    cmd                                          243      76     31     29    65008   18714
    common                                        94      37     39     47    54752   25463
    ...

For detailed subdirectory breakdown::

    codman dirs --subdirs

With ``--show-files`` (``-f``), also shows individual files within each
directory. Files are sorted alphabetically and those with zero active lines
are hidden by default (use ``-e`` to show them)::

    codman dirs --subdirs --show-files

Use ``--kloc`` (``-k``) for a more compact display with kilolines::

    codman dirs -sfk

You can also specify a file filter::

    codman -b qemu-x86 -f "*acpi*" dirs -sf
    =======================================================================================
    BREAKDOWN BY TOP-LEVEL DIRECTORY
    =======================================================================================
    Directory                                  Files    Used  %Used  %Code    Lines    Used
    ---------------------------------------------------------------------------------------
    arch/x86/include/asm                           5       2     40     36      614     221
    arch/x86/lib                                   5       1     20      6     1166      65
      acpi.c                                                           100       65      65

    cmd                                            1       1    100    100      216     215
      acpi.c                                                           100      216     215

    drivers/qfw                                    1       1    100     93      332     309
      qfw_acpi.c                                                        93      332     309

    include/acpi                                   5       4     80     91     3319    3032
    include/dm                                     1       1    100    100      377     377
    include/power                                  1       1    100    100      199     199
    lib/acpi                                      13       3     23     14     3935     544
      acpi.c                                                           100      304     304
      acpi_extra.c                                                      98      181     177
      acpi_writer.c                                                     48      131      63

    lib/efi_loader                                 1       1    100    100       75      75
      efi_acpi.c                                                       100       75      75

    ---------------------------------------------------------------------------------------
    TOTAL                                         86      15     17      7    17547    1208
    =======================================================================================


Detail View (``detail``)
------------------------

See exactly which lines are active/inactive in a specific file::

    $ codman -b qemu-x86 detail common/main.c
    ======================================================================
    DETAIL FOR: common/main.c
    ======================================================================
    Total lines:       115
    Active lines:       93 (80.9%)
    Inactive lines:     22 (19.1%)

        1 | // SPDX-License-Identifier: GPL-2.0+
        2 | /*
        3 |  * (C) Copyright 2000
        4 |  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
        5 |  */
    ...
        23 |
        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 with a ``-`` marker are not included in the build.

HTML Reports (``dirs --html``)
------------------------------

Generate an interactive HTML report with collapsible directory structure::

    codman -b qemu-x86 dirs -sf --html report.html

The HTML report includes:

* Color-coded metrics (green for high usage, red for low)
* Collapsible hierarchical directory structure for drill-down navigation
* Build information in the header (board name, analysis method)
* File-level details within each directory

This is useful for sharing reports or exploring large codebases interactively
in a web browser.

Unused Files (``unused``)
-------------------------

Find all source files that weren't compiled::

    $ codman -b qemu-x86 unused  |head -12
    Unused source files (14105):
      arch/arc/cpu/arcv1/ivt.S
      arch/arc/cpu/arcv2/ivt.S
      arch/arc/include/asm/arc-bcr.h
      arch/arc/include/asm/arcregs.h
      arch/arc/include/asm/bitops.h
    ...

Used Files (``used``)
---------------------

List all source files that were included in a build::

    $ codman -b qemu-x86 used  |head -12
    Used source files (1172):
      arch/x86/cpu/call32.S
      arch/x86/cpu/cpu.c
      arch/x86/cpu/cpu_x86.c
      arch/x86/cpu/i386/call64.S
      arch/x86/cpu/i386/cpu.c
    ...


Per-File Summary (``summary``)
------------------------------

Shows detailed per-file statistics (requires ``-w`` or ``-l``)::

    $ codman -b qemu-x86 summary
    ==========================================================================================
    PER-FILE SUMMARY
    ==========================================================================================
    File                                                  Total   Active Inactive  %Active
    ------------------------------------------------------------------------------------------
    arch/x86/cpu/call32.S                                    61       61        0   100.0%
    arch/x86/cpu/cpu.c                                      399      353       46    88.5%
    arch/x86/cpu/cpu_x86.c                                   99       99        0   100.0%
    arch/x86/cpu/i386/call64.S                               92       92        0   100.0%
    arch/x86/cpu/i386/cpu.c                                 649      630       19    97.1%
    arch/x86/cpu/i386/interrupt.c                           630      622        8    98.7%
    arch/x86/cpu/i386/setjmp.S                               65       65        0   100.0%
    arch/x86/cpu/intel_common/cpu.c                         325      325        0   100.0%
    ...

Copy Used Files (``copy-used``)
-------------------------------

Extract only the source files used in a build::

  codman copy-used /tmp/sandbox-sources

This creates a directory tree with only the compiled files, useful for creating
minimal source distributions.

Analysis Methods
================

The script supports several analysis methods with different trade-offs.

Firstly, files are detected by looking for .cmd files in the build. This
requires a build to be present. Given the complexity of the Makefile rules, it
seems like a reasonable trade-off. These directories are excluded:

* tools/
* test/
* scripts/
* doc/

unifdef
-------

For discovering used/unused code, the unifdef mechanism produces reasonable
results. This simulates the C preprocessor using the ``unifdef`` tool to
determine which lines are active based on CONFIG_* settings.

**Note:** This requires a patched version of unifdef that supports U-Boot's
``IS_ENABLED()`` and ``CONFIG_IS_ENABLED()`` macros, which are commonly used
throughout the codebase. It also supports faster operation, reducing run time
by about 100x on the U-Boot code base.

The tools:

1. Reads .config to extract all CONFIG_* symbol definitions
2. Generates a unifdef configuration file with -D/-U directives
3. Runs ``unifdef -k -E`` on each source file to process conditionals, with
   ``-E`` enabling the IS_ENABLED() support
4. Compares original vs. processed output using line-number information
5. Lines removed by unifdef are marked as inactive

This method Uses multiprocessing for parallel analysis of source files, so it
runs faster if you have plenty of CPU cores (e.g. 3s on a 22-thread
Intel Ultra 7).

The preprocessor-level view is quite helpful. It is also possible to see .h
files using the ``-i`` flag

Since unifdef does fairly simplistic parsing it can be fooled and show wrong
results.


DWARF (``-w/--dwarf``)
----------------------

The DWARF analyser uses debug information embedded in compiled object files to
determine exactly which source lines generated machine code. This is arguably
more accurate than unifdef, but it won't count comments, declarations and
various other features that don't actually generate code.

The DWARF analyser:

1. Rebuilds with ``CC_OPTIMIZE_FOR_DEBUG`` to prevent aggressive inlining
2. For each .o file, runs ``readelf --debug-dump=decodedline`` to get line info
3. Parses the DWARF line number table to map source lines to code addresses
4. Aggregates results across all object files
5. Any source line that doesn't appear in the line table is marked inactive

As with unifdef, this uses multiprocessing for parallel analysis of object
files. It achieves similar performance.


See Also
========

* :doc:`../build/buildman` - Tool for building multiple boards
* :doc:`qconfig`
* :doc:`checkpatch` - Code-style checking tool