Tool-generated fs files must be included in project
I am wondering is it possible to modify msbuild process for a project with fsl/fsy sources in such a way that the .fs files generated by respective FsLex and FsYacc tasks be treated as temporary, and added to the list of files for compiling dynamically after running the tools. Now I have the 2 output .fs files included in project and checked in under source control, and they are not rebuilt when I select rebuild in Visual Studio.
From what I understand of msbuild, this should be possible, but my experience may be limited. Or am I just doing it wrong?
@kkm000 I am not super sure what you mean, but I think I do what you are talking about in this project (which is itself a work in progress): https://github.com/brodyberg/CompilerML/blob/master/Tiger/Tiger/Tiger.fsproj
This project, opened in Xamarin, has two pre-build steps which process lex and yacc input and then overwrite the output files already included in the project so I can see the new lexer or parser after a build.
@brodyberg, my thinking was a bit different: adding generated files (in your example, TigerLexer.fs and TigerParser.fs) into compilation (adding them to FSc task inputs), but not requiring for them to be in the project. So in a sense treat them like they were a kind of object files: they are generated, then used in a next build step, but do not show up in the project.
On a second thought, that will make generated F# types and functions unavailable to intellisense. This is not an easy thing to fix, and certainly not one to fix with NuGet capabilities alone.
And the problem is that when the files are checked out, source control assigns them current time. With svn, all files get the same exact timestamp. So, if anyone commits an fsl or fsy file ithout recompiling and another machine checks out the project (that also includes respective generated .fs files), the files will not be recompiled automatically. I am thinking about approaching this particular problem from another end, and any input is very welcome!
Would be nice to show generated files as nested files.
In the project file it looks like this:

According to you initial idea, I think that you can achieve it using <Visible>false</Visible> attribute.
My project file:
<ItemGroup>
<Compile Include="Ast.fs" />
<Compile Include="$(IntermediateOutputPath)\Parser.fs">
<Visible>false</Visible>
<Link>Parser.fs</Link>
</Compile>
<Compile Include="$(IntermediateOutputPath)\Lexer.fs">
<Visible>false</Visible>
<Link>Lexer.fs</Link>
</Compile>
<FsYacc Include="Parser.fsy">
<OtherFlags>--module Parser</OtherFlags>
</FsYacc>
<FsLex Include="Lexer.fsl">
<OtherFlags>--unicode</OtherFlags>
</FsLex>
<Compile Include="Program.fs" />
</ItemGroup>
and what I see in the VS:
IntelliSense works as expected
@sergey-tihon Thanks for checking, this is an interesting idea. I'll see what I can do with it!
I'll look into better MSBuild integration. I've recently done it for a fairly big project, so my mind is still fresh on it. The big questions is maintaining the compilation order: it's not possible, generally, without a serious hack, to transform at MSBuild run time
<ItemGroup>
<Compile Include="foo.fs>
<FsYacc Include="bar.fsy>
<Compile Include="baz.fs>
</ItemGroup>
into input to the compiler (the pos-generation fsc stage)
<ItemGroup>
<Compile Include="foo.fs>
<Compile Include="bar.fs>
<Compile Include="baz.fs>
</ItemGroup>
while retaining the order (although I do augment the Compile collection for non-order-dependent pre-compile generators). The reason is the collections (Compile and FsYacc) are entirely separate, and retain their order strictly independently. An MSBuild task kind of has access to source line numbers, but relying on this would be a serious and brittle hack. I'll see what I can come up with.
The current state of affairs is less that ideal. I had to put some tweaks into the build file (VS, the new concise "SDK-style" project) for it to work at all.