Follow

Can somebody help me understand how come doesn't seem to have any built-in way to print out all available targets in the project?

I mean, if you can do `cmake --build . --target foobar`, surely you should be able to do `cmake . --list-targets` or equivalent, to discover the possible options to put in `--target` option in the first place!

But apparently you can't, and it seems like somehow it's a weird thing to ask for (like nobody tried to integrate CMake with other tooling before?)...

· · Web · 1 · 1 · 1

@temporal I don't know about other generators, but for Makefiles it does generate a help target that seems to list some (if not all) targets.

@ryuslash So it does! I guess it beats just grepping through CMakeLists.txt (or parsing CMakeCache.txt - there's enough info in there to recover a list of dependencies).

But then, that only works if you use Makefiles. I currently do, but that's just an accident.

I don't understand why this isn't a built-in feature of CMake itself. Instead of building help targets for a subset of generators, I should be able to just list all *CMake* targets, using CMake, regardless of the generator I picked.

@temporal I mostly have experience with the visual studio generator, which has its own thing in theory. There might be something possible with either the BUILDSYSTEM_TARGETS directory property, or the cmake-file-api(7)? There is also the --graphviz command-line argument which would get you a graphviz file of the dependencies.

The only thing I can think of is that to generate a list of targets in CMake you might have to run an arbitrary amount of code. It would be nice though

@ryuslash Oooh, didn't know about cmake-file-api, thanks! It's an interesting hack. Sadly, it became available only with CMake 3.14.x, and half of my workflow runs on 3.12...

Anyway, yeah, I get that generating a list of targets is potentially Turing-complete. But CMake can compute and provide it through generators, as Graphviz, via cmake-file-api, and indirectly stores it in CMakeCache.txt in at least two different ways. It shouldn't be a problem to give the list of targets in a given build folder...

@ryuslash All I'm asking for is that, if I can issue a command like:

cmake --build . --target FOO

Then I want a way to programmatically get a list of allowed values for FOO. Not sure why this is not an obvious feature.

CTest at least has -N option, but then it's annoyingly isolating - doesn't give a way to pass arguments to actual test executable. And unfortunately, "list all tests" is the one GoogleTest flag you can't specify as env var... so I have to skip using CTest anyway to get what I need.

@ryuslash

Ultimately, the simplest and most reliable thing I can do is...

...grep the whole project filetree for:

"add_(library|executable|.test)\((.*)\b"

Or possibly rerun CMake in trace mode and grep output for the same, in case the project uses custom functions/macros to add their targets.

Seems much easier and more stable than any of the alternatives.

@ryuslash I know I should stop ranting already, but holy hell, CMake seems *designed* to make this task impossible.

E.g. there's a GLOBAL_DEPENDS_DEBUG_MODE property that can print what I need... but you cannot set it from CLI. You have to modify CMake files in your project.

Meanwhile, they deprecated the bit of CMakeCache that implicitly contained target graph in plain format.

I'm becoming convinced they're doing it on purpose, for some twisted reason.

@temporal Dang, that is frustrating and annoying... I have no idea what the thoughts behind this are. I have found it lacking in certain ways as well. I'm curious to actually ask the developers about it. Some of these seem so obvious, like your issue, but there must be a reason they were left out.

I guess you could still try overriding add_* to write to a file or stdout whenever they're called, but you'd still have to run CMake at least once for that.

@ryuslash I ended up going the manual way - ripgrep with a regex to find all add_* commands in CMake files, + some simple classification heuristics.

Works well enough, and even on a large codebase it takes ~0.5 seconds to complete, so I'm fine with that for now.

Sign in to participate in the conversation
Mastodon for Tech Folks

This Mastodon instance is for people interested in technology. Discussions aren't limited to technology, because tech folks shouldn't be limited to technology either!