[QBS] RFC pkgconfig support

Ruslan Nigmatullin EuroElessar at qutim.org
Thu Feb 23 17:19:08 CET 2012

23.02.2012, 21:38, "Joerg Bornemann" <joerg.bornemann at nokia.com>:
> On 23/02/2012 13:09, ext marius.storm-olsen at nokia.com wrote:
>>  The qbs user shouldn't have to think about a module being local or not.
>>  Changing a project from using a system libpng to a local/specialized
>>  version, should simply be to drop in a libpng project with its own .qbs
>>  file somewhere in the project hierarchy. No modifications to the other
>>  project should be needed.
> Allright. The user writes Depends { name: "foo" } into his project.
> The module "foo" cannot be found in any search path.
> Now we're asking all registered "module factories" to look for the "foo"
> module. The pkg-config module factory calls 'pkg-config --exists foo' to
> determine if it should generate a module or not.
> Then it dynamically generates the module "foo".
> So far so good. How could it look like?
> What about rules that can be part of a module?
> Do we want to be able to generate those dynamically as well?

May be we should use more declarative way? So the rules won't be a problem anyway

ModuleFactory {
	name: 'pkgconfig'
	property var binary: 'pkg-config'

	Component {
		name: "pkgconfigModule"
		Module {
			property string packageName
			Depends { name: "cpp" }
			function packageProperty (property) {
				var p = new Process();
				p.start(binary, [ '--cflags', packageName ]
				return p.readAll();
			cpp.cflags: packageProperty("--cflags");
			cpp.libs: packageProperty("--libs");

	createModule: {
		// Script that gets a module name.
		// The script creates module object on success,
		// returns undefined otherwise.

		var p = new Process();
		var packageName = convertToPackage(moduleName);
		if (p.start(binary, ['--exists', packageName]) != 0)
		return undefined;

		return pkgconfigModule.create({ "name": moduleName, "packageName": packageName });

> What happens if more than one module factory can generate a module
> "foo"? Who wins? Do we add dependencies between module factories or
> priorities?

Because all factories should provide similar module's data (If we want to build with system library usually there exists only one system library), simple priorities should be enough.
But what will be unique names for this modules? As it was said above pkgconfig's packages' names are not the same as qbs' one. The same situation will be possibly presented for any other tools and archives, like ruby's gems. So there should be presented some converter for them. 

More interesting is the situation when interested library is not found at all. Would be there any way to write workarounds around it if user wants to make application still be possible to build?

Depends { name: "gstreamer"; relaxed: true }
Group {
	condition: gstreamer.found
	files: [ "gstreamerbasedimpl.h", "gstreamerbasedimpl.cpp" ]
	cpp.defines: [ "HAVE_GSTREAMER" ]

Or even add to build new products (i.e. plugins) only in case if library is installed in system

More information about the Qbs mailing list