Help with IDE integration, I need clarification on how inheritance is supposed to work

Hello, I’m a software developer currently working on an IDE integration of
cmake. I’ve run into a few issues outside of programming the integration to
do with the integration guide. My expertise is in c++ which has been
helpful except the current project’s in python. I haven’t touched python
much, but in my limited time I’ve not found a module to control cmake via
python that isn’t just running cmake via a shell, which is currently what
I’m doing.

Now as for the problems, I’ve gotten a bit more familiar with cmake’s
command line than I’d like, and it seems to be missing a few things. Namely
if the current cmake project is using presets and the human version of
command line looks like:

cmake --list-presets
…a bunch of config presets…

cmake --build list-presets
…a bunch of build presets…

cmake --preset
cmake --build --preset

What I’ve discovered, because I was trying to have this work smoothly with
projects that are generated by Visual Studio, is that the buildPresets item
in CMakePresets.json can be missing (well to be fair any of the json items
could be missing and introduce problems). Visual Studio seems to paper over
this by actually following the ide guide and parsing the relevant json
files to fill in command line parameters. That’s because it seems if no
buildPresets item exists in the json, you cannot use cmake --build --preset
without an error complaining that the preset doesn’t exist.
However, buried in their documentation is a list of json objects that are
assumed*. In their case what it seems they’ve done is implicitly associated
a build preset to each config preset. This would otherwise make the command
line process for a build much smoother because now there’s a one to one
relationship between “configs” and “builds”, and quite honestly up until
this point I didn’t even know the buildPresets item existed. So in my
limited experience I was under the impression the build process was more
like this:

cmake --list-presets
cmake --preset
cmake --build --preset

Which feels a whole lot nicer.

Now at first glance, I didn’t realize what a slippery slope this feature
was, that’s because despite cmake --list-presets and cmake --build
list-presets giving a person what they would otherwise need to build. It
actually doesn’t give any feedback of which build preset is associated with
each config preset. This means, regardless of what you’re dealing with you
somehow have to work out this relationship. It’s somewhat of a trip up even
at the human level because these relationships might be implicit and or
only hinted at by name. So far as I can tell in order to sort that
relationship out I now have to parse json, and implement cmake inheritance
rules which aren’t clear from the documentation.

So this is where I’ve stopped for the time being. The way the documentation
reads, CMakeUserPresets.json “inherits” from CMakePresets.json, where
CMakePresets.json is not allowed to inherit from CMakeUserPresets.json. I
was in the process of writing something of a dependency walk, however, I
realized I should double check what’s expected to happen when these presets
“inherit” one another. My impression was it was something like an override
for strings and potentially appending arrays together. I’m not sure if for
example I’m supposed to take the array of configs from
CMakeUserPresets.json and CMakePresets.json and combine them together,
overwriting configs with matching names. It’s also not clear if a config
from CMakeUserPresets.json “inherits” from a config of the same name if
that means it’s referring to itself, if it’s meant to refer to a config
from CMakePresets.json. The documentation also mentions what seems like the
potential to include other .json files, I’ve not seen that done and I don’t
know what syntax is used for that, I think though sorting out how
CMakeUserPresets.json and CMakePresets.json works will make dealing with
that trivial.

If there’s a cmake developer here who can unfry my brain a bit, that’d be
much appreciated. I know if I have to I can dig through the cmake source
files and figure out what exactly cmake.exe does, but I want to make sure I
don’t end up writing something that is a bug in the documentation for me to
fix later.

The only other tidbit that confuses me is that it seems the config step is
what gives the potentially required buildDirectory over the console and
only some evaluated cmake variables? I don’t know if there’s a file I could
have my script read instead.

For context as to where I’m at, my script currently parses json, does more
than likely a bugged version of inheritance, macro expands everything in
the json file, it goes one by one through each config because of
${generator} etc… Then it searches through build configs for a provided
“preset”, tries to find an exact match, if it fails it goes over and checks
for a case insensitive match. If it fails that then it searches for a
config preset in a similar fashion, looks for an exact match, then a case
insensitive one. If* it happens to be so unlucky as to be missing the
build-preset, I have it generate a script file with all the cmake variables
under cacheVariables and pass that with -C I’m not bothering to check that
a commandline is too long, I figured this’d be safer anyway. If the user
requests a rebuild instead of a build, then I pass --fresh on the command
line for the config stage.

I’ve not really touched how the CMakeSettings.json process works really
yet, it’s similar, hopefully because there’s no apparent inheritance I’ve
got that right already.

Cc: @kyle.edwards

A bit of an update, I continued working on the integration with a little bit of prodding of what the cmake cli seemed to do given different .json files. Aside from a few patches because of poorly written python on my part, the integration’s roughly where I last mentioned. I’m holding off of anything more complicated than a build, like workflows until later.

Here’s just a visual update of the bits above

cmake --list-presets
…a bunch of config presets…

cmake --build list-presets
…a bunch of build presets…

cmake --preset <config_preset_name>
cmake --build --preset <build_preset_name>
cmake --list-presets
cmake --preset <config_preset_name>
cmake --build --preset <config_preset_name>

You should also pay attention to workflow presets!

For a multi platform useable example see