Force rcc-ing of qrc file on each build - c++

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?

If you were to use CMake, you could add a pre-build task to delete the your-project-name_autogen folder from the build directory. This forces CMake to rcc the qrc file each build.
The command might look something like:
add_custom_command (TARGET your-project-name PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/your-project-name_autogen)
CMake does this by adding a Pre-Build Event to its generated Visual Studio project, so you can also replicate it with only Visual Studio. If you haven't found the pre-build event section already, right-click on the desired project (not solution), and select Properties. Under Build Events, there should be a section called Pre-Build Events. A command like del your-files would probably suffice.
The answer linked below gave some other decent options.
How to delete files in Visual Studio Pre-build event command line
The CMake command was the solution to my issues with a Qt qrc file containing QML resources.

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:
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.

Related

How to generate the respective protobuf files in Visual Studio during the compilation process automatically?

I have several protobuf messages in a folder which I'd like to automatically convert into the respective header/cc files and then continue the compilation process inside of Visual Studio.
The best solution that I could comeup sofar was to define a Pre-Build Event through Propertise>Build Events>Pre-Build Event and specifying the following as the command:
$(SolutionDir)Dependencies\include\protobuf\bin\protoc.exe --proto_path=$(SolutionDir)Dependencies\include\messages\ --cpp_out=$(SolutionDir)Dependencies\include\messages\ message.proto message2.proto message3.proto
There are currently 2 issues concerning this solution :
I have to manually add each filename myself. How is it possible to make the filenames get picked automatically by VS2019? I tried %filename% macro, to no avail since it seems it returns the project file names only.
I also found out, these files are not generated each time I change the messages. even cleaning the projects, doesn't delete them, so I have to manually delete the generated files and try rebuilding the project again!
Other than resorting to a batchfile that can get called as a prebuild event, how can I achieve this inside Visual Studio without doing that?
I suggest you could refer to the following steps:
1,Modify the properties of the .proto file:Item Type:Custom Build Tool
2,Configure project properties: Properties -> Custom Build Tools -> General
command line:$(SolutionDir)Dependencies\include\protobuf\bin\protoc.exe --proto_path= .\proto %(Filename).proto --cpp_out=$(ProjectDir)protocpp
Description: protoc %(Filename).proto
Outputs: $(ProjectDir)protocpp%(Filename).pb.cc
Add Outputs to Item Type: c/c++ complier
And then you could try to build the .proto file.
Note: The newly added the .proto file also needs to select the operation of the Custom Build Tool

VS code: Useless file keep appearing

Visual Studio Code 1.46.1
Operating system: MacOS 10.15.4 (Catalina)
VS Code Package used: C/C++, Code Runner
Problem: When I run a C++ code using Code Runner, a file with no extension automatically appear.
I would like to know what does this 'useless file' do, and how to make these files stop from spawning.
That is the executable file also called binary file. They are the executable like .exe in windows so it is very useful(as it is the output of source code). If you dont want to see that file in sidebar of vscode then there is a good answer to this question. Alternatively you can configure your build configuration file (located at .vscode in you working directory) and set the build path to somewhere else
You are using Code Runner extension on vscode then you can modify the execution command.
Go to Code-runner: Executor Map Setting
I did this:
"code-runner.executorMap": {
...
"c": "cd $dir && gcc $fileName -o ./temp/$fileNameWithoutExt && $dir./temp/$fileNameWithoutExt",
...
}
create a temp folder.
Now your temp folder will contain those unwanted files.
You can modify execution command like this for c++ also.

Visual Studio 2019 always rebuilds everything after I hit the "build" button

