Skip to content
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

Ship a .framework version of Mono #53370

Merged
merged 24 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3d876f7
WIP
akoeplinger May 17, 2021
ada980d
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex May 27, 2021
82555d5
Copy mono-framework.framework to same build dir as monosgen
directhex May 27, 2021
4879ec7
Copy .frameworks to bin/
directhex May 27, 2021
9e3bc17
Ship .framework in nupkg
directhex May 27, 2021
ff168f9
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex Jun 3, 2021
f97e186
Rename mono-framework to Mono
directhex Jun 3, 2021
0ee1330
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex Jun 29, 2021
7d8d578
Fix framework build on non-catalyst
directhex Jun 29, 2021
e97ec4c
Build stubby (release) and static-component (release) .frameworks
directhex Jun 30, 2021
f16eabb
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex Jun 30, 2021
75ea8d1
Strip frameworks
directhex Jun 30, 2021
9bd0b0e
What if we flatten to iOS-style unversioned frameworks on non-iOS?
directhex Jul 1, 2021
4ee0938
Fix stripping-dwarf-files bug
directhex Jul 2, 2021
45f4e2b
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex Jul 2, 2021
3315ef6
Merge branch 'ios-xcframework' of github.com:directhex/runtime into i…
directhex Jul 2, 2021
8f544ab
Bundle dylibs for components on dynamic component platforms
directhex Jul 2, 2021
db386ee
Only build .frameworks if explicitly turned on; turn on in relevant C…
directhex Jul 6, 2021
aa31a96
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex Jul 6, 2021
62ab8ae
Typo
directhex Jul 6, 2021
2837fcb
Fix casing (from Mitch)
directhex Jul 7, 2021
65e00a7
Add explanation of whitespace fiddling to bypass cmake list limitations
directhex Jul 7, 2021
29e9413
Release and debug were reversed (debug should get full objects, not s…
directhex Jul 7, 2021
bd8272e
Merge remote-tracking branch 'origin/main' into ios-xcframework
directhex Jul 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/liveBuilds.targets
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<IsNative>true</IsNative>
</RuntimeFiles>

<FrameworkFiles Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'" Include="$(MonoArtifactsPath)\mono-framework.framework\*.*" />
<MonoIncludeFiles Condition="'$(TargetsMobile)' == 'true'"
Include="$(MonoArtifactsPath)\include\**\*.*" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@
<TargetPath>runtimes/$(RuntimeIdentifier)/native/include/%(RecursiveDir)</TargetPath>
</RuntimeFiles>

<RuntimeFiles Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'"
Include="@(FrameworkFiles)"
ExcludeFromDataFiles="true">
<TargetPath>runtimes/$(RuntimeIdentifier)/native/mono-framework.framework/%(RecursiveDir)</TargetPath>
directhex marked this conversation as resolved.
Show resolved Hide resolved
</RuntimeFiles>

<CoreCLRCrossTargetFiles PackOnly="true" />
<CoreCLRCrossTargetFiles Condition="'%(FileName)' == 'clrjit' or '%(FileName)' == 'libclrjit'">
<TargetPath>runtimes/$(CoreCLRCrossTargetComponentDirName)_$(TargetArchitecture)/native</TargetPath>
Expand Down
6 changes: 6 additions & 0 deletions src/mono/mono.proj
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,12 @@
<Destination>$(RuntimeBinDir)cross\$(PackageRID)\opt$(ExeExt)</Destination>
</_MonoRuntimeArtifacts>
<_MonoIncludeArtifacts Include="$(MonoObjDir)out\include\**" />
<_MonoRuntimeArtifacts Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'" Include="$(MonoObjDir)out\lib\mono-framework.framework\mono-framework">
<Destination>$(RuntimeBinDir)\mono-framework.framework\mono-framework</Destination>
</_MonoRuntimeArtifacts>
<_MonoRuntimeArtifacts Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'" Include="$(MonoObjDir)out\lib\mono-framework.framework\Info.plist">
<Destination>$(RuntimeBinDir)\mono-framework.framework\Info.plist</Destination>
</_MonoRuntimeArtifacts>
<_MonoRuntimeArtifacts Condition="'$(_MonoIncludeInterpStaticFiles)' == 'true'" Include="$(MonoObjDir)out\lib\libmono-ee-interp.a">
<Destination>$(RuntimeBinDir)libmono-ee-interp.a</Destination>
</_MonoRuntimeArtifacts>
Expand Down
24 changes: 24 additions & 0 deletions src/mono/mono/mini/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,30 @@ if(NOT DISABLE_SHARED_LIBS)
add_library(monosgen-shared-dac SHARED "mini-windows-dlldac.c")
set_target_properties(monosgen-shared-dac PROPERTIES OUTPUT_NAME ${MONO_SHARED_LIB_NAME}-dac)
endif()


directhex marked this conversation as resolved.
Show resolved Hide resolved
if(TARGET_DARWIN)
add_library(mono-framework SHARED $<TARGET_OBJECTS:monosgen-objects>)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a conditional flag so its only built when building from mono.proj ?

target_compile_definitions(mono-framework PRIVATE -DMONO_DLL_EXPORT)
target_sources(mono-framework PRIVATE $<TARGET_OBJECTS:eglib_objects>)
target_link_libraries(mono-framework PRIVATE ${OS_LIBS} ${ICONV_LIB} ${LLVM_LIBS} ${ICU_LIBS})
if(ICU_LDFLAGS)
set_property(TARGET mono-framework APPEND_STRING PROPERTY LINK_FLAGS " ${ICU_LDFLAGS}")
endif()
if(STATIC_ICU)
set_property(TARGET mono-framework APPEND_STRING PROPERTY LINKER_LANGUAGE CXX)
endif ()
set_property(TARGET mono-framework APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-compatibility_version -Wl,2.0 -Wl,-current_version -Wl,2.0")
target_sources(mono-framework PRIVATE "${mono-components-objects}")
Copy link
Member

@lambdageek lambdageek May 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is going to be a mono framework for ios/tvos/catalyst that always statically links in the full non-stub versions of all the components. Is that what we want? We always want to support hot reload and diagnostics, @rolfbjarne ?

Or should each component be its own dynamic .framework, too? (in which case... it would be upto the xamarin-macios embedding code to hook mono_dl_open and locate the components for us)

Or maybe one mono.framework with all the components, and one with only stubs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statically links

I have not read the PR yet... but the goal of a .framework is that it's all dynamic (not static) linking

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea mono is built as a dynamic thing, but it will include all the components statically as part of it. I left some comments on the Paper.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a hard limit to the number of .frameworks an app can have?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We always want to support hot reload and diagnostics,

Debug

  • We do not care about the app bundle size [1]
    • IOW all features (including HR and diagnostics) can be available in the binary (and be enabled/disabled by the app if required)
  • We care about build and deploy times
    • dynamic linking (used for frameworks) makes the build faster
    • the framework (binary) will rarely change (deployed to sim/device once)

[1] unless it starts affecting build/deploy times :-)

Release

  • We care about the app bundle size
    • by default, we won't be using the .framework
      • using the static libraries .a allows the native linker / strip to remove a lot of code. Using the framework would create much larger apps.
    • a release .framework is needed for app extensions
      • why ? it's smaller to share a single, larger .framework than to have a (even partial) runtime in 2 (or more) executables - main app and one/several extension(s)
  • We do not care (within limits) about build times. Release builds being less common than debug ones
  • We do not care about deploy times. Since release build are smaller then generally deploy faster anyway.

I do not see "hot reload" needed for release builds. Not entirely sure about "diagnostics" ...

Modularity is more important for the static libraries. The majority of apps ships without extensions (but that could change).

Or should each component be its own dynamic .framework, too?

There's a limit (at least a suggested one, never seen a rejection) to the number of user frameworks that an app should have. However a framework can have several dynamic libraries inside it... so we could control what's in or out.

Not sure if that's really needed...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given there are quite a number of conditions and cases I wonder if it'd make more sense for Xamarin.iOS to create the .framework as part of the build when it is needed with just the right components? E.g. I've heard that we have some requirements to not ship the diagnostics TCP server code in release builds, even if it is not used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can create Mono.framework, but afaik we can't create the corresponding dSYM, that has to be done on the machine that compiled the object files.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done some work relating to debug symbol generation in #53240

dsyms for anything we generate and put in a nupkg should be available from the MS debug symbol service

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rolfbjarne we do have the dSYM's and can put them into the runtime pack (or the symbols nuget), would you mind trying if you can create the .framework based off of that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akoeplinger I created a very simple test case, and I was able to create a .framework and the corresponding .framework.dSYM from a .dylib and its corresponding .dylib.dSYM. I ran an executable that consumed the .framework in lldb, and lldb was able to symbolicate functions in the .framework. I wasn't able to make macOS' crash reporter symbolicate the framework functions though, so I'm not sure if the end result is actually correct, or if it just happens to work in lldb. One point is that Apple identifies .dSYM directories using a UUID (which shows up in the crash report), and if we create the .framework.dSYM from the .dylib.dSYM, those share the same UUID, and potentially things break.

set_target_properties(mono-framework PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION C
MACOSX_FRAMEWORK_IDENTIFIER net.dot.mono-framework
)
install(TARGETS mono-framework
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()
endif()

find_package(Python3 COMPONENTS Interpreter)
Expand Down