Custom msbuild task
hey i wrote a custom msbuild task and created a nuget for it. in the project Im using the task it seems to work, but in the CI it doesnt. i can reproduce the same error when cleaning my nuget folder locally.
[MSB4036] The "..." task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "/usr/share/dotnet/sdk/8.0.403" directory.
19 Replies
the task that uses the msbuild task runs
BeforeTargets="PrepareForBuild;BeforeBuild"
and im suspecting that the nuget wasnt restored yet
yes, what would be the correct BeforeTargets
for a job that should run after restore but before sourcegenerators run?Source generators run during the regular CoreCompile step. Have you looked at a binary log yet? https://msbuildlog.com/
yeah, i didnt find anything suspicious. the msbuild task produces files and the source generator consumes these files. my problem is that: sometimes on a build files are missing for the source generator and not everything is created, sometimes all files are missing, sometimes none and sometimes just a few
Well, what does the binary log show in those cases? Did your task run?
i have only created the binlog on my local machine where it always succeedes
ill try to create the binlog in the docker container
Are we still talking about the same problem you posted originally?
Or something else?
yeah so it seems that BeforeTargets="PrepareForBuild" is too early and happens before the msbuild task nuget is restored
Right, that's why I told you to use the msbuildlog to find the target you actually want to hook
If you want to run before a source generator, you want the regular compilation task
whats a regular compilation task?
CoreCompile
ok now that the msbuild task works, my source generator for consuming the produces files fails...
or rather, compilation fails before the source generator emits the files
ive added a warning for each file that is processed with context.ReportDiagnostic()
and i can see that half of the files is processed and then i get a compilation error complaining about types not being found that are generated later in the log o.O
I don't know what "compilation fails before the source generator emits the files" means. Source generators don't emit files
right, the source generator calls context.AddSource()
thats what i meant
They add virtual files to the compilation. Nothing emits them unless you ask the compiler to do so
I don't know what this means either
If compilation fails, then it means either:
1. This is not the compilation step you think it is.
2. Your source generator did not produce the source you think it's producing
so my log output looks like this:
CSC : warning SG0001: processed: A [/..../...csproj]
CSC : warning SG0001: processed: B [/..../...csproj]
CSC : warning SG0001: processed: C [/..../...csproj]
CSC : warning SG0001: processed: D [/..../...csproj]
/..../....cs(116,75): error CS0117: 'E_Generated' does not contain a definition for 'mystruct' [/..../....csproj]
/..../....cs(116,111): error CS0117: 'F_Generated' does not contain a definition for 'mystruct' [/..../....csproj]
Build FAILED.
CSC : warning SG0001: processed: E [/..../....csproj]
CSC : warning SG0001: processed: F [/..../....csproj]
the warnings are emitted by the source generator
Look at a binlog
I'm guessing those are not the same build steps
Given the ordering that you posted
its all one csc call, i cant look what csc is doing in the binlog, can i?
csc invokes the source generator, doesnt it?
Then you're likely in possibility 2
Set
EmitCompilerGeneratedFiles
in your csproj and see what your generator is actually emitting
Just because your generator emitted a warning saying that it processed E
doesn't mean that it did what you think it did with E
after inspecting the generated files it was clear that my msbuild task sometimes produced wrong output. the task calls another binary that creates the file and waits for its exit. then it opens the file and reads the content. sometimes the file seems to be empty. placing a sleep(5000) after process.WaitForExit() seems to make it work ...
that only happens in docker and not on windows, i guess on windows the file is locked or something, but i would expect the file writes to be finished when WaitForExit returns