RFE: does cmake have a "simulate" option? ...

would it even make sense for it to have one?
I am working on compiling webkit2gtk’s source using cmake. I have constantly run into dependency problems with the libraries it uses. It would save people a grate deal of time if they could first do a dry run to know all they need to take care of before attempting the compile such a large code base.

$ which cmake
/usr/bin/cmake

$ cmake --version
cmake version 3.18.4

CMake suite maintained and supported by Kitware (kitware.com/cmake).

$ cmake --help

lbrtchx

let me tell you about a kind of use case in which such a feature would be very useful. this is what cmake tells me while trying to compilewebkit2gtk:

… Could NOT find LibSoup: Found unsuitable version “”, but required
is at least “2.54.0” (found LIBSOUP_INCLUDE_DIRS-NOTFOUND)
CMake Error at Source/cmake/OptionsGTK.cmake:211 (message):
libsoup is required.
Call Stack (most recent call first):
Source/cmake/WebKitCommon.cmake:220 (include)
CMakeLists.txt:20 (include)

– Configuring incomplete, errors occurred!
See also “/mnt/e/cmllpz/LklWb/org/webkitgtk/releases/webkitgtk-2.36.3/CMakeFiles/CMakeOutput.log”.
$

so cmake is not even able to get the version number of an installed library while Debian’s apt-get tells you:

sudo apt-get install libsoup2.4-1 --assume-yes
Reading package lists…
Building dependency tree…
Reading state information…
libsoup2.4-1 is already the newest version (2.72.0-2).
libsoup2.4-1 set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 64 not upgraded.
$

On Linux, when you develop (or compile) something, you ALWAYS need the -dev package. You just installed the runtime package.

So install libsoup2.4-dev package or whatever it is named.

The needed information should be in e.g. a README file in the source. If the author does not provide that information, you have to take the long route. There’s nothing that CMake could shortcut.

I just gave you a concrete example of what I meant. I still think it would be helpful if cmake or any other compiling utility had that kind of “simulate” option listing all packages that it will need before going about the actual compilation, so that developers know all they need at once.

Let me look at an possible cases:

  • depending on one module not being found, another one could be used as a fallback. The first has OPTIONAL but the second doesn’t.The second is not required though if the first one is present.

  • packages can be dependent on system or compiler

  • packages can be dependent on variables

  • packages can be on found status of other packages

…or any combination.

@lbrtchx Please don’t attribute to CMake maybe wrong module implementation. Module libsoup (i.e. FindLibSoup.cmake) is not distributed as part of CMake. So address your complaints (i.e. no version detected) to the developer of this module.

Cmake projects often implement conditional logic, so that if one package cannot be found it will search for another or use some sort of fallback.

I think the kind of documentation of all packages you are looking for should be provided by the author of the project.

Let me look at an possible cases:

well yes, and at the end of day it will have to use a package if found, if not it will complain. That is all I am talking about. I would like for “all complaints” to be reported at once as part of a “simulate” kind of dry run.

So address your complaints (i.e. no version detected) to the developer of this module.

Once again, mine was just one example of the quirky cases one may run into. Yes, that -seems- to be a problem with the package itself and not cmake, but how could Linux Debian apt get the version of the package while cmake doesn’t?

This isn’t possible, because if the project contains some sort of logic that says “try to find package A, then if it can’t be found, then try to find package B”, then in a “dry run”, if package A is found then CMake would never look for package B. There’s no way for cmake to introspect all possible control paths the project’s scripts may take.

As far as apt – the apt database/repository tags uploads of the package itself with version information, but cmake does not have access to this information. Cmake relies on files within the package to tell cmake what the version is, and if it’s compatible with the version the cmake project requested. If the package you’re using doesn’t provide these files, there’s no way for cmake to fill in that missing information. This should be reported as a bug to the author of the package you’re trying to use.

This isn’t possible, because if the project contains some sort of logic that says “try to find package A, then if it can’t be found, then try to find package B”, then in a “dry run”, if package A is found then CMake would never look for package B

and that should be reported: “… package ‘A’, ‘B’, … not found; suitable package ‘D’ found”

why and how exactly is that “impossible”? I would like to hear such explanation especially coming from a computer programmer

There’s no way for cmake to introspect all possible control paths the project’s scripts may take.

