fsprojects / FSharp.TypeProviders.SDK

The SDK for creating F# type providers
https://fsprojects.github.io/FSharp.TypeProviders.SDK/
MIT License
298 stars 94 forks source link

How to get path to obj folder from type provider? #376

Closed Dolfik1 closed 1 year ago

Dolfik1 commented 2 years ago

I am interested in fix Xamarin.Android.FSharp.ResourceProvider for .Net 6.

Xamarin.Android uses code generation to access any resources (e.g. images, styles and other). It generates Resource.designer.cs file.

Xamarin.Android.FSharp.ResourceProvider compiles Resources.designer.cs file into assembly to give access to resources from F# code.

Since .Net 6 this file moved from ./Resources/Resource.designer.cs to ./obj/Debug/net6.0-android/Resource.designer.cs. I have no idea how to correctly new Resource.designer.cs path from type provider considering that path may be specified in IntermediateOutputPath variable.

dsyme commented 2 years ago

cc @nosami

TBH I don't have any specific recommendation for this - in general type providers don't get this kind of project-build information though they can "work it out". However you're correct in this case the "obj" folder would be IntermediateOutputPath from MSBuild and that is really hard to work out

It may be better for the type provider to take a static parameter. Or simply search recursively for the output under the project directory (though sometimes it is out of the project directory of course.)

nosami commented 2 years ago

A couple of easier solutions that I can think of....

Dolfik1 commented 2 years ago

It may be better for the type provider to take a static parameter

I think this can be tricky to configure. For example: we have different output path on CI and dev workstations.

Create a symlink from Resources/Resource.designer.cs to ./obj/Debug/net6.0-android/Resource.designer.cs or

Same problem here as I said above.

It used to be possible to set the path of the generated file from the .fsproj file. Maybe this still works?

No it doesn't work anymore.

We could also add build task that copies Resource.designer.cs from $(IntermediateOutputPath) to known folder. But this is also tricky and unclear.

I would like to get the most simple solution, without any additional changes in build or project configuration. Otherwise, we will be forced to add this for every project (we have about 20 android library projects in our solution).

nosami commented 2 years ago

@dellis1972 Do you have any suggestions?

dellis1972 commented 2 years ago

We are hopefully going to change direction with regards to the Resource.designer.cs in Xamarin.Android. See https://github.com/xamarin/xamarin-android/pull/6427 and https://github.com/xamarin/xamarin-android/issues/6310.

We are hopeful that by generating a designer assembly (which is just IL ) this will remove the need for the Type Provider.

In the mean time for .net 6 you might be able to set AndroidUseIntermediateDesignerFile to False in your csproj. We turned this on by default for .net 6. But if you want the old behaviour and use 'Resources/Resource.designer.cs' you can set this property to False and it should work as before

<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidUseIntermediateDesignerFile>False</AndroidUseIntermediateDesignerFile>
Dolfik1 commented 2 years ago

We are hopefully going to change direction with regards to the Resource.designer.cs in Xamarin.Android. See xamarin/xamarin-android#6427 and xamarin/xamarin-android#6310.

We are hopeful that by generating a designer assembly (which is just IL ) this will remove the need for the Type Provider.

In the mean time for .net 6 you might be able to set AndroidUseIntermediateDesignerFile to False in your csproj. We turned this on by default for .net 6. But if you want the old behaviour and use 'Resources/Resource.designer.cs' you can set this property to False and it should work as before

<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidUseIntermediateDesignerFile>False</AndroidUseIntermediateDesignerFile>

I think this is might be used as temporary solution.

Dolfik1 commented 2 years ago

Hello. I tried to build app with AndroidUseIntermediateDesignerFile=False, but this didn't work. I still have no access to Resource class.

I see strange warning in build output:

  Referenced assembly '/Users/nikolay/.nuget/packages/xamarin.android.fsharp.resourceprovider/1.0.1/lib/monoandroid81/Xamarin.Android.FSharp.ResourceProvider.Runtime.dll' has assembly level attribute 'Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute' but no public type provider classes were found
]]]

It seems that Xamarin.Android.FSharp.ResourceProvider is not maintained. So, we cannot migrate our F# Android app to .Net 6.

dsyme commented 1 year ago

Closing as the TPSDK doesn't have any specific functionality related to finding the 'obj' directory