When MSBuildProjectExtensionsPath is set in Directory.Build.props, the nuget props file (nuget.g.props, which defines Pkg* variables) are not read by NCrunch, so references using Pkg* variable are missing.
Seems that NCrunch is using BaseIntermediateOutputPath to read the nuget props file.
You are correct. Changing this property will break NCrunch. To enable NCrunch to work with MSBuild, we need to override certain things and make adjustments inside the build. This does mean there are certain things we simply can't support (like changing this property).
I'm not sure what you're trying to achieve, but does suppressing the property declaration resolve this for you?
Thanks Remco.
Our build system relies on setting this MSBuildProjectExtensionsPath property.
I've tried suppressing it for NCrunch before, but I got this error that obj\project.assets.json is not found. The generated files are in .pkgref folder as we set in MSBuildProjectExtensionsPath.
Could we let NCrunch run nuget restore for itself?
System.Exception: An exception was thrown in the remote environment: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> nCrunch.Common.UserException: Errors occurred while trying to load the project file:
Assets file 'C:\Users\yizmo\source\repos\NCrunchBuildFailure\NCrunchBuildFailure\obj\project.assets.json' not found. Run a NuGet package restore to generate this file.
at nCrunch.Compiler.ComponentAnalysisContext.()
at nCrunch.Compiler.ComponentAnalysisContext.AnalyseComponentBuild()
at nCrunch.Compiler.RemoteBuildRunner.AnalyseComponentBuild(ComponentLoadParameters parameters)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at nCrunch.TaskRunner.Ipc.IpcMessageProcessor.(CallMethodMessage )
at nCrunch.TaskRunner.Ipc.IpcMessageProcessor.ProcessMessageReturningResult(Byte[] data)
at nCrunch.TaskRunner.Ipc.RemoteInstance.(Byte[] )
at nCrunch.TaskRunner.Ipc.RemoteInstance.Invoke(IMessage msg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at nCrunch.Compiler.IRemoteBuildRunner.AnalyseComponentBuild(ComponentLoadParameters parameters)
at nCrunch.Core.BuildManagement.BuildProcessLauncher..(IRemoteBuildRunner )
at nCrunch.Core.BuildManagement.BuildProcessLauncher.(Action`1 , FilePath , String , ExternalProcess )
at nCrunch.Core.BuildManagement.BuildProcessLauncher.(Action`1 , EffectiveProcessorArchitecture , GridClientId , BuildSystemParameters , IList`1 , Nullable`1 , GridAddress , DotNetCoreSdkVersion )
at nCrunch.Core.BuildManagement.BuildProcessLauncher.AnalyseComponentBuildInExternalProcess(ComponentLoadParameters parameters, IList`1 customEnvironmentVariables)
at nCrunch.Client.ComponentLoader.SnapshotComponentLoader.(EffectiveProcessorArchitecture , String )
at nCrunch.Client.ComponentLoader.SnapshotComponentLoader.CreateComponentFromXml(FilePath projectFilePath, ParsedBuildXml projectXml, FilePath solutionFilePath, String[] additionalFilesToIncludeAtSolutionLevel, Boolean isLoadedFromFile, IDEVersion vsVersion, ComponentUniqueName componentName, TaskSettings componentTaskSettings, Exception parseException, String targetFrameworkForMsbuild, String visibleTargetFramework)
yizhou wrote:Thanks Remco.
Our build system relies on setting this MSBuildProjectExtensionsPath property.
I've tried suppressing it for NCrunch before, but I got this error that obj\project.assets.json is not found. The generated files are in .pkgref folder as we set in MSBuildProjectExtensionsPath.
Could we let NCrunch run nuget restore for itself?
I was worried about this. This is, unfortunately, one area of NCrunch where we have little to no flexibility. The problem here is rooted in the way VS handles the Nuget restore step. Basically, we can't do the restore ourselves in a stable way without interfering with VS. When MS introduced the automatic package restore step, our initial builds did actually do this, but we had to take it out because MSBuild simply can't handle two processes performing the step concurrently in the same place.
So we're reliant on VS to perform this restore step for us, then we need to be reliant on standard build conventions when finding these files, because MSBuild has its own expectations and constraints when we call into it.
From the side of someone engineering a build system, overriding this particular property (and certain others like it) can seem like a perfectly reasonable thing to do. But from the perspective of NCrunch's build integration, it's basically like pulling out the foundation under a stack of cards. In almost every other area of the build system there are workarounds we can introduce, or things we can override to bend it to our will. But this part is really baked together. The package restore step and location of its derived files might as well be set in stone as far as a maintainable NCrunch is concerned.
This is not to say that is impossible to make such a system work, but rather that it would involve hacking the build system in ways that would introduce unforeseeable side-effects, making our build integration impossible to maintain.
Sorry, you need to avoid changing this property if you want to use NCrunch on this solution.
It works as expected but we're seeking a more generic solution that doesn't need to hard code the project name in each project.
I've tried $(MSBuildProjectFile) but it becomes a temporary file name like nCrunchTemp_c3f9f128-4e6e-4467-a77c-009678083cfa.csproj.
I'm wondering if there's some property that we can use to get the original project name?
It's great that this works around the issue for you. Nice work!
yizhou wrote:
It works as expected but we're seeking a more generic solution that doesn't need to hard code the project name in each project.
I've tried $(MSBuildProjectFile) but it becomes a temporary file name like nCrunchTemp_c3f9f128-4e6e-4467-a77c-009678083cfa.csproj.
I'm wondering if there's some property that we can use to get the original project name?
Try using $(ProjectName) or $(ProjectFileName). We force these to the name of the original project file.