[QBS] Qt Quick Compiler with QBS

Jicquel Dorian dorian.jicquel at mana-sys.fr
Thu Feb 26 14:45:29 CET 2015


Hi Joerg,

This works like a charm. Thanks a lot for this great work,  we add it as 
a module to our projects so that we only need to set a depends on this 
module.
We needed to modify your qbs for it to works.
At line 161 we wrote
FileInfo.path(info.qrcFilePath)+"/"+qmlJsFile.input,

If i can help, find enclosed our module.
To use it we only need to write
Depends{name:"quickCompiler"} and set qmlrc fileTags as you do on your 
sample.

Many thanks again


Olivier


> Hi Joerg,
>
> Thanks a lot for this work. We will test it as soon as possible dans 
> give you a feedback on it.
>
> BR
>
> Olivier
>
> Le 19/02/2015 12:52, Joerg Bornemann a écrit :
>> On 13-Feb-15 15:01, olivier musse wrote:
>>
>>> Thanks, it seems you know Qt Quick Compiler better than I  ;o)
>>> So when do you think the magic part can be added to QBS ?
>>
>> I've added an example to QBS-749 that demonstrates how to use the 
>> qmlcompiler with qbs 1.3. The magic is done in CompiledQmlApp.qbs. 
>> The actual app project looks like this
>>
>> ---snip---
>> import qbs
>>
>> CompiledQmlApp {
>>     name: "MyApp"
>>     files: ["main.cpp"]
>>     qmlResourceFiles: ["qml.qrc"]
>> }
>> ---snap---
>>
>> Build the project with qbs -f myapp.qbs and make sure that your Qt 
>> build has the QML compiler installed.
>>
>>
>>
>> BR,
>>
>> Joerg
>>
>
>
>
> _______________________________________________
> QBS mailing list
> QBS at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/qbs

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/qbs/attachments/20150226/6a37503c/attachment.html>
-------------- next part --------------
import qbs
import qbs.TextFile
import qbs.FileInfo
import qbs.Process

Module {
    name:"qqc"
    Depends { name: "Qt.quick" }
    Depends { name: "Qt.core-private" }
    Depends { name: "Qt.qml-private" }

    Rule {
        inputs: ["qmlrc"]
        Artifact {
            filePath: input.fileName + ".json"
            fileTags: ["qmlrcinfo"]
        }
        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "Starting quick compiler rule";
            cmd.sourceCode = function() {
                var content = {
                    qrcFilePath: input.filePath
                };

                function qtQuickResourceFileOutputName(fileName) {
                    return fileName.replace(/\.qrc/, "_qtquickcompiler.qrc");
                }

                function qtQuickCompilerOutputName(fileName) {
                    var str = fileName.replace('/', '_');
                    var i = str.lastIndexOf('.');
                    if (i != -1)
                        str = str.substr(0, i) + '_' + str.substr(i + 1);
                    str += ".cpp";
                    return str;
                }

                function scanQrc(input) {
                    var absInputDir = FileInfo.path(input.filePath);
                    var qmlJsFiles = [];
                    var otherFiles = [];
                    var process = new Process();
                    var exitCode = process.exec(
                                product.moduleProperty("Qt.core", "binPath") + '/rcc',
                                ["--list", input.filePath]);
                    if (exitCode !== 0)
                        throw Error("rcc failed with exit code " + exitCode);
                    for (;;) {
                        var line = process.readLine();
                        if (!line)
                            break;
                        line = line.trim();
                        line = FileInfo.relativePath(absInputDir, line);
                        if ((/\.(js|qml)$/).test(line))
                            qmlJsFiles.push(line);
                        else
                            otherFiles.push(line);
                    }
                    if (otherFiles.length) {
                        content.newQrcFilePath = qtQuickResourceFileOutputName(input.fileName)
                    }
                    content.qmlJsFiles = [];
                    qmlJsFiles.forEach(function (f) {
                        content.qmlJsFiles.push({
                                                    input: f,
                                                    output: qtQuickCompilerOutputName(f)
                                                });
                    });
                }

                scanQrc(input);

                var tf = new TextFile(output.filePath, TextFile.WriteOnly);
                tf.write(JSON.stringify(content));
                tf.close();
            }
            return cmd;
        }
    }

    Rule {
        inputs: ["qmlrcinfo"]
        outputFileTags: ["cpp", "qrc"]
        multiplex: true
        outputArtifacts: {
            var infos = [];
            inputs["qmlrcinfo"].forEach(function (input) {
                var tf = new TextFile(input.filePath, TextFile.ReadOnly);
                infos.push(JSON.parse(tf.readAll()));
                tf.close();
            });

            var result = [];
            infos.forEach(function (info) {
                if (info.newQrcFilePath) {
                    result.push({
                                    filePath: info.newQrcFilePath,
                                    fileTags: ["qrc"]
                                });
                }
                info.qmlJsFiles.forEach(function (qmlJsFile) {
                    result.push({
                                    filePath: qmlJsFile.output,
                                    fileTags: ["cpp"]
                                });
                });
            });
            result.push({
                            filePath: "qtquickcompiler_loader.cpp",
                            fileTags: ["cpp"]
                        });
            return result;
        }
        prepare: {
            var infos = [];
            inputs["qmlrcinfo"].forEach(function (input) {
                var tf = new TextFile(input.filePath, TextFile.ReadOnly);
                infos.push(JSON.parse(tf.readAll()));
                tf.close();
            });

            var cmds = [];
            var qmlCompiler = product.moduleProperty("Qt.core", "binPath") + "/qtquickcompiler";
            var cmd;
            var loaderFlags = [];

            function findOutput(filePath) {
                for (var k in outputs) {
                    for (var i in outputs[k]) {
                        if (outputs[k][i].filePath.endsWith(filePath))
                            return outputs[k][i];
                    }
                }
                return undefined;
            }

            infos.forEach(function (info) {
                if (info.newQrcFilePath) {
                    loaderFlags.push("--resource-file-mapping=" + info.qrcFilePath
                                     + "=" + info.newQrcFilePath);
                    cmd = new Command(qmlCompiler, ["--filter-resource-file",
                                                    info.qrcFilePath,
                                                    findOutput(info.newQrcFilePath).filePath]);
                    cmd.description = "generating " + info.newQrcFilePath;
                    cmds.push(cmd);
                } else {
                    loaderFlags.push("--resource-file-mapping=" + info.qrcFilePath);
                }
                info.qmlJsFiles.forEach(function (qmlJsFile) {
                    cmd = new Command(qmlCompiler, [
                                          "--resource=" + info.qrcFilePath,
                                          FileInfo.path(info.qrcFilePath)+"/"+qmlJsFile.input,
                                          findOutput(qmlJsFile.output).filePath]);
                    cmd.description = "generating " + qmlJsFile.output;
                    cmds.push(cmd);
                });
            });

            cmd = new Command(qmlCompiler, loaderFlags.concat(
                                  infos.map(function (info) { return info.qrcFilePath; }),
                                  findOutput("qtquickcompiler_loader.cpp").filePath
                                  ));
            cmd.description = "generating loader source";
            cmds.push(cmd);
            return cmds;
        }
    }

}


More information about the Qbs mailing list