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

Rob190 41 Reputation points
2021-08-31T11:54:19.037+00:00

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++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,597 questions
{count} votes

Accepted answer
  1. RLWA32 41,996 Reputation points
    2021-09-01T21:01:40.613+00:00

    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.


1 additional answer

Sort by: Most helpful
  1. Sam of Simple Samples 5,516 Reputation points
    2021-08-31T19:30:53.88+00:00

    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.