Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msbuild does not build precompiled header before building source file if UseMultiToolTask=true and path to the pch.h is relative #11403

Open
autoantwort opened this issue Feb 10, 2025 · 11 comments
Labels

Comments

@autoantwort
Copy link

Issue Description

I have the following project:

pch.h
pch.cpp
test/in-sub-folder.cpp 
Directory.Build.props

The content of the Directory.Build.props is

<Project>
  <PropertyGroup>
    <UseMultiToolTask>true</UseMultiToolTask>            
  </PropertyGroup>
</Project>

and the test/in-sub-folder.cpp file has a #include "../pch.h"

If I try to compile the project I get

03:08:37:193	Rebuild started at 03:08...
03:08:37:252	1>------ Rebuild All started: Project: TestCcache2, Configuration: Debug x64 ------
03:08:37:383	1>in-sub-folder.cpp
03:08:37:433	1>pch.cpp
03:08:37:433	1>F:\git_projects\TestCcache2\test\in-sub-folder.cpp(1,10): error C1083: Cannot open precompiled header file: 'TestCcache2\x64\Debug\TestCcache2.pch': No such file or directory
03:08:38:000	1>Done building project "TestCcache2.vcxproj" -- FAILED.
03:08:38:007	========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
03:08:38:007	========== Rebuild completed at 03:08 and took 00,849 seconds ==========

Steps to Reproduce

You can find an example project here: https://github.com/autoantwort/msbuild-bug-repro

Expected Behavior

The file in the subfolder should be compiled after the precompiled header is compiled

Actual Behavior

The file in the subfolder is compiled before the precompiled header is compiled

Analysis

It seems that msbuild misses the dependency on the precompiled header file.

Versions & Configurations

** Visual Studio 2022 Developer Command Prompt v17.12.4
C:\Program Files\Microsoft Visual Studio\2022\Professional>msbuild -version
MSBuild-Version 17.12.12+1cce77968 für .NET Framework
17.12.12.57101
@autoantwort autoantwort changed the title msbuild does not build precompiled header before building source file if UseMultiToolTask=true and path the pch.h is relative msbuild does not build precompiled header before building source file if UseMultiToolTask=true and path to the pch.h is relative Feb 10, 2025
@autoantwort
Copy link
Author

BTW the bug does not occur when I do a #include "pch.h" in test/in-sub-folder.cpp which should be an error because there is no such file in the include search paths (IntelliSence also complains).

@YuliiaKovalova
Copy link
Member

Hi @yuehuang010,

Could you please check if it belongs to custom C++ targets/tasks that might cause this issue?
Thanks!

@yuehuang010
Copy link
Contributor

It is designed to use #include "pch.h" in test/in-sub-folder.cpp. The compiler takes the name from the /Yu"pch.h" switch to look for the #include line.

@autoantwort
Copy link
Author

autoantwort commented Feb 11, 2025

But you can also use #include "../pch.h" in test/in-sub-folder.cpp which is theoretically more correct and specify /Yu"../pch.h". When I don't use UseMultiToolTask this also works fine, otherwise I get the described bug.

@yuehuang010
Copy link
Contributor

MTT detect the pch dependency using the /Yu name to associate to the creating <ClCompile> item. I would expect an error like below because the pch.cpp is still being created in parallel with infolder.cpp.

Adding source "ConsoleApplication1.cpp" with dependency on "pch.cpp".
Adding source "Folder\infolder.cpp".
Adding source "pch.cpp".

error C1083: Cannot open precompiled header file: 'ConsoleApplication1.pch': No such file or directory

@yuehuang010
Copy link
Contributor

yuehuang010 commented Feb 11, 2025

What is the use case? Is it to address the Intellisense squiggle?

A simple workaround is to add the pch path to the list of Include path. That will satisfy the compiler and intellisense.

@autoantwort
Copy link
Author

I would expect an error like below because the pch.cpp is still being created in parallel with infolder.cpp.

No it works fine (UseMultiToolTask=false):

1>------ Rebuild All started: Project: TestCcache2, Configuration: Debug x64 ------
1>pch.cpp
1>TestCcache2.cpp
1>in-sub-folder.cpp
1>TestCcache2.vcxproj -> F:\git_projects\TestCcache2\x64\Debug\TestCcache2.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
========== Rebuild completed at 21:07 and took 01,240 seconds ==========

@autoantwort
Copy link
Author

What is the use case? Is it to address the Intellisense squiggle?

Yes, otherwise everything gets red and code completion does not work.

@yuehuang010
Copy link
Contributor

yuehuang010 commented Feb 11, 2025

I would expect an error like below because the pch.cpp is still being created in parallel with infolder.cpp.

No it works fine (UseMultiToolTask=false):

1>------ Rebuild All started: Project: TestCcache2, Configuration: Debug x64 ------
1>pch.cpp
1>TestCcache2.cpp
1>in-sub-folder.cpp
1>TestCcache2.vcxproj -> F:\git_projects\TestCcache2\x64\Debug\TestCcache2.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
========== Rebuild completed at 21:07 and took 01,240 seconds ==========

MTT will parallelize all work, but it needs information to create a DAG. Help set the edges directly.

<ClCompile>
  <MultiToolTaskDependency>pch.h</MultiToolTaskDependency>
</ClCompile>

@autoantwort
Copy link
Author

So normally when UseMultiToolTask=false the tasks don't get parallelized?

Do I have to set MultiToolTaskDependency for every of my ~6600 files?

@yuehuang010
Copy link
Contributor

yuehuang010 commented Feb 12, 2025

So normally when UseMultiToolTask=false the tasks don't get parallelized?

By default compile parallelism is off. Your options are 1) to enable the MSVC compiler parallelism via the switch /MP. or 2) Use task level MTT.

Do I have to set MultiToolTaskDependency for every of my ~6600 files?

You can use <ItemDefinitionGroup/> to set the value for all <ClCompile/>. The metadata on an individual <ItemGroup/> will overwrite the <ItemDefinitionGroup/>.

<ItemDefinitionGroup>
  <ClCompile>
    <MultiToolTaskDependency>pch.h</MultiToolTaskDependency>
  </ClCompile>
</ItemDefinitionGroup>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants