[Bug] vcxproj ProjectReference from csproj triggers a build of the vcxproj but does not copy the target when modified
fforjan opened this issue · comments
Issue Description
Whe csproj references a vcxproj updated to copy the native dll to the .net folder, the initial build will copy the dll but any subsequent build triggered from the C# project following a modification to of the C++ will not copy the output.
Note that the option that building the solution is not acceptable, we have this type of issue into a large solution when a unit tests refrecnes a native DLL and the developer usually build the unit test project only.
Steps to Reproduce
- Clone the repository: https://github.com/fforjan/CSProjectAndVcxprojReferences
- Open in visual studio
- Build the ConsoleApp project
Notice that the NativeDll.dll is copied into the output folder, both for net472 and net80
- Modify a cpp file into the NativeDLL project
- Build again the ConsoleApp project.
Expected Behavior
As one the initial build, if any projectreference is updated, the dll must be copied over ?
Actual Behavior
Notice the the NativeDLL.dll is NOT updated into the output folder while the NativeDLL compilation was triggered.
Analysis
No response
Versions & Configurations
Reproduced with Microsoft Visual Studio Enterprise 2022 (64-bit) - Version 17.9.2
I can reproduce a different behavior with MSBuild in command line.
The NativeDll will never appear when using the command line, and if the NativeDLL was already present :
CSProjectAndVcxprojReferences\ConsoleApp>msbuild
MSBuild version 17.9.5+33de0b227 for .NET Framework
Build started 3/7/2024 2:30:23 PM.
Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" on node 1 (default targets).
Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" (1) is building "C:\git\CSProjectAndVcxproj
References\ConsoleApp\ConsoleApp.csproj" (1:2) on node 1 (Build target(s)).
Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" (1:2) is building "C:\git\CSProjectAndVcxpr
ojReferences\NativeDll\NativeDll.vcxproj" (2) on node 1 (default targets).
PrepareForBuild:
Structured output is enabled. The formatting of compiler diagnostics will reflect the error hierarchy. See https://ak
a.ms/cpp/structured-output for more details.
InitializeBuildStatus:
Creating "NativeDll\Debug\NativeDll.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
Touching "NativeDll\Debug\NativeDll.tlog\unsuccessfulbuild".
ClCompile:
All outputs are up-to-date.
All outputs are up-to-date.
Link:
All outputs are up-to-date.
NativeDll.vcxproj -> C:\git\CSProjectAndVcxprojReferences\NativeDll\Debug\NativeDll.dll
FinalizeBuildStatus:
Deleting file "NativeDll\Debug\NativeDll.tlog\unsuccessfulbuild".
Touching "NativeDll\Debug\NativeDll.tlog\NativeDll.lastbuildstate".
Done Building Project "C:\git\CSProjectAndVcxprojReferences\NativeDll\NativeDll.vcxproj" (default targets).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreGenerateAssemblyInfo:
Skipping target "CoreGenerateAssemblyInfo" because all output files are up-to-date with respect to the input files.
_GenerateSourceLinkFile:
Source Link file 'obj\Debug\net8.0\ConsoleApp.sourcelink.json' is up-to-date.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
_CreateAppHost:
Skipping target "_CreateAppHost" because all output files are up-to-date with respect to the input files.
_CopyOutOfDateSourceItemsToOutputDirectory:
Skipping target "_CopyOutOfDateSourceItemsToOutputDirectory" because all output files are up-to-date with respect to th
e input files.
CopyFilesToOutputDirectory:
ConsoleApp -> C:\git\CSProjectAndVcxprojReferences\ConsoleApp\bin\Debug\net8.0\ConsoleApp.dll
IncrementalClean:
Deleting file "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\bin\Debug\net8.0\NativeDll.dll".
Done Building Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" (Build target(s)).
Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" (1) is building "C:\git\CSProjectAndVcxproj
References\ConsoleApp\ConsoleApp.csproj" (1:3) on node 1 (Build target(s)).
_WriteAppConfigWithSupportedRuntime:
Skipping target "_WriteAppConfigWithSupportedRuntime" because all output files are up-to-date with respect to the input
files.
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the i
nput files.
CoreGenerateAssemblyInfo:
Skipping target "CoreGenerateAssemblyInfo" because all output files are up-to-date with respect to the input files.
_GenerateSourceLinkFile:
Source Link file 'obj\Debug\net472\ConsoleApp.sourcelink.json' is up-to-date.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
_CopyAppConfigFile:
Skipping target "_CopyAppConfigFile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
ConsoleApp -> C:\git\CSProjectAndVcxprojReferences\ConsoleApp\bin\Debug\net472\ConsoleApp.exe
IncrementalClean:
Deleting file "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\bin\Debug\net472\NativeDll.dll".
Done Building Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" (Build target(s)).
Done Building Project "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\ConsoleApp.csproj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Notice there is an 'incrementral clean' but it doesnt copy the native dll after ?
IncrementalClean:
Deleting file "C:\git\CSProjectAndVcxprojReferences\ConsoleApp\bin\Debug\net472\NativeDll.dll".
@GangWang01 Could you repro this issue? We suspect it might be an up-to-date check problem.
It's easy to reproduce with the provided solution https://github.com/fforjan/CSProjectAndVcxprojReferences. As the issue mentioned, I reproduced and attached binlogs binlogs.zip.
- Clone the repo and open the solution using VS 17.9.2.
- Build C# project ConsoleApp. Binlog is FirstBuildWithVS.binlog.
- Make code change to C++ file in C++ project project NativeDLL.
- Build C# project ConsoleApp. Binlog is IncrementalBuildWithVS.binlog. Note that only C++ project was built, but C# project wasn't built at all. NativeDLL.dll in bin directory of C# project wasn't the latest one.
- Repeat step 3.
- Use msbuild.exe from Developer Command Prompt to build. Binlog is IncrementalBuildWithMSbuild.binlog. Note that another issue appeared. NativeDll.dll in bin directory of C# project was deleted.
Is the NativeDLL a CLI project? If it is not, it should not be returning from GetTargetPath.
@yuehuang010 no it is a C++ library project - not sure what you mean by CLI ? - and follows https://stackoverflow.com/a/42507529 to allow copying its output to the C# project.
I am leaning toward NativeDll getting copied in VS as a bug. A C# project wouldn't know what to do with a C++ output.
I think the csproj has another mechanism of fetching it via the Traversal copy that has to be opt-in. It should fetching the BuildOutputGroup target.
The stack overflow link as an interesting description about why it should work.
But if you have a different settings I'm happy to try.
@rainersigwald can you help to take a look? Note that there are different problems when building with VS and msbuild.exe.
@GangWang01 let me know if you have any update
@surayya-MS any update on your side ?
@surayya-MS ping !
Thanks for filing this bug @fforjan!
Currently, our team is focusing on higher-priority items, we will get to this one later.