Skip to content

Need a way to specify RID-specific dependencies #4552

Closed

Description

@ericstj

Folks often need to cross compile and use an OS-specific package. Today the only way they can do this is to fork their project.json.

I think we need a "dependencies" section under the RID entry in runtimes.

This is related to NuGet/Home#1660.

Activity

  1. ericstj commented on Dec 10, 2015

    @ericstj
    MemberAuthor

    Dependencies under RID might not be the right design since RID has no impact on the compile graph today, but the basic problem is I need to produce an implementation on Windows that uses windows specific packages (which cannot be used for Unix and will fail to resolve any assets) and vice-versa.

    /cc @davidfowl @anurse

  2. ericstj commented on Jan 9, 2016

    @ericstj
    MemberAuthor

    Here's a suggestion for how we can represent this: permit a runtime to be nested under framework. When that exists it indicates that we should cross compile for that runtime. In that case we'll use the TFM:RID target (runtime graph) for both the compile items and the runtime items. The runtime listed under framework can have its own dependency section to represent packages dependencies specific for that runtime. Here's a sample of how that might be used:

    EG:

    "dependencies": {
        "NETStandard.Library": "1.0.0-rc2-23616"
    },
    
    "frameworks": {
      "dnxcore50": {
        "runtimes": {
          "win": {
            "compilationOptions": {
              "define": ["WIN"]
            },
            "dependencies": {
              "System.Security.Cryptography.Cng": "4.0.0",
              "System.Net.Http.WinHttpHandler": "4.0.0"
            }
          }
          "unix": {
            "compilationOptions": {
              "define": ["Unix"]
            },
            "dependencies": {
              "System.Security.Cryptography.OpenSsl": "4.0.0",
              "System.Net.Http.CurlHandler": "4.0.0"
            }
          }
        }
      }
    }
    

    @davidfowl @anurse: thoughts?

  3. andyleejordan commented on Jan 26, 2016

    @andyleejordan
    Member

    We are definitely going to need this for an internal project, sooner rather than later.

  4. davidfowl commented on Jan 26, 2016

    @davidfowl
    Member

    I'll write something up with how this might work. We have a design in mind

  5. vors commented on Jan 26, 2016

    @vors

    I (as a user) think it's a good design.

    Also connected scenario: I want to be able to build my dependencies from sources, but at the same time, I want to be able to consume dependencies as packages from nuget. I would love to have it to provide an easier setup for people, who care only about a particular package in the project.

    Looks like this feature will allow me to do it as well.

  6. davidfowl commented on Jan 26, 2016

    @davidfowl
    Member

    Project file changes

    Foo/project.json

    {
        "version": "1.0.0-*",
        "frameworks": {
          "netstandard1.3": {
            "dependencies": {
              "System.Console": "4.1.0-rc2-3455"
            }
          },
          "netstandard1.3(win7)": {
            "dependencies": {
              "System.Security.Cryptography.Cng": "4.1.0-rc2-3455",
              "System.Net.Http.WinHttpHandler": "4.1.0-rc2-3455"
            }
          },
          "netstandard1.3(unix)": {
            "dependencies": {
              "System.Security.Cryptography.OpenSsl": "4.1.0-rc2-3455",
              "System.Net.Http.CurlHandler": "4.1.0-rc2-3455"
            }
          }
        }
    }

    We would infer defines for the RID.

    public class Foo
    {
        public void Method()
        {
           #if WIN7
              // Do something windows specific
           #elif UNIX && NET451
              // Do something mono specific
           #elif UNIX
             // Do something unix specific
           #endif
        } 
    }
    

    Lock file changes

    {
        ...
        "targets": {
            "DNXCore,Version=v5.0": { },
            "DNXCore,Version=v5.0(win7)": { },
            "DNXCore,Version=v5.0(unix)": { },
            "DNXCore,Version=v5.0/win7-x86": { },
            "DNXCore,Version=v5.0/win7-x64": { }
        }
        ...
    }

    Notice the {tfm}({rid}) sections. These are new "compile time graphs".

    dotnet/nuget pack changes

    Foo.1.0.0.nupkg

        lib/
            netstandard1.3/
                Foo.dll
        runtimes/win7/lib/
            netstandard1.3/
                Foo.dll
        runtimes/unix/lib/
            netstandard1.3/
                Foo.dll
       Foo.nuspec
    

    Foo.nuspec

    <?xml version="1.0" encoding="utf-8"?>
    <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
      <metadata minClientVersion="3.4.0">
        <id>Foo</id>
        <version>1.0.0-beta-23504</version>
        <dependencies>
          <group targetFramework=".NETStandard1.3">
            <dependency id="System.Console" version="4.1.0-rc2-3455" />
          </group>
        </dependencies>
        <runtimeDependencies>
          <group targetFramework=".NETStandard1.3" targetRuntime="win7">
            <dependency id="System.Console" version="4.1.0-rc2-3455" />
            <dependency id="System.Security.Cryptography.Cng" version="4.1.0-rc2-3455" />
            <dependency id="System.Net.Http.WinHttpHandler" version="4.1.0-rc2-3455" />
          </group>
          <group targetFramework=".NETStandard1.3" targetRuntime="unix">
            <dependency id="System.Console" version="4.1.0-rc2-3455" />
            <dependency id="System.Security.Cryptography.OpenSsl" version="4.1.0-rc2-3455" />
            <dependency id="System.Net.Http.CurlHandler" version="4.1.0-rc2-3455" />
          </group>
        </runtimeDependencies>
      </metadata>
    </package>

    The sections DO NOT MERGE. During the runtime graph walk, one of the sections are chosen, just like the TFM graph walk today.

    Potential additions

    netstandard1.3(win7-x64, win8-x86)
    

    This would be a shortcut for supporting multiple runtimes (if dependencies were shared).

  7. ericstj commented on Jan 26, 2016

    @ericstj
    MemberAuthor

    What happens if a dependency like this only shows up in the runtime graph?
    Since runtime.jsons are only honored if the appear in the compile graph wouldn't the RID specific dependencies be ignored?

    Foo is a library that has a Unix and Win build. Unix build depends on Bar. Bar gets listed in Foo's runtime.json.
    Bar is a library that has a Linux and OSX build. Linux build depends on Baz. Baz gets listed in Bar's runtime.json.

    Foo is consumed by App that is not RID specific. The app's compile graph contains Foo so it gets Bar. The app's compile graph does not contain Bar, so it never gets Bar's runtime.json, and thus never gets Baz when deployed on Linux.

  8. davidfowl commented on Jan 27, 2016

    @davidfowl
    Member

    @ericstj We decided to put something in the nuspec. Updated the spec to respect this.

  9. ericstj commented on Jan 27, 2016

    @ericstj
    MemberAuthor

    LGTM. I'm guessing minClientVersion for this should be 3.4.0 or something.

    So when consuming this package

    • compiling anywhere only uses the <group targetFramework=".NETStandard1.3"> section
    • running on win7-x86 it would use the <group targetFramework=".NETStandard1.3" targetRuntime="win7"> section
    • running on win-x86 it would use the <group targetFramework=".NETStandard1.3"> section
    • running on ubuntu.14.04-x64 it'd use the <group targetFramework=".NETStandard1.3" targetRuntime="unix"> section
  10. davidfowl commented on Jan 27, 2016

    @davidfowl
    Member

    @ericstj
    We need to roll back the change to System.Security.Principal.Windows (WindowsPrincipal) and potentially the System.Windows.Registry until we have this feature because right now we (ASP.NET) are broken. https://github.com/dotnet/corefx/issues/5694

  11. davidfowl commented on Jan 27, 2016

    @davidfowl
    Member

    @ericstj That's correct.

  12. andyleejordan commented on Jan 27, 2016

    @andyleejordan
    Member

    I thought @anurse already had a spec for this.

    Specifically this section.

  13. davidfowl commented on Jan 27, 2016

    @davidfowl
    Member

    You can assume this supersedes that 😀

  14. analogrelay commented on Jan 27, 2016

    @analogrelay
    Contributor

    @andschwa That is not technically related, that is for configuration of corehost. It is derived from this data, but it a different spec.

  15. andyleejordan commented on Jun 20, 2016

    @andyleejordan
    Member

    @piotrpMSFT why won't this make it into RTM? It's still blocking us pretty badly. We have to use a LINUX configuration and preprocessor definitions to work-around this. It's ugly.

  16. removed their assignment
    on Feb 7, 2018
  17. transferred this issue fromdotnet/clion Jan 31, 2020
  18. added this to the Backlog milestone on Jan 31, 2020
  19. baronfel commented on Nov 28, 2023

    @baronfel
    Member

    NuGet packages support RID-specific assets now. Closing this as a result.

  20. PathogenDavid commented on Dec 10, 2023

    @PathogenDavid
    Contributor

    @baronfel This isn't about RID-specific assets, it's about RID-specific dependencies.

    Unless I missed something in .NET 8, I don't think the latter is supported.

    (That being said, maybe NuGet/Home#1660 or NuGet/Home#10571 is a better place to track this anyway?)

  21. baronfel commented on Dec 10, 2023

    @baronfel
    Member

    Ah, good call on both counts. NuGet will need to understand/define something structure for describing these, then probably the SDK's ResolvePackageAssets task will need updating to follow that structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions