-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Adding a custom SDK resolver #2278
Comments
I would like to use this to make it easier to add support for other project types, like Rust. Ideally, a directory level configuration could point to a path containing an SDK. It'd work like directory.build.props where parent dirs are searched. I'd put that along the solution file. Also, there should be a way (NuGet?) to distribute sdks. The aforementioned config file could point to a NuGet package with an SDKs folder in it, then it'd be automatically downloaded and added to the search path. Then something like Visual Rust can package its targets as an SDK and distribute it on NuGet. |
@onovotny fyi there is an issue for a NuGet resolver at NuGet/Home#5220 |
@dasMulli Thanks for the pointer! My ask when designing this feature is that it's not tied to .NET. That is, it should ideally support any project type that uses CPS to enable it to have its own SDK. The example I'm thinking of right now is Rust, but it can apply to any other language/platform. |
Another example of the need for this: it's impossible to know of all possible installations of MSBuild. For example, OmniSharp (what powers VS Code) bundles the MSBuild runtime, which means the MSBuild folder and SdkResolver lookup path is |
I would very much like to define a repo-level SDK for some project types that are custom to our repo. If MSBuild would be willing to search for SDKs similar to how @onovotny described, that would be awesome. |
Would it be possible for MSBuildSDKsPath to behave like PATH in that you can have multiple paths to sdk folders (already on disk). MSBuildSDKsPath can be overridden by environment if I understood correctly |
After reading some more of the discussions, it might be good to mention that for us it makes sense if a source tree can actually contain their own SDK(s) in the actual tree. Having something like searching in the parent folders for an SDK config file would also help deployment on both developers and build machines, since they retrieve the source tree anyway. I guess the resolver API would allow one to write a vs extension that actually scans parent folders for an SDK config file, but when I install this as a VS extension, will it also work from command line msbuild? |
Would like to throw in my two cents, how I do the target resolution up to now:
That Smart.targets file is located in the root folder of a branch / workspace and redirects to other targets that belong to my build framework. From what I understood up to now, the SDK stuff is nothing else than two imports of a props and target file. So I think you could probably do something similar like I do or bake it directly into MSBuild as a default sdk resolver. The advantage is, whenever you want to change the build behavior for some projects under a specific folder you can simply throw a Smart.targets file in their parent folder and it will be automatically taken. Another advantage is of course that it doesn't matter where your projects are located, there is no relative path that needs to be updated. |
Auto-import of props/targets file already exists - The SDK feature is mostly about re-using shared logic so I don't think it will be common to add SDKs to a repo (but maybe if you have 3 different types of project and want 3 different imports..).
This is actually a good idea and could be used as quick-fix for problems like https://github.com/dotnet/cli/issues/6178 where some SDKs are only distributed in VS but you'll want the main SDKs to be loaded from the CLI folder and only fall back to a VS path. (current solution is to copy the SDK folder). Could also be |
@dasMulli wow, thanks for the hint regarding the auto-import. That will help me alot. Is that already working in VS 2015/MSBuild 14 or has it been introduced with VS 2017 / MSBuild 15 ? |
That feature is new in MSBuild 15 / VS 2017 |
This issue is causing periodic problems for Roslyn contributors. While the .NET SDK gets installed into the expected directory, Roslyn always relies on a particular version of the SDK for reasons that vary over time. We would like the ability to restore the SDK itself as part of our Restore.cmd script, and have that SDK get resolved automatically as part of both build and IDE scenarios. Leveraging this functionality will improve our ability to engage and retain external contributors by improving "pit of success" approach to development. Eventually we would like the complete restore process to happen inside Visual Studio (if/when necessary with minimal overhead), but until we reach that point a reasonable approach is Clone/Restore.cmd/Open solution. Until this feature is implemented, we are left with an unfortunate "manually installed things" step. |
An orthogonal issue for these dev scenarios is probably support for a relative path in |
Indeed. As the design stands now it's relatively easy to setup the command line build for a repo to "just work". Go up to dotnet/roslyn, clone run However the same is simply not true for the Visual Studio based experience. Open Roslyn.sln, Build and you're likely to be hit with an error message from our build The 2.2.0 SDK is required to build this repo. It can be install here https://dotnetcli.blob.core.windows.net/dotnet/Sdk/2.2.0-preview1-007622/dotnet-sdk-2.2.0-preview1-007622-win-x64.exe That's really unfortunate and frankly confusing to our users. Why is building from the command line possible when building from Visual Studio fails?
Indeed. Worse is that it requires installing as "admin". Outside the initial VS install it shouldn't be necessary to use admin to build any repo. It's generally a sign that we need to be more easily extensible. |
An SDK resolver that activates only when a user has specified a version. This resolver is ordered to come before the DotNetSdkResolver but if a user does not specify a version (the default), then the NuGet SDK resolver is skipped. The NuGet SDK resolver can be disabled with an environment variable just in case its causing issues or a user wants to override its functionality. NuGet assemblies are loaded at runtime from their installed location. They either come come [VisualStudioInstallRoot\Common7\IDE\CommonExtensions\Microsoft\NuGet or next to MSBuild.exe. There is also an environment variable that can be set to specify a folder to use instead. I've also placed references to NuGet into private subclasses so that assemblies are not loaded unless they are needed. This means that if you have no version specified and no `global.json` with versions, `Newtonsoft.Json` and `NuGet.*.dll` are not loaded. You only pay JIT penalty if you're using the functionality and hopefully we'll make up that time later in the build through caching. Addresses item 6 in #2803 Related to #2278
Problem
The default SDK resolver loading only looks for resolvers in $(MSBuildToolsDirectory32)/SdkResolvers (source).
Most of the time, this path is going to be
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\SdkResolvers
. Writing files here requires admin permissions.My scenario: I'm looking for a way to share a common set of targets and props across ASP.NET Core's 500+ csproj files, which are scattered among repos. We've tried PackageReference, but continually run into limitations. I've written and tested a custom SDK resolvers. It seems promising, but there is no easy way to make this available for MSBuild for VS and dotnet.exe without getting elevated permissions to write into the VS folder and/or
C:\Program Files\dotnet
folder.Request
Provide a way to register custom SDK resolvers without needing to write into the MSBuild tools folder.
Ideas
<UsingTask>
, add<UsingSdkResolver>
directive that takes an assembly path.The text was updated successfully, but these errors were encountered: