I'm working on an ESP-IDF based project that runs on ESP32 microcontrollers.
The project has a bunch of different C++ libraries (ESP-IDF calls them components
) I've written. Normally I compile the whole project and it gets installed on the ESP32, and everything works great.
I've been writing tests, and how I make the tests work is a little different than the standard build process. For each set of tests, I am testing just one of my C++ components. (for instance "Wireless" or "UserInputs", etc) I mock out the rest of my components and the ESP-IDF code that my code uses, and this lets me just test "Wireless", for instance.
To do this, I'm using CppUTest
and a series of makefiles. The makefile structure is based on the structure here: https://github.com/memfault/interrupt/tree/master/example/unit-testing/minimal
And here's the article I followed that is describing that makefile/testing setup. https://interrupt.memfault.com/blog/unit-testing-basics#setting-up-cpputest
So, there's a main makefile, and it finds all the per-component makefiles. Those per-component makefiles specify which .cpp
files to compile, what folders to find your imports in, where your tests are, etc. And all that works great.
The situation I'm in is that I want to be able to run the debugger in VSCode to set breakpoints, pause execution, and inspect my variables at a given point in my code.
Just doing this in the tests is enough. I don't need debugger in my main ESP-IDF build process.
But I'm having the most challenging time working with this kind of setup. Because there's not just ONE make file.
Here's the core of what I want to do. I want to be able to set a breakpoint, and then do something to tell my code to compile with a given list of .cpp
files, and header import locations. Just like in those per-component test make files. And I want my code to execute to that breakpoint and then give me the sauce in VSCode.
Any suggestions on how I can work in this direction would be very helpful.
I was able to work this out. Here's what I did...
Firstly, I ran my tests. Now when I look in unit_tests/build/
I see sub
folders for each make file. And in those subfolders there are executables. For instance, unit_tests/build/data/data_tests
I made a .vscode/launch.json
file in my repo. It's looks like this...
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch for Dispatch Component",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/unit_tests/build/dispatch/dispatch_tests",
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) Launch for Wireless Component",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/unit_tests/build/wireless/wireless_tests",
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) Launch for Data Component",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/unit_tests/build/data/data_tests",
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
]
}
Notice that in that launch.json
file there are multiple configurations
. One for each component/make file. The name
of each configuration says what component it's for, and the program
field points to the executable that the tests built.
If I'm in the Data
component and want to drop into a breakpoint, here's
what I do.
Makefile_data.mk
that hits my
breakpoint.Run and Debug
button on the left in VSCode. (the bug with the play button)Run and Debug
and select Launch for Data Component
Now my tests run and when they get to the breakpoint in the code in my Data component they will pause. Pretty slick!