-
Notifications
You must be signed in to change notification settings - Fork 257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom Fable TFM #13977
Comments
Hey @jwosty, NuGet owns the mapping for the frameworks, but we need a more general agreement that a An example is the recent addition of the .NETnanoFramework in here: #10800. cc @terrajobst |
What is your expectation of compatibility? Say I've a project targeting the new Fable TFM. What other projects can I reference / which packages can I install? Can I install But if the answer is not none, then we need to talk about how these mappings evolve over time. |
android and ios no longer have a target framework identifier, they're platforms within the .NETCoreApp TFM. There used to be old Xamarin TFMs, but that's obsolete since .NET 5/6 with If fable can fit within the "platform" concept, then no changes are needed to NuGet. It will Just Work when the appropriate MSBuild properties are set. |
There's some relevant prior discussion here: fable-compiler/Fable#3549 . There's still some open questions in there but I hope it provides some context. This is more of an ask for help and guidance as to what some good options if this were to be done, rather than a formal request (hence opening it as a discussion originally instead of an issue). Fable already has a great ecosystem of packages that work with it, but it currently just uses a NuGet tag ("fable") to tell if a package is fable compatible (essentially a poor man's TFM). See a list here: https://www.nuget.org/packages?q=Tags%3A%22fable%22 ; looks like the current count is 494 packages. The NuGet TFM on these packages is actually a lie. There are drawbacks of such an approach (with which we are living), with probably the biggest drawing being that for a package to support both real .NET and Fable, it has to have two separately named packages (for example Thoth.Json and Thoth.Json.Net) See this comment in particular for two different options for TFM schemes I have been mulling over: fable-compiler/Fable#3549 (comment)
It would be its own universe. Referencing a package from a Fable project would need to itself have Fable as a target (because non-Fable packages lack the sources that Fable currently needs to perform its compilation, and not every valid .NET standard program is a valid Fable program).
In terms of MSBuild, yes. But I think even for those NuGet requires itself to be aware of all possible TFMs, right? (I may be wrong and please correct me if so; I last researched this stuff over a year ago) For reference, here was my attempt at a PoC: https://github.com/jwosty/Fable.MSBuild.Sdk/ |
So basically Fable can only consume Fable and can only be consumed by Fable. IOW, Fable is only compatible with itself. That's the easiest model. To give some background, with .NET 5 we moved away from custom framework mappings in favor of platform-style TFMs (such as Your model doesn't require that; I just want to set the expectation that if we go with a standalone TFM we can't easily add platform relationships later. You get, of course, the standard version relationship for Fable itself (e.g. Does that still sound good? How much work would it be to add a standalone TFM with no compatibility mapping? |
OK so some of this is coming back to me. I think I had figured out that Fable kind of has to have its own TFM, because if you just piggyback on the "platform" concept, you have to allow referencing the base TFM too, which 100% cannot work for Fable (a fable project cannot reference a
Yep, that is totally fine. Fable can't do that anyway and probably will never be able to tbh. |
@jwosty do the different language targets of Fable (js, ts, python rust, etc) need to be substantially different targets from an API surface point of view? And how does the Fable API surface evolve over time as a general rule? Would there eventually need to be |
I'm putting a stake in the ground by opposing any framework without version. IOW, folks will be able to use |
I think so. Since Fable basically just shims the BCL and FSharp.Core with its own definitions, and since this has to be done manually, the supported APIs are the not same across the different targets.
Yep, I would imagine the version would just be in lockstep with the Fable compiler's version (in fact version 5.0 is currently in alpha, so I imagine we'd actually be starting with a |
@terrajobst The cost of adding a standalone tfm is pretty low. I'm curious to learn more about the language targets. Are they something that needs to be expressed in a similar way platforms are expressed, or would all language targets target the exact same tfm? |
I think they would work similarly to .net platforms. Conceptually you can write code that is compileable to all target languages Fable supports (i.e. plain-old-F# using only simple functions and types). It's only when you start using some target language specific things that restricts your code to a particular language runtime. For example: calling Javascript's DOM API, or calling out to Python's NumPy. I'm honestly unsure whether there should be a single |
To follow up: would it make sense for NuGet to only concern itself with the general pattern, i.e. |
Is there such as thing as |
Hello, I am one of Fable maintainer, I know Fable well but still have trouble with all the NuGet concepts. I don't really know the difference between TFM and platform, and how they work for package resolution. Because of that, I don't understand things like:
To clarify a few points from above:
TagsThis is not exactly true, the The same applied to others tags like Fable package typeFable can work with 2 types of NuGet packages:
A Fable package can also be a .NET package. For example, this is the case for FsToolkit.ErrorHandling. This is important because we don't want that because a package is mark as a Fable package to not be able to use it on a standard F# project.
Yes Fable API surface evolve over time:
Something I want to note, if I remember correctly, one of the main reason/benefit for adding a new platform/TFM is the ability to restore different dependencies based on the target runtime. For example, you could have a
Because of the above, I think our idea was to always have a language associated with Fable. The exception, could be for package that can be used on any runtime which is why @jwosty talked about And if needed, we could use a custom MSBuild task to automate it for the user. We are already doing some similar automation via https://github.com/fable-compiler/Fable.Package.SDK Scenarios / QuestionsCan a Fable package can consume .NET package? Currently, this is the case will it be case with the new system or does it means we need
Can we have different list of dependencies based on the Fable target (Rust, Python, JavaScript)? Currently, we can't support that we need to depends on both which can mess up the compilation sometimes. Our workaround, is to publish 2 different packages but this doesn't scale well and needs a lot of compiler directives.
Can a Fable package be marked to be compatible with any target? Currently, this is possible. The only requirement is for the Fable package to use only BCL supported API. Note that ATM not all target supports the same list of APIs because some are in beta but in the future we want to have the same level of support.
Summary
I tried to both answer the questions from above and add my own knowledge of Fable. I hope, I was able to make it somewhat understandable. If more explanations are needed, I stay available. |
NuGet Product(s) Involved
NuGet.exe
The Elevator Pitch
Hello NuGet team! I'm representing the Fable project (the popular F#-to-Javascript transpiler), and we want to look into having a custom TFM for fable specifically, so that we can integrate it better into the NuGet/MSBuild ecosystem (similarly to how Tizen, Andriod, iOS, etc works).
Additional Context and Details
I previously opened a discussion item for this here. More of the gory details and relevant links are in there. We would really like to have a conversation with someone from the NuGet team about this.
The text was updated successfully, but these errors were encountered: