question

RobertSimpson avatar image
0 Votes"
RobertSimpson asked RobertSimpson edited

How to prevent unnecessary recompilation of C++ static libraries?

MSVC Version 16.11.0 Preview 4.0, Windows 10.

I have two MSVC C++ solutions which share a number of static libraries. When I switch from one solution to the other and try to run the app, MSVC always recompiles the static libraries. To try to stop this, I recreated the solution file for one of the apps, copied it to the 2nd app and manually edited the solution name. Both apps run fine but MSVC thinks the libraries are out of date and always recompiles them.

I have been assuming the vcxproj files for the static libs can't be causing this because there is only one for each static lib and they all live in the library directory which is separate from the app directories.

Is there a way to find out why MSVC thinks a recompile is necessary? Or is there some feature of MSVC which requires a recompilation? I'm thinking if there is some sort of global optimization, it may always want to recompile everything. But this problem occurs even with the debug build.

c++
· 16
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


According to some articles (https://www.bing.com/search?q=visual+studio+detect+the+cause+of+rebuild), try changing a settings in Options dialog, Projects and Solutions, Build And Run, two “MS Build…” lists, set to “Diagnostic”.

Build the solution, then search the logs (in Output window) for “not up to date” message, or maybe for other relevant details.


0 Votes 0 ·

It's reporting a lot of projects not up-to-date e.g.

 1>Project is not up-to-date: project file or some of its imports were modified.
 2>Project is not up-to-date: project file or some of its imports were modified.
 3>Project is not up-to-date: project file or some of its imports were modified.
 4>Project is not up-to-date: project file or some of its imports were modified.
 5>Project is not up-to-date: project file or some of its imports were modified.
 6>Project is not up-to-date: project file or some of its imports were modified.
 7>Project is not up-to-date: project file or some of its imports were modified.
 7>    All source files are not up-to-date:  command line has changed since the last build.
 8>Project is not up-to-date: project file or some of its imports were modified.
 8>    All source files are not up-to-date:  command line has changed since the last build.

Some of the projects are not being recompiled even though they are in the build dependencies AND in the references. They're all 3rd party libraries though e.g.


 1>------ Up-To-Date check: Project: ..\..\..\..\..\wxWidgets-3\build\msw\wx_base.vcxproj, Configuration: Debug x64 ------
 1>Project is not up-to-date: project file or some of its imports were modified.



0 Votes 0 ·

When switching from one solution to another that uses the static libraries and pressing F5 to run the application does visual studio rebuild the application after the static libraries appear to be rebuilt?

0 Votes 0 ·

No, the app isn't rebuilt. Only the libraries.

0 Votes 0 ·

@RobertSimpson I created two solutions which share the same static libraries but the problem didn't happen. It is difficult to reproduce the problem. Can you provide a sample?

0 Votes 0 ·

In the two solutions whose projects consume the output of the static library projects are the static library projects identified as dependencies through references or manually setting project dependencies?

0 Votes 0 ·

The libraries are listed both in the references and in Build depencencies -> Project dependences. I have not added any dependencies in manually.

Interestingly, I just disovered one of the libraries was missing in the both the above (because I'd re-created the project file but forgotten to add it back into the dependencies) but it was still being rebuilt . I really don't understand why.

0 Votes 0 ·

If only the library is specified in a project then I don't understand how it is able to even find the source files to do a build.

0 Votes 0 ·
Show more comments

I tried a very simple example and it doesn't show the problem. I have a lot of different apps that use various combinations of the libraries but some need updating before they will compile. Anyway, I might be able to find a small example or maybe find a pattern.

0 Votes 0 ·

Ok now have a simple example that shows the issue. Switching from 'Project-1' to 'Project-2' and vice versa causes the lib.cpp source file to be recompiled.

https://1drv.ms/u/s!Aq_J7sG5MG9jyXjGfE2F9sKcKeaE?e=QtW9YD

0 Votes 0 ·
Show more comments
RLWA32-6355 avatar image
0 Votes"
RLWA32-6355 answered RLWA32-6355 commented

If only the static libraries appear to be rebuilt but the app that consumes them is not then I think that what you are seeing is the Visual Studio build process providing status information about the static library projects even though they are not actually being rebuilt.

First, set the Visual Studio IDE Tools->Options->Projects->Projects and Solutions->Build and Run as follows -

128288-buildandrun.png

In my test I created two solutions each of which consumed the same two static library projects. Each solution was built and then closed. The I opened each solution and used F5. For the first solution this is what the Build Output showed -

 Build started...
 1>------ Build started: Project: StaticA, Configuration: Debug Win32 ------
 2>------ Build started: Project: StaticB, Configuration: Debug Win32 ------
 1>Build started 9/1/2021 4:43:01 PM.
 2>Build started 9/1/2021 4:43:01 PM.
 2>Target InitializeBuildStatus:
 2>  Creating "Debug\StaticB.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
 2>Target ClCompile:
 2>  All outputs are up-to-date.
 2>  All outputs are up-to-date.
 1>Target InitializeBuildStatus:
 1>  Creating "Debug\StaticA.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
 1>Target ClCompile:
 1>  All outputs are up-to-date.
 1>  All outputs are up-to-date.
 1>Target Lib:
 1>  All outputs are up-to-date.
 1>  StaticA.vcxproj -> C:\Users\RLWA32\source\repos\Rlwa32\StaticA\StaticA\Debug\StaticA.lib
 1>Target FinalizeBuildStatus:
 1>  Deleting file "Debug\StaticA.tlog\unsuccessfulbuild".
 1>  Touching "Debug\StaticA.tlog\StaticA.lastbuildstate".
 1>
 1>Build succeeded.
 1>    0 Warning(s)
 1>    0 Error(s)
 1>
 1>Time Elapsed 00:00:00.08
 2>Target Lib:
 2>  All outputs are up-to-date.
 2>  StaticB.vcxproj -> C:\Users\RLWA32\source\repos\Rlwa32\StaticB\StaticB\Debug\StaticB.lib
 2>Target FinalizeBuildStatus:
 2>  Deleting file "Debug\StaticB.tlog\unsuccessfulbuild".
 2>  Touching "Debug\StaticB.tlog\StaticB.lastbuildstate".
 2>
 2>Build succeeded.
 2>    0 Warning(s)
 2>    0 Error(s)
 2>
 2>Time Elapsed 00:00:00.07
 ========== Build: 2 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

Note that neither static library was actually rebuilt and the application that consumed them shows as up-to-date. I closed that solution, opened the second solution and pressed F5 to run. Build output was

 Build started...
 1>------ Build started: Project: StaticA, Configuration: Debug Win32 ------
 1>Build started 9/1/2021 4:44:07 PM.
 1>Target InitializeBuildStatus:
 1>  Creating "Debug\StaticA.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
 1>Target ClCompile:
 1>  All outputs are up-to-date.
 1>  All outputs are up-to-date.
 1>Target Lib:
 1>  All outputs are up-to-date.
 1>  StaticA.vcxproj -> C:\Users\RLWA32\source\repos\Rlwa32\StaticA\StaticA\Debug\StaticA.lib
 1>Target FinalizeBuildStatus:
 1>  Deleting file "Debug\StaticA.tlog\unsuccessfulbuild".
 1>  Touching "Debug\StaticA.tlog\StaticA.lastbuildstate".
 1>
 1>Build succeeded.
 1>    0 Warning(s)
 1>    0 Error(s)
 1>
 1>Time Elapsed 00:00:00.03
 2>------ Build started: Project: StaticB, Configuration: Debug Win32 ------
 2>Build started 9/1/2021 4:44:07 PM.
 2>Target InitializeBuildStatus:
 2>  Creating "Debug\StaticB.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
 2>Target ClCompile:
 2>  All outputs are up-to-date.
 2>  All outputs are up-to-date.
 2>Target Lib:
 2>  All outputs are up-to-date.
 2>  StaticB.vcxproj -> C:\Users\RLWA32\source\repos\Rlwa32\StaticB\StaticB\Debug\StaticB.lib
 2>Target FinalizeBuildStatus:
 2>  Deleting file "Debug\StaticB.tlog\unsuccessfulbuild".
 2>  Touching "Debug\StaticB.tlog\StaticB.lastbuildstate".
 2>
 2>Build succeeded.
 2>    0 Warning(s)
 2>    0 Error(s)
 2>
 2>Time Elapsed 00:00:00.04
 ========== Build: 2 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

Again, the static libraries were not actually rebuilt and the consuming app was shown as up-to-date.

If you can reproduce these results then the static libraries are not rebuilt and Visual Studio's Minimal build progress reporting was misleading you.




buildandrun.png (20.9 KiB)
· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

This is the start of the output where it is looking at the wxWidgets libraries (which are also included as projects in exactly the same way as the other libraries):

 Build started...
 1>------ Up-To-Date check: Project: ..\..\..\..\..\wxWidgets-3\build\msw\wx_base.vcxproj, Configuration: Debug x64 ------
 1>Project is not up-to-date: project file or some of its imports were modified.
 1>------ Build started: Project: base, Configuration: Debug x64 ------
 2>------ Up-To-Date check: Project: ..\..\..\..\..\wxWidgets-3\build\msw\wx_core.vcxproj, Configuration: Debug x64 ------
 2>Project is not up-to-date: project file or some of its imports were modified.
 2>------ Build started: Project: core, Configuration: Debug x64 ------

It is incorrectly reporting the project is no up-to-date but it doesn't seem to matter in this case as it doesn't compile the library. So something is already wrong here but the symptoms are different.

For the libraries that are being recompiled, it is definitely recompiling them e.g.

 14>    text-buffer.cpp
 14>    C:\xxxxx\xxxxx\xxxxx\lib\stream\text-buffer.cpp(283,50): warning C4244: 'argument': conversion from '__int64' to 'int', possible loss of data
 14>    C:\xxxxx\xxxxx\xxxxx\lib\stream\text-buffer.cpp(297,49): warning C4244: 'argument': conversion from '__int64' to 'int', possible loss of data
 14>    Generating Code...



1 Vote 1 ·

As was previously suggested by @Viorel-1 use the diagnostic reporting to determine which project items visual studio believes are out of date and cause the rebuild. Once you have identified the items you may be able to determine the reason why visual studio acts as it does. Since I cannot reproduce the specifics of your situation I'm afraid that's the best advice I can give you.

0 Votes 0 ·

Right. So I have the (verbose) log file. I can see VS is rebuilding projects because it claims they are out-of-date. I'm unsure how to proceed. What exactly is VS looking at to determine the 'out-of-date' status? The timestamps look ok but maybe I'm looking at the wrong thing?


 >Project is not up-to-date: build input 'c:\xxxx\xxxxx\xxxx\xxxxx\project-name\x64\debug\mylib-wx-vc16.lib' was modified after the last build finished.

To determine the 'after' condition, there must be two timestamps it's comparing. What are these exactly?


0 Votes 0 ·
Show more comments
SimpleSamples avatar image
0 Votes"
SimpleSamples answered RobertSimpson commented

I assume you are adding the source files for the static libraries to every project. Instead, have one project (or separate projects) for the static libraries and for all projects that user the libraries add just the lib file as a linker input.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

No I'm not adding the lib source files to every project. They are only part of the library project they belong to. The libraries are included via 'references' in the IDE. I used to include them manually and it worked fine but I found it much easier to include them via the IDE. (I also have the same apps in makefiles for gcc so I understand what you are saying. I just prefer to either use an IDE or go straight to makefiles rather than having some combination.)

0 Votes 0 ·