I'm new to Visual Studio. Now I'm using Visual Studio 2019 to develop Clang&LLVM. I found that every time I right-click the clang executable in the Solution Explorer and choose "Build" or "Debug->Start new instance", VS starts to re-build everything from scratch, although I haven't changed any source file. Since LLVM is a giant project, this recompilation takes too long.
Is there any solution to make VS smarter to only recompile necessary files (files got changes and their dependencies)?
This could happen if there is a file with "copy always" ("copy to output directory" option)
Fix: Change it to "copy if newer"
You could find these easily by checking the (.vcxproj) project file in a text editor. (search for <CopyToOutputDirectory>, possible values: Never, Always, PreserveNewest. See msbuild-docs)
In my case this problem occur in one specific situation, when project is compile with flag /MP and have "precompiled header".
In above case while compiling your app the file "Microsoft.Build.CPPTasks.CL.read.1.tlog" is created and unfortunately contains paths to temporary files e.g
"\?\C:_Sources\MyApp\OBJ\DEBUG\X64\MyApp\stdafxD-8811C005.PCH.TMP
\?\C:_Sources\MyApp\OBJ\DEBUG\X64\MyApp\PCH-92DA10DF.OBJ.TMP"
When you run compilation again every entries from the file is checked for any changes, since we have entry points to not existing file, the compiler have to compile it again, we can see the "missing" file is a precompiled header, so the entire application must be recompiled
For now I found 3 solutions for this problem:
Do not use flag /MP
Use other build system like ninja, fastbuild, etc.
Write simple app to remove temporary entries from all *.tlog files
and run it before every build
Sample code in c# for solution 3.
static void Main(string[] args)
{
string sobjPath = #"C:\_Sources\MyApp\Obj";
string[] allfiles = Directory.GetFiles(sobjPath, "*.tlog", SearchOption.AllDirectories);
foreach(string filePath in allfiles)
{
List<string> lines = File.ReadAllLines(filePath).ToList();
var linesCount = lines.Count;
lines.RemoveAll(x => x.StartsWith(#"\\?") && x.EndsWith(#".TMP"));
if(linesCount != lines.Count)
{
File.WriteAllLines(filePath, lines);
}
}
}
Source of recompilation can be found in output if diagnostic is set to Tools->Options->Projects and Solutions->Build and Run->MSBuild project build output verbosity = Diagnostic.
In my case it was because they were first builds after installation of new computer. I checked out files from svn but later I changed computer date and time because it was incorrect. After change all previously checked files has date in future so recompilation occurred. To solve issue I deleted all sources and checked out again from svn.

How can I make sure that a file is compiled on every build n msvc? [duplicate]

In one cpp-file I use the __DATE__ macro to get the compile-date.
It gives me the date of the last compile of that file. But as the file is not changed very often, the date is old in most cases, sometimes several months.
What I actually want is the date of the last build of the project.
Is there an setting to force VS2010 to rebuild that single cpp-file on every compile of the project?
Regardless of changes in the file?
The only way I found until now is to modify the file or delete the created obj-file by an script before the build, I would prefer an solution inside VS if that is possible.
You could probably add a Pre-Build Step that touch (see this thread) the file?
To add a Pre-Build Step, open your Project Properties, then Configuration Properties > Build Events > Pre-Build Event then add the command line you want to have executed in Command Line.
Following the suggestion from Amitd, apparently you can also touch the file using PowerShell, see this for explanations.
As suggested by Adrian McCarthy in the comments below, deleting the .obj file would be preferable in the context where source control is used and you want to keep the .cpp read-only. Using the "macros" exposed by Visual Studio, deleting them can be made easy:
del $(TargetDir)sourcefile.obj
Quoted from Cheers and hth. - Alf as another way to achieve this
nmake (bundled with Visual Studio and the SDK) option /t does a touch, it was once the conventional way to do this for Windows programmers.
You can add the following pre-build step, were you simply touch the date stamp of the file. The +,, is a special flag to the copy command, telling it to update the timestamp of the file:
copy file.cpp +,,
As suggested by Adrian McCarthy, you can simply delete the object file every time you build the project.
Therefore, create a pre-build event invoking the del command. According to Microsoft, you can use the $(IntDir) macro to refer to the directory wher the object file is stored (you should not use the $(TargetDir) macro).
I had issues with the return code of the command (error MSB3073), therefore I changed the command to always exit with 0.
del $(IntDir)datefile.obj & exit 0
Create this build event in the project configuration, under Configuration Properties / Build Events.

Microsoft Visual Studio: Loading resources in Qt application (without plug-in)

We don't have a Qt plug-in installed for MSVS, and it makes me wonder how/whether it is possible to load resources (images, etc) to the application.
Yes, you can load ressources.
Unfortunately, the qrc Editor which create qrc files is part of the Qt Addin for VS...
But you can create this xml file by hands, for the format see here
Once the qrc file created, you have at least two possibilities :
A) Use qmake
Add a reference to your qrc file in your pro file :
RESOURCES = ApplicationResources.qrc
Regenerate your vcproj from your pro by using qmake
qmake -tp vc
B) If you don't generate your vcproj file from your pro file, you can :
Add manually your qrc file in your solution, for example in the following path :
Resource Files/Res/ApplicationResources.qrc
Add the following commands in the properties of the qrc file in visual studio :
command line : $(QTDIR)\bin\rcc.exe -name ApplicationResources res\ ApplicationResources.qrc -o $(IntDir)\qrc__ ApplicationResources.cpp
Description : RCC res/ApplicationResources.qrc
Output : $(IntDir)\qrc__ ApplicationResources.cpp
C) You can also use an external binary resources file
The command line :rcc -binary myresource.qrc -o myresource.rcc
In the application, you have to register the resource file :
QResource::registerResource("/path/to/myresource.rcc");
For using resource file in the source code see the doc
However, like cheez, I also suggest using qmake and pro file and do not edit properties by hand in Visual Studio...
Hope this helps !
Use the qrc executable to generate a cpp file which you can include in your project:
/usr/local/Trolltech/Qt-4.5.1/bin/rcc -name core core/core.qrc -o build/release/core/qrc_core.cc
See http://doc.trolltech.com/4.0/resources.html
However, I strongly suggest using qmake or some other build system to automate this for you.