[Qbs] Interfacing Qbs to Conan

Jochen Ulrich jochen.ulrich at clausmark.com
Thu Feb 6 17:58:19 CET 2020

Hi Richard!

> I hope this gives you some ideas how to move forward

Thanks Richard! We really appreciate your help!

> There might be different solutions to this, but what I think would be simple and straight forward

Basically, we are doing it the way you described.
However, we decided not to make a conan module which the generated modules depend on because we expect that this would lead to multiple invokations of `conan install` (one for each generated module) which we want to avoid.
So we decided to have a project-level probe instead which detects the conan executable and the conanfile and runs `conan install`.
This way, one can also easily define the path to the conanfile inside the Qbs files.

> I would be more than happy to discuss any issues appearing on the way.

Yeah. While working on the Conan ModuleProvider, we encountered a few obstactles. Luckily, it seems we are able to work around them.
I list these obstacles here along with the workarounds we are currently implementing so we can discuss them.
I would then create a feature request ticket to extend the ModuleProvider accordingly.

So the following things might be helpful when writing a ModuleProvider:

1.) Access to (project-level) probes
It is quite likely that a ModuleProvider needs some external tools or files and those should be detected using probes.
In our case, we need to detect the conan executable and the conanfile(s).
Our workaround is to let the project-level probe execute `conan install` so the ModuleProvider does not need to know the location of the conan executable and the conanfile(s). This then produces a conanbuildinfo.json which the probe places in a defined location inside the build directory so that the ModuleProvider is able to find it.

2.) Access to the project the ModuleProvider is running in
A ModuleProvider might need or save some files in the buildDirectory. So access to the project.buildDirectory and project.sourceDirectory would be helpful.
In our case, we need to locate the conanbuildinfo.json in the buildDirectory. Enhancement 1.) might also solve this. However, in our project, we might end up with several conanbuildinfo.json files (hierarchy of projects) and therefore, access to project.name to differentiate the files might be helpful.
Our workaround to get the buildDirectory is to assume that the outputBaseDir of the ModuleProvider is inside the build directory. So we simply do something like `var buildDirectory = FileInfo.cleanPath( outputBaseDir + '/../..' )`.
For the multiple conanbuildinfo.json files issue, we simply take all of them inside a defined directory.

3.) Access to the full name of the Depends items for which the ModuleProvider was called
This works for the fallback ModuleProvider AFAIK. However, at the moment there can be only one fallback ModuleProvider AFAIK. So it would not be easily possible for a project to use both pkgConfig and Conan, right?
Allowing access to the full name of the Depends item in a regular ModuelProvider when evaluating the relativeSearchPaths property would allow writing something like `Depends { name: "conan.somePackage" }` which would invoke the conan ModuleProvider which would then generate the Module for "somePackage".
Our workaround is to generate Modules for all dependencies from the conanfile, no matter if they are used as Depends items in Qbs or not.
So this is not a real issue in our case but it limits ModuleProviders which do not have something like the conanfile but only rely on the name of the dependency.

4.) Mechanism to force execution of the ModuleProvider
Since ModuleProvider generate modules on a dynamic basis, it is not unlikely that the environment changes and the ModuleProvider needs to re-run. At the moment, this can be forced with the --force-probe-execution command line parameter. However, it would be nice if Qbs could detects this automatically. I'm not sure how this could be realized. Maybe a property on the ModuleProvider that, when it evaluates to `true`, forces re-execution of the ModuleProvider?
In our case, we would like to re-run the ModuleProvider when the conanfile (or conanbuildinfo.json) has changed.
Our workaround is that we have to call qbs with --force-probe-execution manually when the conanfile has changed.

So would those enhancements make sense?

Best regards

More information about the Qbs mailing list