nor should it, … then since package “D” found on step so und so, that would contextually constrain the DAG determining all possible search paths cmake would follow …

again, why and how exactly is that “impossible”?

As far as apt – the apt database/repository tags uploads of the package itself with version information, but cmake does not have access to this information.

cmake does detect the environment it is running on. If it knows it is doing an installation on, say, a Linux/Debian/bullseye baseline, I don’t find as irrational at all making use of apt database/repository tags for its own heuristics

This should be reported as a bug to the author of the package you’re trying to use.

which I did: (cmake) Could NOT find LibSoup: Found unsuitable version "" ...
but I am talking about an entirely programming aspect here.

CMake already does report information like this, I believe with the --debug-find option. From within CMake code, you can include the FeatureSummary module and call feature_summary to get a full detailed list of all packages that were found and which ones weren’t (though this only lists packages that were searched for in the current cmake run). If you’re creating a project yourself, you can just add a call to feature_summary at the end of your main CMakeLists.txt. If you’re building another project, you may have to insert this into their CMakeLists.txt if they don’t already have it.

I am not a CMake maintainer, but I am a programmer. I’m not saying it’s impossible to report what packages were not able to be found in the current run - that is absolutely possible, and already supported like I explained above. What is much more difficult is for CMake to report a full list of all packages a project might search for in any build configuration. Many projects have conditional dependencies on third party packages, use fallbacks if one can’t be found, etc, and CMake does not support introspecting project code to determine a full list of any packages a project might try to find. This is documentation that should be provided by the project author.

Two issues with this:

  1. It is not trivial to determine what package manager the user is using. Even just on Ubuntu, it could be apt or apt-get. But many packages are installed via pip. This quickly becomes a problem whose difficulty outweighs the benefits its implementation would provide, because:
  2. Some packages define different version handling logic for inclusion in CMake projects than simply their tagged version in a package manager. Some packages use different versioning systems altogether between their package manager releases and their actual code version. (I’m not saying this is a good practice, but it is a reality.) CMake thus requires a package version file to determine if a requested version is available and compatible, to provide a consistent interface for CMake to determine this information. When using find_package, you can omit a version requirement, to prevent cmake from caring if the package provides a version file or not.

There you have it! Why not exposing that internal feature a la: cmake --simulate --output-file: … ?

Because it requires the author to code it up? CMake can read find_package() calls, but it cannot know why it is being done. Is it for introspection? To use during configure? Is there a fallback? Is it a typo?

Without some more structured dependency information, CMake cannot do what you’re asking in any reliable way.

find_package(Foo)
if (NOT Foo_FOUND)
  find_package(Bar)
endif ()

What would you expect CMake to report here? Additionally, CMake has absolute zero idea about what “Foo” or “Bar” even mean. They could be apt install commands. Or pip-based. Or tarballs from some vendor that only gives out SDK tarballs after some clickthrough license terms. There’s just not enough information for CMake to give more than a “I dunno, try searching for the name of the package”-level guidance to more than some single-digit percentage of its target audience.

1 Like

What would you expect CMake to report here?

that package “Foo” was not found that the attempt has been made to find “Bar”.

Additionally, CMake has absolute zero idea about what “Foo” or “Bar” even mean.

Nor should it.

There’s just not enough information for CMake to give more than a “I dunno, try searching for the name of the package” …

and that is all that is needed for all packages which were not found at once instead of making its users having to deal with every point of resistance at a time …

relatively simple, python-based utilities such as yt-dl has “simulate” options, why exactly wouldn’t a compilation utility have it?

This is not possible in general. What should be done here?

find_package(SomeCMakeAPI REQUIRED) # Fails
use_cmake_api()

find_package(Other)

CMake cannot continue past the SomeCMakeAPI package request because the API it provides could do anything (including other find_package calls, so you’ll be missing your mark about “all at once”).

If you want this from projects, encourage them to restructure to look for everything up front, figure out what that means, then use FeatureSummary. Myself? I prefer to just find a package and error because considering “was this required dependency found or not?” everywhere after a find_package(REQUIRED) is just too complicated in general.

Because CMake is not yt-dl? That tool has a narrow set of constraints it is working within (namely detecting the format and metadata to actually download for a video). CMake is executing arbitrary Turing-complete code. There’s a world of difference here that is just not trivial.

1 Like