2

I want to generate C# classes from a flatbuffer schema, and consume these classes in another project.

For this I need to invoke the flatbuffer schema compiler to generate the classes. I do not want to check in the class-files, but rather generate them during the build process, such that I do not need to update them manually.

Assume a C# solution with two projects:

MessageDefinitions.csproj
MessageConsumer.csproj

MessageDefinitions contains a prebuild event, which invokes the flatbuffer schema compiler and puts the generated C# source files into the folder MessageDefinitions/Messages/.

I then want to consume the generated types in MessageConsumer (which has a reference to MessageDefinitions).

The problem is that the compiled MessageDefinitions.dll does not contain the generated types, and thus building MessageConsumer fails. If I compile a second time, the build succeeds, as the files in MessageDefinitions/Messages/ already exist and are included in the compiled output.

Is there a way to make the compiler include the source files generated by the prebuild-event in MessageDefinitions on the first build?

Any help is appreciated, Kind regards.

MariusQS
  • 23
  • 3
  • You should consider putting the generated file in a sub folder called gen in your project – Daniel A. White Oct 07 '22 at 12:32
  • From past experience I can suggest this, create a dummy empty project in your solution called e.g. BeforeBuildEvents that is the first project to build in your solution then move the Pre-Build events from your project to this project. That helped my in the pass to solve similar issues with pre-build events – Siraf Oct 07 '22 at 12:36
  • Chicken-and-egg problem. It will run the prebuild event only *after* determining what needs to be built and whether a build is necessary at all. You can only get a helpful answer when you explain why such shenanigans were deemed necessary. – Hans Passant Oct 07 '22 at 12:42
  • genuine question, sorry if this sounds silly - why not just `` ? – Marc Gravell Oct 07 '22 at 12:55
  • @MarcGravell I simplified my real project for this post, probably a bit too much. "Class1.cs" represents an autogenerated flatbuffer message definition generated during the prebuild-event by invoking the flatbuffer schema compiler. So, it does not actually copied but created during the event. – MariusQS Oct 07 '22 at 13:05
  • @DanielA.White Would a sub-folder named "gen" be treated differently by the compiler? The output of the prebuild-event is already placed into a subfolder of the MyProject-folder. – MariusQS Oct 07 '22 at 13:07
  • @Siraf If I understand your proposal correctly, this is what I did. The problem is that the compiled dummy project will not contain the files generated during the prebuild event, and thus they cannot be consumed by dependent projects. – MariusQS Oct 07 '22 at 13:12
  • @HansPassant This explains why my attempt does not work. I was hoping for something like a compiler flag that would enable this behavior, but could not find a suitable option in the docs. – MariusQS Oct 07 '22 at 13:17

1 Answers1

4

Add something like the following to MessageDefinitions.csproj. I adapted and simplified it from the gist AddGeneratedFile.csproj by the author of MSBuild Structured Log Viewer (a tool a strongly recommend taking advantage of when working with MSBuild).

  <PropertyGroup>
    <MessageClassesPath>MessageDefinitions/Messages/**/*.cs</MessageClassesPath>
  </PropertyGroup>

  <Target Name="AddMessageClasses" AfterTargets="PreBuildEvent" BeforeTargets="BeforeCompile;CoreCompile">
    <ItemGroup>
      <Compile Include="$(MessageClassesPath)" />
    </ItemGroup>
  </Target>
weir
  • 4,521
  • 2
  • 29
  • 42