[QBS] A Rule with more than one Artifact?

William Gallafent william at gallaf.net
Mon Sep 10 19:03:29 CEST 2012

Hi All,

I'm trying to work out how to achieve the following.

I have a custom tool which takes one (text) file as input and
generates two files (a cpp and an hpp) as output. I use the cpp and
the hpp to generate a DynamicLibrary (so far so good, but only by
coincidence! The DynamicLibrary depends explicitly on the cpp, it's
just "luck" that the hpp has been created at the same time).

I then need to use the hpp in the compilation phase of a dependent
project, which subsequently links against the library! At the moment I
use a Product that looks like this to generate the DynamicLibrary.
There's a custom rule that indicates that the .cpp files depend on the
input and provides a command which performs the action to create them,
but I can't see a way to indicate that the .hpp is created /in the
same step/ as the .cpp is created.

My question is: how do I express the custom Rule that generates /two/
files from /one/ input file?

The /true/ dependencies goes something like this (a slightly confusing
way to think about it, but anyway):

(a.cpp, a.hpp): a.txt
foo.dylib: (a.cpp, a.hpp)
b.exe: (a.hpp, foo.dylib)

So far I've only managed to express using qbs the following though:

a.cpp: a.txt
foo.dylib: a.cpp
b.exe: foo.dylib

What I'm unable to do so far is to indicate that the .hpp is created
/at the same time/ as the cpp - I naively tried adding a second
Artifact but this of course didn't work. This means that other
products that need the hpp to exist before building do not realise
that these output files need to be created first, because the .hpp
files do not get entered into the tree anywhere!

I could probably make a sort of "sequence point" which prevents the
dependent project from /starting/ to build until the DynamicLibrary
build is /complete/, but that wouldn't be so efficient; I'd prefer to
express the genuine dependencies correctly!

Here's (a simplified version of) the Product as it stands at the moment:

DynamicLibrary {
  name: "foolib"
  Group {
    files: ["a.txt"]
    fileTags: ["sampleinput"]
  Depends {name: "cpp"}
  Rule {
    inputs: ["sampleinput"]
    Artifact {
      fileTags: ["cpp"]
      fileName: FileInfo.baseName (input. fileName) + ".cpp"
    // ToDo: How to have a rule that generates two artifacts from one input?
    // Artifact {
    //   fileTags: ["cpp"]
    //   fileName: FileInfo.baseName (input. fileName) + ".Hpp"
    //   }
    prepare: {
      var args = [input.fileName, output.fileName]
      var cmd = new Command ("bin/txt2cpp.rb", args);
      cmd. description = "Generating C++ for " + input. fileName + "
to create " + output. fileName;
      cmd. highlight = "codegen"
      return cmd;

Apologies for wrong use of terminology and otherwise confusing
narrative, I'm new to qbs (but like it a lot already!) All help


Bill Gallafent.

More information about the Qbs mailing list