Search code examples
c++qtvisual-studio-2015qt-resource

Force rcc-ing of qrc file on each build


How to force rcc-ing of a qrc file on each build in Visual Studio 2015? We are embedding the resources in the binary, so if something like qml or image assets change, we need to run rcc to get a fresh .cpp file for the current state. I see several options - brutally touching the .qrc file in a pre build event, running a script which checks everything in the asset folder before build and checking the timestamps and comparing them to a state at the previous build. Are there cleaner and more elegant options?


Solution

  • Since it was requested in the comments, I'm publishing the solution I came up with. So, in my case the qrc file is added to the Visual Studio solution, and has a proper Custom Build Tool set (but that is the common way and should be set up by the VS Qt plugin) like this:

    enter image description here

    All I had to do was to make a trivial C# program which reads the contents of the qrc and updates the modification timestamp of the qrc file, if any of the contained items was newer than the qrc itself. This is all it takes:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Xml.Linq;
    using System.Xml.Serialization;
    using System.IO;
    
    namespace QrcValidator
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length != 1)
                {
                    System.Console.WriteLine("usage: QrcValidator.exe <qrc file path>");
                    return;
                }
                Console.WriteLine(string.Format("Validating {0}", args[0]));
                XDocument qrcDocument = XDocument.Load(args[0]);
                var qrcFileLastWrtieTimeUtc = File.GetLastWriteTimeUtc(args[0]);
                foreach (var file in qrcDocument.Descendants("RCC").Descendants("qresource").Descendants("file"))
                {
                    if (File.GetLastWriteTimeUtc(file.Value) >= qrcFileLastWrtieTimeUtc)
                    {
                        Console.WriteLine("{0} is dirty, setting last write time of {1} to current UTC time", file.Value, args[0]);
                        File.SetLastWriteTimeUtc(args[0], DateTime.UtcNow);
                        Environment.Exit(0);
                    }
                }
            }
        }
    }
    

    This tool takes the qrc file as the first argument. So I just added calling this tool as a pre build event, and if any changes have happened to the resources, the qrc file is touched, and it's normal build command is invoked.