Cheating Miguel?

One day Miguel…
(No, wait — the story isn’t really about him. Let me try again.)
Once upon a time in the world of Open Source…
(Also off the mark; OSS only comes into it partway.)
When greed gets called common sense, the deception has already started.
(Almost an aphorism.)
Backstory
It got into my head to write a Mac program in C#. I thanked Miguel de Icaza for the excellent Open Source project Mono, praised him again for his MonoMac library, grumbled a little at the somewhat raw MonoDevelop, and got to work. In due course I paid for an App Store account, and the program was a step away from finished when a big project at my day job started and it had to be put aside. A year later a message arrived saying my idle App Store account would be closed in 30 days — a sign that I ought to do something. MonoDevelop, having updated itself into Xamarin Studio, promptly offered to convert the MonoMac project to Xamarin.Mac and led me off to a page where I was invited to buy that very Xamarin.Mac for a mere $999, without which deployment to the App Store would be impossible.
To be honest, I was rather taken aback. Having started hobby development in a free product, paying a thousand dollars for the privilege of publishing was the last thing on my mind, even if I was hoping to earn beer money. More than that, I vaguely remembered posts and success stories on StackOverflow about publishing to the store, about some packager and so on. But every checkbox I needed in Xamarin Studio was firmly disabled and demanded the full version of the product. That was when I understood that somewhere along the way I had been deceived — or, in modern phrasing, that the product’s distribution strategy had been changed so that publishing to the store became a premium paid service.
Everyone Is Within Their Rights
Looking at the relationship between me and Xamarin, in the person of Miguel, nobody deceived anybody — a developer is entitled to do whatever they like with their own product, all the more so to change licences or offer premium services for money. In the case of Xamarin.Mac that service is static linking against the Mono libraries, after which the program stops depending on the Mono Runtime and can run on any machine. The project also gets signed with the right certificates, supplied with Entitlements, sandboxing settings and the rest of what App Store publication requires:
As of December 12th 2012, Xamarin now offers a superset of MonoMac called Xamarin.Mac. It features broader API coverage, a commercial license for Mono’s LGPL components, Mono embedding, license to publish to the Mac AppStore and support.
The Mono Runtime itself is distributed under the GNU Library GPL 2.0, under which the question of static linking remains fairly contentious. Setting the tangle of terminology aside: when shipping a proprietary product linked against an LGPL library, the developer must also make it possible to swap that LGPL library for a different version. Usually that means shipping source code alongside the program, or using a different licence. Xamarin’s own site takes the same view:
Or if you ship an application that requires to statically link the Mono runtime and you are not able to provide the object code to relink Mono, you must obtain a commercial license from Xamarin.
The Deception
Deceiving anyone was the last thing I wanted, least of all a man as respected as Miguel de Icaza — author of Gnome and Mono, founder of Xamarin and Ximian. But by and large I am convinced that his marketing people, in making the product paid (and to my mind exorbitantly paid), had already deceived me, hiding behind the letter of the law while violating its spirit. So I reserved the same right for myself: formally breaking nothing, but ending up publishing my program on the App Store built with the free toolchain. Among other things the program contains an .exe file with .NET bytecode and the necessary libraries, which can be executed by a current .NET Framework and Mono Runtime, and which is entirely sufficient for static linking against the Mono libraries, AOT compilation, or anything else. The LGPL does not oblige me to write the end user a manual explaining how to do that (never mind that I don’t know how myself) — only to provide everything needed for it.

Technical Details
My MonoDevelop had updated itself into Xamarin Studio, where building .pkg packages is now blocked. The instructions for creating packages had also vanished from the MonoMacPackager page, replaced by links to Xamarin.Mac. Annoying, but not fatal — archives and older versions of the product do exist in the wild. I downloaded MonoDevelop 3.0.6, adapted the project for it (one incompatible API call had to go), selected “Link All” and… never did manage to compile the thing properly. Truth be told I never worked out why: the packager simply refuses to work with different versions of the Mono Runtime, throws a linker error and gets no further. Even so, choosing “Don’t link” does produce a working project. It comes out about 8 MB larger but runs without any real trouble. In that mode the full System.*.dll assemblies are included rather than just their metadata, as they would be under “Link All”. In my case that is actually a plus, because the same rule applies to the project’s main .exe — all of the bytecode stays in it.
The installer produced this way launches perfectly and installs the product, but then the program refuses to start. Digging through Google and the system log showed that MonoDevelop bakes the wrong Entitlements into the program — keychain-access-groups, which are incompatible with OS 10.8 and possibly not valid at all. Xamarin.Mac solves this, but I had taken the thorny road, so solving it was on me too. In the end I settled on a post-build script that applies the correct data to the bundle and re-signs it.
The build went off to the App Store and came straight back with complaints about other Entitlements problems, a missing signature on libMonoPosixHelper.dylib, and, for good measure, disallowed use of shared memory. The first was fixed with more edits to the plist, the second by extending the post-build script, but the third had me stumped. There was information about it on Stackoverflow, which said it had already been fixed and that in any case it was solved by setting the MONO_DISABLE_SHARED_AREA environment variable. The variable idea is sound enough, except it needs setting not at compile time but at run time, on the customer’s machine. I don’t know how Xamarin.Mac handles it; I settled on adding a key to info.plist that sets the variable when the program starts:
<key>LSEnvironment</key>
<dict>
<key>MONO_DISABLE_SHARED_AREA</key>
<string>1</string>
</dict>
That turned out to be enough, though the program did get bounced back one more time over an incorrect name in the window title bar.

Epilogue
The program is on the store now and honestly earns its $1.40 a day. If nothing changes, in 713 days I will be able to buy the full version of Xamarin.Mac, not counting the App Store fee itself. I wrote to Miguel on Twitter about the situation but got no reply. To someone else asking the same question he replied along the lines of “go ahead and use it”, but better buy Xamarin.Mac.

Meanwhile the Xamarin support people got back to me: as a long-standing Xamarin.iOS customer and a current student I can buy the product for just $99. That is a good offer and I will very likely take it, even if I don’t entirely share the company’s position.
P.S. To everyone about to comment along the lines of “nasty pirate takes money from a respected man” — save your nerves and don’t add to the entropy of the world’s networks.
Originally published on Habr, 2014-03-29.
