Visual Studio: preventing unecessary recompiles of static libs

Pages: 12
From what I see the lib doesn't get recompiled but relinked instead, following message:
LINK : C:\Users\MY_USERNAME\Desktop\Project-2\x64\Debug\Project-2.exe not found or not built by the last incremental link; performing full link


When you build in project-1 the linker complains because executable (*.exe file) of project-2 is not present in build directory of project-1

If you look into lib folder you'll see a file named "static-lib.lastbuildstate", the contents of this file specify last executable linked which is set to project that you last built.

since *.exe file does not exists but is specified in lasbuildstate file, MSBuild thinks it needs to relink because *.exe is not there.

It doesn't need to recompile because *.obj files (compiler output) exist so it skips that part.

Therefore project separation such the one you did will simply not work because there is no way for MSBuild to know you maintain 2 separate projects.
There is no way because MSBuild works per solution, however you have 2 solutions.

There are multiple workarounds however:
1. If you want to keep your unusual build setup, you'll need to edit "Build events -> Prebuild event" in project property page per configuration.
Into prebuild event insert command that will copy other project build output into this project build output.

2. Same but more elegant option is to keep those 2 projects in separate folders like it's now, however add project-1 to solution 2, and add project-2 to solution1.
This way both solutions have both projects but in separate folders, static lib won't be rebuilt unless modified

3. Third option is to link explicitly as already explained before, this is normal way of doing it for 3rd party libraries or libraries which you don't modify often.

4. Another option is to open configuration manager and disable building LIB project, it should work as long as you don't touch (ex. clean) *.LIB file, I never tried this but if that doesn't work then explicit linking is needed.

5. The best option is the one where you keep all your projects and libraries in one root folder where only one build directory is present, that way MSBuild is aware of everything.
In such a setup you can maintain multiple solutions as you wish, or even better solution filters.
Solution filters are special kind of solutions with *.slnf extension, for more info see here:
https://docs.microsoft.com/en-us/visualstudio/ide/filtered-solutions?view=vs-2019

In any case, your current build setup is very unusual and will not work as you want.
Last edited on
I think I'm seeing something very different. For a start, these are the default projects that MSVC produces. All I did was to use the wizard to create 3 empty projects: two applications and one static library.

Secondly, I have no dependencies between project 1 and project 2. They are both dependent on the library but not on each other.

Thirdly, the lib.cpp is being recompiled (see below). I added a single line in f() in lib.cpp: "float x = 1.2;" which causes a compiler warning so I can see when a compile happens. (Somewhat surprisingly MSVC just lists the source file in the log and doesn't actually say a compile is happening.)

After building project 1, then project 2, the output when building project 1 for a 2nd time is:



Build started...
1>------ Build started: Project: static-lib, Configuration: Debug x64 ------
1>lib.cpp
1>C:\...\MSVC-rebuild-issue\static-lib\lib.cpp(4,16): warning C4305: 'initializing': truncation from 'double' to 'float'
1>static-lib.vcxproj -> C:\...\MSVC-rebuild-issue\Project-1\x64\Debug\static-lib.lib
1>Done building project "static-lib.vcxproj".
2>------ Build started: Project: Project-1, Configuration: Debug x64 ------
2>Project-1.vcxproj -> C:\...\MSVC-rebuild-issue\Project-1\x64\Debug\Project-1.exe
========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========


From the verbose log:


1> All outputs are up-to-date.
1> All source files are not up-to-date: command line has changed since the last build.



2>------ Up-To-Date check: Project: Project-1, Configuration: Debug x64 ------
2>Project is not up-to-date: build input 'c:\...\msvc-rebuild-issue\project-1\x64\debug\static-lib.lib' was modified after the last build finished.
2>------ Build started: Project: Project-1, Configuration: Debug x64 ------

Last edited on
Rob190,
I'm afraid you overlooked or did not understand my previous post...

All I did was to use the wizard to create 3 empty projects: two applications and one static library.

No friend, what you really did is create 3 independent solutions (each for one project), and now wonder why they don't work as if inside single solution.

What you expect will work only if all projects are within same solution.

The behavior that you want achieve is not possible because that applies only if all projects are within same solution, but you broke into 3 independent pieces.

As you can see there are 2 ways to add\create new projects:
1. File -> new -> project (creates new solution)
2. Right click existing solution -> add -> new project (uses existing solution)

HINT:
To avoid such problems in the future, add new project to same solution by right click on solution in VS and add new project (option 2 above), you don't create new solution for each new project.

Secondly, I have no dependencies between project 1 and project 2

No you don't but both projects have dependency on same LIB project, what happens is that now each project modifies the lastbuildstate file of the LIB project which by design triggers build for the LIB project because last build was not initiated by the same project.

Thirdly, the lib.cpp is being recompiled

Ah yes, I overlooked this, the LIB indeeds get rebuilt (compile + link),
however this does not change anything said so far.

Your build setup will not work and there is no answer to your question because that's not how things work in VS.

To fix this problem, you have only 2 options:
1. Explicit linking (allows you to have projects in it's own solutions)
2. Put all projects into same solution and VS will build the LIB just once (until modified)

Hint:
Option 1 is used when dealing with 3rd party libs.
Option 2 is used when you develop your own library.

If you really want to have projects in separate directory, no problem, Option 2 can handle that, but it's recommended to have project files within same solution folder.

EDIT:
For your convinience here is sample solution made of your projects, this is how you setup build system when developing your own library (this is option 2 discussed before)

https://1drv.ms/u/s!AhDrKQrnMQzuhAqPEBTvouNWj1Ak?e=yhyLcX
Last edited on

Secondly, I have no dependencies between project 1 and project 2

No you don't but both projects have dependency on same LIB project, what happens is that now each project modifies the lastbuildstate file of the LIB project which by design triggers build for the LIB project because last build was not initiated by the same project.


Oh good grief they're using a log file to track dependencies. AND they're including non-dependent info (from the parent project) in it. Sorry for taking so much of your time. I really had been assuming MS was doing something reasonable here.

I don't suppose there's a way to disable the use of the lastbuildstate file is there? I did a quick search and found a few discussions relating to problems with the .tlog and lastbuildstate files.

I did originally link the libraries explicitly. The problem I had was that sometimes they were not being rebuilt, leading to data corruption which was very difficult to debug. I have a number of layered libraries so I need to be absolutely sure the dependency tracking works. Actually I've noticed the 'preview' versions don't always get this right and I've had a few bugs disappear after a 'rebuild-all' recently. Anyway, I'll try adding the libraries explicitly and see what happens.

I'm not keen on putting everything in one solution. Too many projects and some need quite a bit of updating before they'll work with VS2019/2022.

For now, I've just checked out the projects into different workspaces and (hard) linked directories that need to share data. That might end up being a better way of working. Not sure yet.

Thanks so much for your time and help. Much appreciated.

Rob.
You're welcome.

I'm not keen on putting everything in one solution.

Of course, that's why we use solution filters.

You can have one master solution with all the projects and multiple solution filters to focus on specifics as needed. (see link I gave you before)

You can switch between solution filters without closing and reopening any solutions.

You Separate projects into their own solutions when there is nothing in common between them, which is where you make a mistake.

There can't be too many projects in one solution, the days of slow solution issues are long gone.

For example my solution on which I'm working contains 43 projects and I face no issues or performance problems.
I also have 6 solution filters and it everything works just fine and fast.
Last edited on
Registered users can post here. Sign in or register to post.
Pages: 12