asmdiff 0.1.1__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python3 test_asmdiff.py)",
5
+ "Bash(git -C /home/fatta/esp-idf/tools/asmdiff log --oneline -5)",
6
+ "Bash(git -C /home/fatta/esp-idf/tools/asmdiff diff main...HEAD --stat)"
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,2 @@
1
+ __pycache__/
2
+ *.py[cod]
@@ -0,0 +1,28 @@
1
+ # asmdiff
2
+
3
+ Single-file, stdlib-only Python CLI that compares per-function assembly
4
+ between paired C implementations across a compiler matrix. Published to
5
+ PyPI as `asmdiff` (hatchling build, see pyproject.toml).
6
+
7
+ ## Toolchain
8
+
9
+ - Runtime: Python >= 3.8; config files (asmdiff.toml) need >= 3.11 (tomllib).
10
+ - No third-party dependencies, in source or tests. Keep it that way.
11
+ - Compilers invoked at runtime: whatever the user's matrix names
12
+ (host gcc/clang, xtensa/riscv ESP toolchains via glob patterns).
13
+
14
+ ## Commands
15
+
16
+ - Run tests: `python3 test_asmdiff.py` (unittest; add `-v` for detail).
17
+ - Run the tool: `python3 asmdiff.py asmdiff_example.c`.
18
+ - Everything is safe/reversible: the tool only compiles to `-S` in a
19
+ temp dir and prints. No flashing, no shared infra.
20
+
21
+ ## Layout
22
+
23
+ - `asmdiff.py` — the entire tool.
24
+ - `test_asmdiff.py` — unit tests, one class per feature area.
25
+ - `asmdiff.example.toml` — documented starter config; keep it generic
26
+ (portable gcc/clang defaults, ESP targets as commented examples).
27
+ - README.md documents every user-visible behavior; changes to flags or
28
+ config keys update README, example toml, and the module docstring.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: asmdiff
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Compare per-function assembly between paired C implementations
5
5
  Project-URL: Homepage, https://github.com/rt-rtos/asmdiff
6
6
  Project-URL: Repository, https://github.com/rt-rtos/asmdiff
@@ -16,7 +16,7 @@ Classifier: Topic :: Software Development :: Debuggers
16
16
  Requires-Python: >=3.8
17
17
  Description-Content-Type: text/markdown
18
18
 
19
- # asmdiff
19
+ # [asmdiff](https://pypi.org/project/asmdiff/)
20
20
  ## per-function assembly comparison for paired C implementations
21
21
 
22
22
  > asmdiff is a stdlib only command-line tool for comparing the generated assembly of individual C functions across implementations, compiler flags, compiler versions, and source revisions. It is intended for investigating compiler code generation rather than benchmarking runtime performance.
@@ -94,7 +94,7 @@ $ asmdiff.py asmdiff_example.c
94
94
  ```
95
95
  asmdiff.py SOURCE.c [SOURCE2.c] [--pair OLD:NEW]... [--across FUNC]...
96
96
  [--cc 'CC FLAGS']... [--target NAME]... [--config PATH]
97
- [-- EXTRA_FLAGS...]
97
+ [--compile-commands [PATH]] [-v] [-- EXTRA_FLAGS...]
98
98
  ```
99
99
 
100
100
  | Option | Meaning |
@@ -105,6 +105,8 @@ asmdiff.py SOURCE.c [SOURCE2.c] [--pair OLD:NEW]... [--across FUNC]...
105
105
  | `--cc 'CC FLAGS'` | One compiler invocation, command and flags in a single quoted string. Repeatable to build a matrix. |
106
106
  | `--target NAME` | A named target from the config file, resolved to a `--cc` entry. Repeatable; appended to the matrix after `--cc` entries. |
107
107
  | `--config PATH` | Config file to use. Default search: `asmdiff.toml` next to `SOURCE.c`, then in the current directory, then `~/.config/`. First hit wins. |
108
+ | `--compile-commands [PATH]` | Borrow each source's include/define flags from a `compile_commands.json`; with no `PATH`, walk up from the CWD checking each directory and its `build/` until the repository root. See [below](#borrowing-includes-from-compile_commandsjson). |
109
+ | `-v`, `--verbose` | On compile failure, print the full compiler command and complete error output. Default shows only the compiler, the source, and the first error lines. |
108
110
  | `-- FLAGS...` | Everything after a bare `--` is appended to *every* compiler invocation. |
