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

How is the Freetype native binary installed on iOS? #102

Open
corliss opened this issue Mar 22, 2017 · 16 comments
Open

How is the Freetype native binary installed on iOS? #102

corliss opened this issue Mar 22, 2017 · 16 comments

Comments

@corliss
Copy link
Contributor

corliss commented Mar 22, 2017

How is the iOS Freetype binary located and installed? The p/invoke code previously used the path "__Internal", which I removed as part of the Portable unification checkin. But I wasn't able to locate a binary with that name either in this repo or in the Dependencies repo. So where did that come from?

We should also add support for

  • Mac
  • UWP
  • Android

The SharpFont PCL will suffice, together with per-platform native freetype binaries. A single nuspec can handle this, I think, by having the correct binaries in the correct subfolders of lib.

@corliss corliss changed the title How are the binary dependencies installed for non-Windows? How is the Freetype binary dependencies installed on iOS? Mar 22, 2017
@corliss corliss changed the title How is the Freetype binary dependencies installed on iOS? How is the Freetype native binary installed on iOS? Mar 22, 2017
@Robmaister
Copy link
Owner

Based on this link it appears as though __Internal means that it's packed into the binary which is also hosting the instance of Mono running that C# code. I believe that on iOS you're only allowed to distribute a single binary file, hence this magic string.

This StackOverflow question states that modifying the .dll.config should work, though no one was able to confirm.

I don't have an iPhone or the toolchain setup to see if this works, but I could try and see if anyone I know would be willing to run some test code for me. @manu-silicon wrote the original changes, so perhaps he has the capacity to test such a change?

The original change, #80, is supposed to work for UWP and Android as well, though perhaps it wasn't declared in the profile selected for PCL. Mac has been supported for a very long time, SharpFont.dll.config has a dllmap to a .dylib in OS X, and OpenRA currently ships with it on OS X.

@corliss
Copy link
Contributor Author

corliss commented Mar 22, 2017

it appears as though __Internal means that it's packed into the binary which is also hosting the instance of Mono running that C# code.

What causes it to be packed into the binary, since neither SharpFont nor SharpFont.Dependencies do anything to make that happen?

@corliss
Copy link
Contributor Author

corliss commented Mar 22, 2017

The original change, #80, is supposed to work for UWP and Android as well, though perhaps it wasn't declared in the profile selected for PCL. Mac has been supported for a very long time.

I think I'm starting to understand, but still some open questions. So here's a list of all supported platforms, with my understanding of how this works:

  • Windows: It appears that SharpFont.Dependencies copies the x64 or x86 version of freetype6.dll to the bin directory. The relevant line of SharpFont.Dependencies.props is:
    <Content Include="$(MSBuildThisFileDirectory)..\bin\msvc10\$(PlatformName)\freetype6.dll">

  • Linux & FreeBSD: SharpFont.dll.config has these lines, but how is libfreetype.so.6 installed? Or do we assume that it is preinstalled with the OS?

<dllmap dll="freetype6" os="linux" target="libfreetype.so.6" />
<dllmap dll="freetype6" os="freebsd" target="libfreetype.so.6" />
  • UWP: Can't find any code related to UWP.
  • Android: Can't find any code related to Android
  • iOS: We need to add a line mapping freetype6 to __Internal for iOS, but even after that, how is the freetype binary included with the app?

@Robmaister
Copy link
Owner

Windows: It appears that SharpFont.Dependencies copies the x64 or x86 version of freetype6.dll to the bin directory. The relevant line of SharpFont.Dependencies.props is:

Yep. If you're publishing your own software that is more complex, you might also distribute both versions of the dll and do a runtime selection based on the host architecture. Or select a different version of MSVC that you choose to depend on instead.

Linux & FreeBSD: SharpFont.dll.config has these lines, but how is libfreetype.so.6 installed? Or do we assume that it is preinstalled with the OS?

Downstreams will typically publish a package on a package manager, and will mark freetype as a dependency to be installed before that package will be installed. So basically yes, assume that it is installed, or enforce installation prior to running the program/game

UWP: Can't find any code related to UWP.

It should "just work" as long as the dll is included in the app package. Some MSBuild work might be handy to automate this if the <Content> tag in the .props file isn't enough.

Android: Can't find any code related to Android

Will also just work. If the dllmap to linux doesn't resolve, Mono will search for variants of the existing dll name, and I believe some version of FreeType ships with Android.

iOS: We need to add a line mapping freetype6 to __Internal for iOS, but even after that, how is the freetype binary included with the app?

I'm not 100% on the details here, but as I understand it, everything is packaged into one native binary by Xamarin. The native portion of the app essentially just bootstraps a Mono environment and hosts your C# assembly that's embedded in the binary. All your other native dependencies are supposed to be statically linked into this same binary. Mono uses the magic string "__Internal" to mean "the binary that's executing this code", since that's the one binary you're allowed to have at all.

Depending on the details, a .dll.config might not actually be included here at all, ,making this solution impossible or just really hard. I think we'll need someone with the right environment to test some of this stuff for us eventually. I'm all about killing off the iOS specific package, so if there's some way to intercept DllImports and use your iOS detection function, then that will be our backup to the .dll.config change

@corliss
Copy link
Contributor Author

corliss commented Mar 22, 2017

More questions :)

  • UWP: So the desktop binaries are used here? That doesn't make sense, because UWP has different file APIs, and supports other processors such as ARM.
  • iOS: I understand about the Mono environment, but how does it know about FreeType at all? Or is FreeType always included for all apps by Mono/Xamarin? (BTW I can test the iOS change in a day or two.)

@HinTak
Copy link
Contributor

HinTak commented Mar 22, 2017

Sigh. You guys have absolutely no idea about how Mono works.

Mono implements gdiplus, which Mono's implementation of System.Drawing and System.Windows.Forms depends on, via a whole bunch of libraries, one of which is freetype. This is on non-windows. On windows, mono uses the native microsoft's gdiplus so mono does not depends on freetype through gdiplus; but gtk# depends on gtk and gtk depends on cairo which in turn depends on freetype.

So anything that has a GUI with mono basically can assume freetype is present, except mono on windows with winforms.

@HinTak
Copy link
Contributor

HinTak commented Mar 22, 2017

You are right, Xamarin.Mac does not need or ship freetype.

You want to know whether freetype can be assumed to be around, I gave you the answer: gtk# on all platforms and winforms on non-windows.

@HinTak
Copy link
Contributor

HinTak commented Mar 22, 2017

FWIW, mono is not a variant of microsoft CLR, although microsoft now owns xamarin. There are distinct differences (and different bugs) between mono's implemention of various CLR libraries vs Microsoft's.

@HinTak
Copy link
Contributor

HinTak commented Mar 22, 2017

? Xamarin uses microsoft CLR? The last time I checked (around Christmas?) , netcore was still essentially windows only...

@Robmaister
Copy link
Owner

UWP: So the desktop binaries are used here? That doesn't make sense, because UWP has different file APIs, and supports other processors such as ARM.

Yup, freetype makes little use of CRT/Win32 calls. The most would be opening a file to read it's contents. If that doesn't work because of the sandboxing, there's a Face constructor that accepts a byte array.

For ARM, it looks like the solution is to simply build an ARM version of freetype and use that, like how OpenCV does it among others: https://blogs.msdn.microsoft.com/lucian/2015/11/27/opencv-building-uwp-binaries/

iOS: I understand about the Mono environment, but how does it know about FreeType at all? Or is FreeType always included for all apps by Mono/Xamarin?

Part of the build process for a Xamarin app is to statically link freetype into the final binary, and you'd have to build freetype yourself for that currently.

I suppose UWP ARM and iOS builds of freetype would be helpful in this case

@corliss
Copy link
Contributor Author

corliss commented Mar 22, 2017

This is where I wish github markdown supported tables :)

Can we agree on this goal: the user only needs to include the SharpFont and SharpFont.Dependencies nuget, and never has to worry about native binaries. That is, the nugets take care of installing them if needed. Given that, here's a summary so far:

  • Windows: x64 and x86 builds supported
  • UWP: x64 and x86: Same builds as desktop. Issues with files. (Note: a byte array is sub-optimal when dealing with lots of fonts - fonts can get quite large. I believe that Freetype uses memory mapped files when that option is available.) TODO: ARM
  • Linux/BSD: preinstalled on the system
  • Android: preinstalled. Need to test this (or has this been tested already?)
  • Mac: Already supported, uses the freetype that is preinstalled in the OS.
  • iOS: May need an entry in SharpFont.dll.config. Need to test whether iOS has a preinstalled freetype binary, if not will need to ship one.

All told, that is quite a lot of work. But we'll get there. :) And along with that - HarfBuzz!

@corliss
Copy link
Contributor Author

corliss commented Mar 22, 2017

FYI I will open separate issues for each platform, intended to be closed only when each platform is fully verified.

@Robmaister
Copy link
Owner

@HinTak

Sigh. You guys have absolutely no idea about how Mono works.

Chill with the condescending tone, please. No, we don't all know everything about Mono, but I'd like to at least keep the discussions constructive.

Mono implements gdiplus, which Mono's implementation of System.Drawing and System.Windows.Forms depends on, via a whole bunch of libraries, one of which is freetype. This is on non-windows. On windows, mono uses the native microsoft's gdiplus so mono does not depends on freetype through gdiplus; but gtk# depends on gtk and gtk depends on cairo which in turn depends on freetype.

You want to know whether freetype can be assumed to be around, I gave you the answer: gtk# on all platforms and winforms on non-windows.

Not all distributions of Mono have to include libgdiplus or cairo. One example would be Unity3D.

FWIW, mono is not a variant of microsoft CLR, although microsoft now owns xamarin. There are distinct differences (and different bugs) between mono's implemention of various CLR libraries vs Microsoft's.

Yup, it's a rewrite of the runtime back when the CLR was only "open" in that the spec was published as an ECMA and ISO standard and everything else was closed source. I'm aware that they are separate runtimes.

? Xamarin uses microsoft CLR? The last time I checked (around Christmas?) , netcore was still essentially windows only...

That's not what I said, Mono can be embedded into a native executable and I believe this was what Xamarin did in order to bypass restrictions on iOS apps. Unity3D does this as well, which is how C# scripts can be hosted inside their C++ engine.

.NET Core SDK is currently available for Windows, OS X, and Linux as well: https://www.microsoft.com/net/download/core

If you are running on Linux or OS X, though, SharpFont won't work as they're still trying to figure out DLL mapping: https://github.com/dotnet/coreclr/issues/930

@Robmaister
Copy link
Owner

@corliss

Can we agree on this goal: the user only needs to include the SharpFont and SharpFont.Dependencies nuget, and never has to worry about native binaries. That is, the nugets take care of installing them if needed. Given that, here's a summary so far:

Yes, this should be the goal.

  • UWP: x64 and x86: Same builds as desktop. Issues with files. (Note: a byte array is sub-optimal when dealing with lots of fonts - fonts can get quite large. I believe that Freetype uses memory mapped files when that option is available.) TODO: ARM

I believe FreeType also has a system of loading fonts from a file stream, haven't taken the time to look into the feasibility of making that interop properly with C# streams.

  • Android: preinstalled. Need to test this (or has this been tested already?)

Definitely still needs a test, hopefully it's just hanging around /usr/lib or something.

  • Mac: Already supported, uses the freetype that is preinstalled in the OS.

I misspoke/forgot - only older versions of OS X distributed freetype.6.dylib, so now we depend on the copy distributed with the default Mono package. /Library/Frameworks/Mono.framework/Libraries/libfreetype.6.dylib

  • iOS: May need an entry in SharpFont.dll.config. Need to test whether iOS has a preinstalled freetype binary, if not will need to ship one.

Be prepared for a mapping to __Internal to not work, we may have to bring back SharpFont.iOS for now with just the single #define to change the DLL path, or find some crazy hack around it.

@corliss
Copy link
Contributor Author

corliss commented Mar 22, 2017

Be prepared for a mapping to __Internal to not work, we may have to bring back SharpFont.iOS for now with just the single #define to change the DLL path, or find some crazy hack around it.

In that case, is it possible to get help re: iOS? Just in terms of understanding where it currently finds the library. There are many threads on the internet of people wanting to build FreeType for iOS, which leads me to believe that it does not come preinstalled on the system.

@Robmaister
Copy link
Owner

Yeah, it's not pre-installed as far as I know, the user must download, build, and link it themselves. I tried to explain this earlier, probably a bit poorly:

Part of the build process for a Xamarin app is to statically link freetype into the final binary, and you'd have to build freetype yourself for that currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants