*rubbing eyes* in MSBuild, what is the difference between DependsOnTargets and AfterTargets? Isn't that the same thing?
@drewdaniels The project I'm working on this second is primarily developed on Mac so we need to edit the MSBuild directly.
@mcc As I understand it, they are close to the inverse of each other.
Thinking in terms of what triggers what:
"AfterTargets" will trigger the target you're defining when _they_ are built, but you can build the target you're defining without triggering them.
"DependsOnTargets" are triggered before the target _you're defining_ is built, but your target won't always be triggered if they are.
@sundew OK. In that case, is BeforeTargets different from DependsOnTargets
@mcc Similar in effect, but defined at the opposite end, I think.
A has BeforeTargets="B"
equals
B has DependsOnTargets="A"
Building B first builds A.
There may be some differences if a "Depends" target is already being built as part of a dependency chain, I'm not sure if it would be built more than once, but I would expect "Before" to trigger for each target it is before?
Citation/experimentation very much needed. :)
To be honest, this is all very much deep magic that I would avoid if at all possible. 🙃
So I feel like this has happened to me nine times, in three different build systems, and I'm so tired.
We have an MSBuild project. It has targets A,B,C,D. Target D has an AfterTargets="A;B;C" in its xml.
When we run the project, we visibly see in the output window that the targets run in the order C;D;A;B. Moreover, the output of D is incorrect, as if D had been run without A and B having run first.
Why. Why. Why. Why. Why.
How do I convince MSBuild to do what I tell it to.
I'd try to delete the compiled results of all of them before compiling. Maybe that forces msbuild to do the right thing, since it is the only way not to throw an error. If it works, you can run it as an script before compiling.
The issue sounds like an optimization gone wrong. Are there references in the code from D to A, B and C? Maybe it is ignoring that line and applying its own dependency analysis. If there are only references to C from D, it would totally explain the behavior.
@jcurioso We figured it out later
@mcc I know this isn’t precisely helpful, but this is why I always use CMake for anything that needs to build on Windows. Truly never understood Vcproj or MSBuild at all.
@c0dec0dec0de If you are building a C# program, you will not be doing it in CMake. You will be doing it in MSBuild (eg, csproj files, which are literally MSBuild files with a csproj extension).
Related questions which I do not expect you to have an answer to.
1. Is this relevant? I think no, because it relates to MSBuild being told to build multiple project files in parallel, and our current problem concerns targets run potentially in parallel?
https://github.com/dotnet/msbuild/issues/11784
2. There's a <ZipDirectory> task in MSBuild. We in fact want our MSBuild to create a zip. But we want a 0-compression zip, which ZipDirectory lacks as an option.
How would you attack this problem? Must work on WIndows
@mcc problem 2:
This appears to be the source code for ZipDirectory
https://github.com/dotnet/msbuild/blob/main/src/Tasks/ZipDirectory.cs
It has a CompressionLevel parameter which accepts "NoCompression". I don't know why this isn't advertised in these docs:
https://learn.microsoft.com/en-us/visualstudio/msbuild/zipdirectory-task?view=visualstudio
*rubbing eyes* I stated this indistinctly.
There is a target CoreCompile. dotnet.exe runs this automatically.
We have our own targets, A, B, C, D. A, B and C are listed as AfterTarget="CoreCompile". D is listed as AfterTarget "A,B,C".
At this exact moment, what I believe is that I have stated an ordering where if you compile A, B, or C, you must build D after that, but I have not stated ANY dependency such that D must be *delayed* until A, B and C have completed.
⁇
We seem to get the behavior we want if we give D an AfterTargets="A;B;C" AND a DependsOnTargets="A;B;C". Okay. I…
I think this is correct?
@mcc if target A has AfterTargets="B" then running B will also run A afterwards, if target A has DependsOnTargets="B" then running A will also run B first
@mcc I just use Visual Studio and set a target in my solution file to whatever project files and then setup my dependency graph in there. MSBuild seems to read the sln, though sometimes I have to set the target.
Recently I’ve stated using dotnet build which I think just wraps msbuild.