109
111
 
110
112
  With no `--cc` and no `--target`, the config file's top-level
@@ -139,19 +141,19 @@ each compiler+flags combination once:
139
141
 
140
142
  ```toml
141
143
  # asmdiff.toml — next to your harnesses, in CWD, or in ~/.config/
142
- default = "s3-amy" # target(s) used when no --cc/--target is given
144
+ default = "esp32s3" # target(s) used when no --cc/--target is given
143
145
 
144
- [s3-amy] # production-like ESP32-S3 codegen
146
+ [esp32s3] # production-like ESP32-S3 codegen
145
147
  cc = "$HOME/.espressif/tools/xtensa-esp-elf/esp-*/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc"
146
148
  flags = [
147
- "-O2", "-DAMY_USE_FIXEDPOINT", "-DNDEBUG",
149
+ "-O2", "-DMY_FEATURE", "-DNDEBUG",
148
150
  "-Wno-strict-aliasing", "-mlongcalls",
149
- "-I$HOME/project/components/amy/src",
151
+ "-I$HOME/project/components/dsp/include",
150
152
  ]
151
153
 
152
- [host-fixed] # same defines on host gcc
154
+ [host] # same defines on host gcc
153
155
  cc = "gcc"
154
- flags = ["-O2", "-DAMY_USE_FIXEDPOINT", "-I$HOME/amy/src"]
156
+ flags = ["-O2", "-DMY_FEATURE", "-I$HOME/project/components/dsp/include"]
155
157
  ```
156
158
 
157
159
  `cc` values expand `~` and `$VARS` and may be glob patterns, so a config
@@ -168,8 +170,8 @@ shapes:
168
170
 
169
171
  ```bash
170
172
  asmdiff.py h.c # config default target(s)
171
- asmdiff.py h.c --target s3-amy --target host-fixed # two-target matrix
172
- asmdiff.py h.c --across f --target s3-amy --cc 'gcc -O2' # mix freely
173
+ asmdiff.py h.c --target esp32s3 --target host # two-target matrix
174
+ asmdiff.py h.c --across f --target esp32s3 --cc 'gcc -O2' # mix freely
173
175
  ```
174
176
 
175
177
  A config placed next to your harness files travels with them: any invocation
@@ -179,6 +181,100 @@ included `asmdiff.example.toml` is a starting point. If a flag or include
179
181
  path must vary per machine, that's what per-machine config files are for —
180
182
  nothing lives in the tool.
181
183
 
184
+ ### Borrowing includes from `compile_commands.json`
185
+
186
+ A real project source rarely compiles with a handful of `-I` flags. An
187
+ ESP-IDF component pulls in `freertos/FreeRTOS.h`, `esp_*` headers, and a
188
+ *generated* `sdkconfig.h`, reachable only through the dozens of `-I`/`-D`
189
+ flags the build system computes — none of which live in the source file.
190
+ That is why `asmdiff.py component.c` fails with `freertos/FreeRTOS.h: No
191
+ such file or directory`: not a wrong compiler (the xtensa toolchain ships
192
+ no FreeRTOS either), just missing include paths. Transcribing them by hand
193
+ is miserable.
194
+
195
+ So don't. Any build that uses CMake or Ninja can emit a
196
+ [`compile_commands.json`](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
197
+ recording the exact flags for every source it builds (ESP-IDF writes one to
198
+ `build/compile_commands.json` on every `idf.py build`). Point a target at it:
199
+
200
+ ```toml
201
+ [esp32s3-idf]
202
+ cc = "xtensa-esp32s3-elf-gcc"
203
+ flags = ["-O2", "-mlongcalls"]
204
+ compile_commands = "$HOME/myproject/build/compile_commands.json"
205
+
206
+ ```
207
+
208
+ Now `asmdiff.py $HOME/myproject/components/dsp/biquad.c --target esp32s3-idf`
209
+ finds that file's entry in the database and adds the include/define flags
210
+ it recorded — `-I`, `-isystem`, `-iquote`, `-idirafter`, `-include`,
211
+ `-imacros`, `-D`, `-U`, plus the header-environment driver flags `-specs`
212
+ and `--sysroot` — to this target's command. Everything else the
213
+ database records (its own compiler, `-O`/`-std`/`-W` flags, `-c`, `-o`, the
214
+ source) is ignored: **you** own the compiler and optimisation flags via
215
+ `cc`/`flags`; only the header environment is borrowed. That split is the
216
+ point — you can now sweep *your* `-O`/`-m` variations over a source that
217
+ only ever compiled one way under the build system.
218
+
219
+ Details that make it robust:
220
+
221
+ - **Paths are made absolute** against each entry's `directory`, so a
222
+ database full of build-relative `-I../include` flags still resolves when
223
+ asmdiff runs from anywhere.
224
+ - **`@file` response files are expanded.** Build systems park flags in
225
+ them — ESP-IDF v6 hides `-specs=picolibc.specs` in
226
+ `build/toolchain/cflags`, and without it every libc header breaks —
227
+ so the flag scan reads them (nested ones too) instead of skipping the
228
+ token. A bare specs name is left for the compiler's own search
229
+ directories; a specs path resolves like any other recorded path.
230
+ - **Per source file.** The lookup keys on the source you pass (matched by
231
+ resolved absolute path), so two files in an `--across`/summary run each
232
+ get their own recorded flags.
233
+ - **Absent source is an error**, not a silent empty flag set — otherwise
234
+ you'd just hit the missing-header failure this feature exists to prevent.
235
+ The message flags a same-basename entry recorded under a different path.
236
+ - **`compile_commands` expands `~` and `$VARS`.** The `==` header always
237
+ prints the resolved compiler command; run with `-- -v` if you want to see
238
+ every include path the compiler actually received.
239
+
240
+ ### Auto-discovering the database
241
+
242
+ When you run asmdiff from inside the project anyway, the path is
243
+ redundant. Two opt-ins skip it:
244
+
245
+ ```toml
246
+ [esp32s3-idf]
247
+ cc = "xtensa-esp32s3-elf-gcc"
248
+ flags = ["-O2", "-mlongcalls"]
249
+ compile_commands = true # search instead of naming a path
250
+ ```
251
+
252
+ ```bash
253
+ asmdiff.py biquad.c --compile-commands # same, for any matrix
254
+ asmdiff.py biquad.c --compile-commands path/to/compile_commands.json
255
+ ```
256
+
257
+ Both walk up from the current directory, checking each level for
258
+ `compile_commands.json` and then `build/compile_commands.json` (where
259
+ CMake and idf.py leave it) — first hit wins. The walk stops at the
260
+ repository root (the first directory with a `.git`), so running from any
261
+ depth of component directory finds the project database, but an unrelated
262
+ one further up the filesystem is never picked up. Finding nothing is an
263
+ error: discovery is opt-in, so if you asked for it, silence would be a
264
+ lie. It is never on by default — a target without `compile_commands` and
265
+ no `--compile-commands` flag borrows nothing.
266
+
267
+ The precedence is what you'd hope: a target that names its own
268
+ `compile_commands` path always keeps it; `--compile-commands` (with or
269
+ without a path) fills in every other matrix entry, including `--cc`
270
+ strings and the built-in gcc/clang fallback.
271
+
272
+ One behavioral difference: with a *discovered* database, a source that has
273
+ no entry is compiled without borrowed flags after a one-line stderr note,
274
+ instead of being an error. That keeps standalone harness files working
275
+ when a `build/` directory happens to sit nearby; an explicitly named
276
+ database still treats an absent source as the error it is.
277
+
182
278
  ## Whole-file summary
183
279
 
184
280
  With no `--pair`, no `--across`, and no `old_*`/`new_*` functions to
@@ -207,6 +303,12 @@ weight, did a call appear that shouldn't have? It sums parsed function
207
303
  bodies only (no literal pools, data, or alignment), so it is not a size
208
304
  measurement, and per-function rows are where the real information is.
209
305
 
306
+ Only labels the assembler types as functions are listed — global data
307
+ (string constants, state structs, lookup tables) gets column-0 labels too
308
+ but is not code. A `calls` list longer than 8 symbols is truncated to
309
+ `..., +N more`; real firmware dispatch functions call dozens of distinct
310
+ symbols and would otherwise make rows thousands of characters wide.
311
+
210
312
  ## Comparing the same function across two builds (`--across`)
211
313
 
212
314
  `--pair` needs both variants to coexist in one compilation. Real changes
@@ -1,4 +1,4 @@
1
- # asmdiff
1
+ # [asmdiff](https://pypi.org/project/asmdiff/)
2
2
  ## per-function assembly comparison for paired C implementations
3
3
 
4
4
  > asmdiff is a stdlib only command-line tool for comparing the generated assembly of individual C functions across implementations, compiler flags, compiler versions, and source revisions. It is intended for investigating compiler code generation rather than benchmarking runtime performance.
@@ -76,7 +76,7 @@ $ asmdiff.py asmdiff_example.c
76
76
  ```
77
77
  asmdiff.py SOURCE.c [SOURCE2.c] [--pair OLD:NEW]... [--across FUNC]...
78
78
  [--cc 'CC FLAGS']... [--target NAME]... [--config PATH]
79
- [-- EXTRA_FLAGS...]
79
+ [--compile-commands [PATH]] [-v] [-- EXTRA_FLAGS...]
80
80
  ```
81
81
 
82
82
  | Option | Meaning |
@@ -87,6 +87,8 @@ asmdiff.py SOURCE.c [SOURCE2.c] [--pair OLD:NEW]... [--across FUNC]...
87
87
  | `--cc 'CC FLAGS'` | One compiler invocation, command and flags in a single quoted string. Repeatable to build a matrix. |
88
88
  | `--target NAME` | A named target from the config file, resolved to a `--cc` entry. Repeatable; appended to the matrix after `--cc` entries. |
89
89
  | `--config PATH` | Config file to use. Default search: `asmdiff.toml` next to `SOURCE.c`, then in the current directory, then `~/.config/`. First hit wins. |
90
+ | `--compile-commands [PATH]` | Borrow each source's include/define flags from a `compile_commands.json`; with no `PATH`, walk up from the CWD checking each directory and its `build/` until the repository root. See [below](#borrowing-includes-from-compile_commandsjson). |
91
+ | `-v`, `--verbose` | On compile failure, print the full compiler command and complete error output. Default shows only the compiler, the source, and the first error lines. |
90
92
  | `-- FLAGS...` | Everything after a bare `--` is appended to *every* compiler invocation. |
91
93
 
92
94
  With no `--cc` and no `--target`, the config file's top-level
@@ -121,19 +123,19 @@ each compiler+flags combination once:
121
123
 
122
124
  ```toml
123
125
  # asmdiff.toml — next to your harnesses, in CWD, or in ~/.config/
124
- default = "s3-amy" # target(s) used when no --cc/--target is given
126
+ default = "esp32s3" # target(s) used when no --cc/--target is given
125
127
 
126
- [s3-amy] # production-like ESP32-S3 codegen
128
+ [esp32s3] # production-like ESP32-S3 codegen
127
129
  cc = "$HOME/.espressif/tools/xtensa-esp-elf/esp-*/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc"
128
130
  flags = [
129
- "-O2", "-DAMY_USE_FIXEDPOINT", "-DNDEBUG",
131
+ "-O2", "-DMY_FEATURE", "-DNDEBUG",
130
132
  "-Wno-strict-aliasing", "-mlongcalls",
131
- "-I$HOME/project/components/amy/src",
133
+ "-I$HOME/project/components/dsp/include",
132
134
  ]
133
135
 
134
- [host-fixed] # same defines on host gcc
136
+ [host] # same defines on host gcc
135
137
  cc = "gcc"
136
- flags = ["-O2", "-DAMY_USE_FIXEDPOINT", "-I$HOME/amy/src"]
138
+ flags = ["-O2", "-DMY_FEATURE", "-I$HOME/project/components/dsp/include"]
137
139
  ```
138
140
 
139
141
  `cc` values expand `~` and `$VARS` and may be glob patterns, so a config
@@ -150,8 +152,8 @@ shapes:
150
152
 
151
153
  ```bash
152
154
  asmdiff.py h.c # config default target(s)
153
- asmdiff.py h.c --target s3-amy --target host-fixed # two-target matrix
154
- asmdiff.py h.c --across f --target s3-amy --cc 'gcc -O2' # mix freely
155
+ asmdiff.py h.c --target esp32s3 --target host # two-target matrix
156
+ asmdiff.py h.c --across f --target esp32s3 --cc 'gcc -O2' # mix freely
155
157
  ```
156
158
 
157
159
  A config placed next to your harness files travels with them: any invocation
@@ -161,6 +163,100 @@ included `asmdiff.example.toml` is a starting point. If a flag or include
161
163
  path must vary per machine, that's what per-machine config files are for —
162
164
  nothing lives in the tool.
163
165
 
166
+ ### Borrowing includes from `compile_commands.json`
167
+
168
+ A real project source rarely compiles with a handful of `-I` flags. An
169
+ ESP-IDF component pulls in `freertos/FreeRTOS.h`, `esp_*` headers, and a
170
+ *generated* `sdkconfig.h`, reachable only through the dozens of `-I`/`-D`
171
+ flags the build system computes — none of which live in the source file.
172
+ That is why `asmdiff.py component.c` fails with `freertos/FreeRTOS.h: No
173
+ such file or directory`: not a wrong compiler (the xtensa toolchain ships
174
+ no FreeRTOS either), just missing include paths. Transcribing them by hand
175
+ is miserable.
176
+
177
+ So don't. Any build that uses CMake or Ninja can emit a
178
+ [`compile_commands.json`](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
179
+ recording the exact flags for every source it builds (ESP-IDF writes one to
180
+ `build/compile_commands.json` on every `idf.py build`). Point a target at it:
181
+
182
+ ```toml
183
+ [esp32s3-idf]
184
+ cc = "xtensa-esp32s3-elf-gcc"
185
+ flags = ["-O2", "-mlongcalls"]
186
+ compile_commands = "$HOME/myproject/build/compile_commands.json"
187
+
188
+ ```
189
+
190
+ Now `asmdiff.py $HOME/myproject/components/dsp/biquad.c --target esp32s3-idf`
191
+ finds that file's entry in the database and adds the include/define flags
192
+ it recorded — `-I`, `-isystem`, `-iquote`, `-idirafter`, `-include`,
193
+ `-imacros`, `-D`, `-U`, plus the header-environment driver flags `-specs`
194
+ and `--sysroot` — to this target's command. Everything else the
195
+ database records (its own compiler, `-O`/`-std`/`-W` flags, `-c`, `-o`, the
196
+ source) is ignored: **you** own the compiler and optimisation flags via
197
+ `cc`/`flags`; only the header environment is borrowed. That split is the
198
+ point — you can now sweep *your* `-O`/`-m` variations over a source that
199
+ only ever compiled one way under the build system.
200
+
201
+ Details that make it robust:
202
+
203
+ - **Paths are made absolute** against each entry's `directory`, so a
204
+ database full of build-relative `-I../include` flags still resolves when
205
+ asmdiff runs from anywhere.
206
+ - **`@file` response files are expanded.** Build systems park flags in
207
+ them — ESP-IDF v6 hides `-specs=picolibc.specs` in
208
+ `build/toolchain/cflags`, and without it every libc header breaks —
209
+ so the flag scan reads them (nested ones too) instead of skipping the
210
+ token. A bare specs name is left for the compiler's own search
211
+ directories; a specs path resolves like any other recorded path.
212
+ - **Per source file.** The lookup keys on the source you pass (matched by
213
+ resolved absolute path), so two files in an `--across`/summary run each
214
+ get their own recorded flags.
215
+ - **Absent source is an error**, not a silent empty flag set — otherwise
216
+ you'd just hit the missing-header failure this feature exists to prevent.
217
+ The message flags a same-basename entry recorded under a different path.
218
+ - **`compile_commands` expands `~` and `$VARS`.** The `==` header always
219
+ prints the resolved compiler command; run with `-- -v` if you want to see
220
+ every include path the compiler actually received.
221
+
222
+ ### Auto-discovering the database
223
+
224
+ When you run asmdiff from inside the project anyway, the path is
225
+ redundant. Two opt-ins skip it:
226
+
227
+ ```toml
228
+ [esp32s3-idf]
229
+ cc = "xtensa-esp32s3-elf-gcc"
230
+ flags = ["-O2", "-mlongcalls"]
231
+ compile_commands = true # search instead of naming a path
232
+ ```
233
+
234
+ ```bash
235
+ asmdiff.py biquad.c --compile-commands # same, for any matrix
236
+ asmdiff.py biquad.c --compile-commands path/to/compile_commands.json
237
+ ```
238
+
239
+ Both walk up from the current directory, checking each level for
240
+ `compile_commands.json` and then `build/compile_commands.json` (where
241
+ CMake and idf.py leave it) — first hit wins. The walk stops at the
242
+ repository root (the first directory with a `.git`), so running from any
243
+ depth of component directory finds the project database, but an unrelated
244
+ one further up the filesystem is never picked up. Finding nothing is an
245
+ error: discovery is opt-in, so if you asked for it, silence would be a
246
+ lie. It is never on by default — a target without `compile_commands` and
247
+ no `--compile-commands` flag borrows nothing.
248
+
249
+ The precedence is what you'd hope: a target that names its own
250
+ `compile_commands` path always keeps it; `--compile-commands` (with or
251
+ without a path) fills in every other matrix entry, including `--cc`
252
+ strings and the built-in gcc/clang fallback.
253
+
254
+ One behavioral difference: with a *discovered* database, a source that has
255
+ no entry is compiled without borrowed flags after a one-line stderr note,
256
+ instead of being an error. That keeps standalone harness files working
257
+ when a `build/` directory happens to sit nearby; an explicitly named
258
+ database still treats an absent source as the error it is.
259
+
164
260
  ## Whole-file summary
165
261
 
166
262
  With no `--pair`, no `--across`, and no `old_*`/`new_*` functions to
@@ -189,6 +285,12 @@ weight, did a call appear that shouldn't have? It sums parsed function
189
285
  bodies only (no literal pools, data, or alignment), so it is not a size
190
286
  measurement, and per-function rows are where the real information is.
191
287
 
288
+ Only labels the assembler types as functions are listed — global data
289
+ (string constants, state structs, lookup tables) gets column-0 labels too
290
+ but is not code. A `calls` list longer than 8 symbols is truncated to
291
+ `..., +N more`; real firmware dispatch functions call dozens of distinct
292
+ symbols and would otherwise make rows thousands of characters wide.
293
+
192
294
  ## Comparing the same function across two builds (`--across`)
193
295
 
194
296
  `--pair` needs both variants to coexist in one compilation. Real changes
@@ -0,0 +1,51 @@
1
+ # asmdiff config — named compiler+flags targets.
2
+ #
3
+ # Copy to one of the locations asmdiff searches (first hit wins):
4
+ # 1. the path given with --config
5
+ # 2. asmdiff.toml next to the SOURCE.c being compiled
6
+ # 3. asmdiff.toml in the current directory
7
+ # 4. ~/.config/asmdiff.toml
8
+ #
9
+ # Each [table] is a target usable as `--target NAME`; the optional
10
+ # top-level `default` names the target(s) used when no --cc/--target
11
+ # is given (a list runs several: default = ["gcc", "clang"]).
12
+ # Compile at the flags your project ships with — that is the whole
13
+ # point of the tool.
14
+
15
+ default = "gcc"
16
+
17
+ [gcc]
18
+ cc = "gcc"
19
+ flags = [
20
+ "-O3", "-Wall", "-Wextra",
21
+ # Project-specific include paths and defines go here:
22
+ # "-I/path/to/project/src", "-DMY_FEATURE",
23
+ ]
24
+
25
+ [clang]
26
+ cc = "clang"
27
+ flags = ["-O3", "-Wall", "-Wextra"]
28
+
29
+ # cc values may use ~, $VARS, and glob patterns. A glob that matches
30
+ # several installed toolchains resolves to the highest version-sorted
31
+ # one (announced on stderr); pin the exact esp-NN directory instead if
32
+ # reproducibility across sessions matters more than convenience.
33
+ [esp32s3]
34
+ cc = "$HOME/.espressif/tools/xtensa-esp-elf/esp-*/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc"
35
+ flags = ["-O2", "-mlongcalls", "-DNDEBUG"]
36
+
37
+ # A project source that pulls in framework headers (ESP-IDF's freertos/*,
38
+ # esp_*, a generated sdkconfig.h, ...) needs the dozens of -I/-D flags its
39
+ # build system passes. Point `compile_commands` at the database that build
40
+ # emits (idf.py leaves build/compile_commands.json), and asmdiff copies the
41
+ # include/define flags recorded there for the file being compiled — so you
42
+ # never transcribe include paths by hand. The compiler and -O/-m flags
43
+ # still come from cc/flags; only the header environment is borrowed.
44
+ # A path expands ~ and $VARS; `compile_commands = true` instead searches
45
+ # at run time: each directory from the CWD up to the repository root,
46
+ # and its build/ subdirectory (a source missing from a database found
47
+ # that way is compiled without borrowed flags, with a note).
48
+ [esp32s3-idf]
49
+ cc = "$HOME/.espressif/tools/xtensa-esp-elf/esp-*/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc"
50
+ flags = ["-O2", "-mlongcalls"]
51
+ compile_commands = true