-
Notifications
You must be signed in to change notification settings - Fork 6
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 Task factory - error when Multitargeting #20
Comments
Hmm, I just tried the repro - it is compiling without errors for me. The output is (I built the
I was running it from Windows - maybe the error happened on Linux? I remember that sometimes there were some subtle differences between those two within MSBuild that occasionally caused problems. |
Are you building with these target frameworks in the csproj? <TargetFrameworks>netstandard1.3;netcoreapp2.0</TargetFrameworks> I am running on windows, doing the build within VS2017 15.6.1 |
Also, at least for me, if you just changed from using |
Yeah, those two - you can see the corresponding DLL file information lines in the output I pasted. :) I did the build from commandline though. Maybe that has some differences compared to VS...? |
Ok so |
I think I found the problem. The VS build uses desktop version of the I think once you add the |
Thanks for having a look :-) The Note this embedding of dependencies is only done for the Desktop version of GitVersionTask. The Fody weaver, aside from just embedding the dependencies as resources, also generates and includes an But if this is the problem, why would it only occur when multi targeting? I can build through VS absolutely fine if I just target the one targetframework or the other. Which means the desktop task is working fine in that scenario? The error only occurs once I target more than one framework.. If there was a problem with a missing assembly or the way fody is resolving the dependencies, then I would expect it to fail on every build from within VS, not just the multitargeting.. :-) |
Thanks for the info, I totally missed the fact that certain dependencies are embedded in After some testing, the current situation is this:
I looked into output of the build in MSVS. Apparently in both scenarios, the UtilPack executes the following tasks successfully, in this order:
Even in successful invocations, there is a text "Failed to resolve GitVersionCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null." indicating that UtilPack failed to resolve the assembly. However, in those cases, I guess the Costura's assembly resolve trick kicked in and saved it. However, when the My guess is that maybe when the assembly is loaded again from the same location, it's Module initializer method (where Costura registers itself to What is the reason you guys ended up using Costura in first place? Can it be avoided somehow? If it is a reasonable option, it would be worth investigating it. |
Thank you so much for looking into this further. To be honest I am not sure of the historic reasons but I know that we used to ILMerge the assemblies. I changed that in my PR to use Costura embedding because I thought this would simplify the build process a little. However it sounds like this has introduced the problem so I will take your advice and look at switching it back to ILMerge or potentially removing it all together and move to seperate assemblies. Im not sure why they were eager for a single assembly but it sounds unnecessary really. Ok i'll try that :-) cheers |
I played around a bit, and I added a Using ILMerge would be a good thing, I would recommend my own project CILMerge, but unfortunately it is a bit out of date. If the reason for the assembly merge is (like me) that you want to ensure that architectural layers only reference each other as needed (and disable circular references), then NsDepCop might be good option. I have not yet used it myself, but it seems to aim at exactly what I was doing when most of my projects were CILMerged: making sure that intra-project dependencies are handled well and according to rules. This way, instead of splitting your project into several assemblies, you just need to split it into several namespaces within one assembly (which is the end-result for project consumers anyway). |
Interesting. It sounds like a time sink to me to trace the exact root cause, so I have taken the easy road and removed all forms of dependency embedding. I have updated the repro, and it all seems to be working fine. To be honest being a build time package, I can't understand why embedding would be necessary - it can't be aesthetics, and the dependency graph is not complicated. I can only think that at some point in the past, older versions of msbuild were not able to locate assemblies correctly necessitating in the need to embed dependencies.. In any case, this doesn't seem to be a problem anymore, I'm not sure if that is due to msbuild, or Utilpack handling the resolution now - but either way, it works :-) |
Quick question - why so many restores? It seems three restores per target framework youy are building against:- 1>[NuGet Minimal]: Restoring packages for C:\Users\Administrator\AppData\Local\Temp\gx3n052t.hmk\dummy... Why three? |
Also is there a way to leave the temp directories around if you want to have a peek to see what is going on :-) |
Also, I notice its using So I log in to windows as "Daz" which is not an Admin. In this scenario, do you think it should it use Daz for the temp directory rather than Administrator? I'm not sure, because I guess the process has been elevated to run under the Admin user, but it still feels weird I have files being placed under a different profile. |
Glad to hear! It is most likely the combination of both MSBuild and UtilPack, but the main thing is that it works now!
It runs three tasks under the UtilPack task factory per framework, so when building for two frameworks you get six restores (since each restore is done for each task), three per each framework.
Ah, those paths only to satisfy the NuGet - the restore will fail if I don't put something in certain properties of the
Yeah - that's because your VS is running as administrator, so the |
Ah I see. Is there any potential of an optimisation around that in the case that the tasks are all from the same assembly? i.e so the number of restores in this case would drop to one? p.s I am not complaining, I am just pre-empting questions that people will have when inspecting the build output :-)
Ah ok. Would you perhaps consider changing this to use the repo or package directory? If it doesn't actually write anything there it's just aesthetics but it's much less alarming seeing a repo or package path in an msbuild output log than seeing a user profile path, and it would help eliminate questions like the one I had about the Admin directory. Just a consideration. Thanks for clarifying! |
Long ago I investigated the methods in IBuildEngine4 interface, which would allow to share state between MSBuild invocations, exactly in hopes of this kind of optimization. IIRC I ran into some problems there though (maybe the state sharing methods were unusable until the actual task execution started?), so I decided to drop it at that time. I'll open separate issue for that.
No worries - I think you're making valid points, and this is good discussion. 👍
It's a good idea - I'll open issue for that. :) |
I have been testing a little more and have just found an issue that is puzzling me a little..
The task factory breaks if I use multi-targeting with more than one target framework specified.
For example - building with either of these and the task factory works:
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<TargetFrameworks>netstandard1.3</TargetFrameworks>
However when I do this:
I get the following build errors:
There is a branch here for repro: https://github.com/dazinator/gitversion_pr1269/tree/issue
The text was updated successfully, but these errors were encountered: