dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.47k stars 4.77k forks source link

Passing of linker flags in the runtime NuGet packs #52603

Open filipnavara opened 3 years ago

filipnavara commented 3 years ago

Follow up to https://github.com/dotnet/runtime/issues/41299, https://github.com/dotnet/runtime/issues/52482#issuecomment-838290365, https://github.com/dotnet/runtime/issues/52482#issuecomment-838596561

Xamarin consumes the .NET static native libraries (System.Native, System.Security.Cryptography.Native.Apple, Mono runtime, etc.) through NuGet packages. For the iOS/tvOS scenarios Xamarin links the static libraries from the pack into the final executable. In some cases additional linker flags may need to be specified to the final linking command to ensure all the libraries are linked properly.

The current situation on the Xamarin side is that it hard-codes some of the linker flags. Frameworks seem to be imported thanks to references from the managed bindings and finally the rest works through the auto-link magic.

On single-file host scenarios on the dotnet/runtime side extra_libs.cmake files are sprinkled around the repository that do the linker flag resolution and plug into the single-file pipeline.

I'd like some feedback from the stakeholders whether there is some solution to improve the status quo. For example, if we could produce a linker response file (.rsp) with the necessary linker flags as part of the dotnet/runtime static library builds. The response files could be consumed by the single file host instead of the extra_libs.cmake files, shipped in the runtime NuGets and also consumed as part of the MSBuild pipeline on the Xamarin side.

cc @VSadov @rolfbjarne @jkoritzinsky @AaronRobinsonMSFT @grendello @akoeplinger

dotnet-issue-labeler[bot] commented 3 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

VSadov commented 3 years ago

The purpose of extra_libs.cmake is to have requirements of a particular library in one place - so that anything that builds or statically links the library could just include a corresponding extra_libs.cmake file.

I am not familiar enough with .rsp to tell if it is expressive enough to replace extra_libs.cmake. If response file could serve the same purpose and used in more scenarios, like in NuGets, it could be a better option.

filipnavara commented 3 years ago

The problem with extra_libs.cmake is two-fold. First, it requires CMake and possibly may even use some CoreCLR specific functions from other included CMake files. Second, it's not shipped along with the static libraries.

The .rsp files were merely an example suggestion of something that would be easily consumable by both CMake and MSBuild. It's just a file with linker parameters, no additional build time logic. I am not sure if there is something that needs to be explicitly dynamic (in case of replacing extra_libs.cmake it would not be a big deal since both the consumer and producer run on the same machine within the same pipeline; it would be problem for the NuGets though).

Alternative approach could be leaving pretty much everything as-is on the dotnet/runtime side but produce a .props files in the runtime NuGet that sets MSBuild property/item group with linker flags in a variable recognizable by Xamarin.

VSadov commented 3 years ago

The reason why these are cmake-specific is purely historical. Every .NET native library has a set or requirements - build time dependencies, headers, linker settings. We used to have them hardcoded in the libraries cmake files. When we started also linking the libraries into the host, we realized that now we would need to hardcode in two places and, who knows, maybe in more places later. So the parts that deal with dependencies and requirements were factored out.

It might not be the only solution and not even the best solution. It just happen to work. I would be open to alternatives.

filipnavara commented 3 years ago

So the parts that deal with dependencies and requirements were factored out.

That's totally sensible and I am really happy that it was done. I am just pointing out that Xamarin is a third place where these things are hard-coded at the moment (or work by sheer luck) and that it would be nice to find a solution where that hard-coding is removed. I'm not exactly sure what the best solution would be though.

Maybe it makes sense to state the requirements first?