Bug 27206 - Unified API migration tool incorrectly updates the target framework on XamMac projects
Summary: Unified API migration tool incorrectly updates the target framework on XamMac...
Alias: None
Product: Xamarin.Mac
Classification: Desktop
Component: Other ()
Version: 1.12.0
Hardware: PC Mac OS
: Normal normal
Target Milestone: ---
Assignee: Chris Hamons
Depends on:
Reported: 2015-02-19 04:21 UTC by Prashant Cholachagudda
Modified: 2015-05-13 16:01 UTC (History)
4 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Prashant Cholachagudda 2015-02-19 04:21:39 UTC
Converting a XamMac application to the Unified API. The conversion tool changes the .csproj file framework version from 4.5 to 2.0.

Here are the lines from .csproj that changed after the conversion:

Version information:

=== Xamarin Studio ===

Version 5.7.1 (build 17)
Installation UUID: ed6755aa-af00-4433-85c5-a4c5d023bc00
Mono 3.12.0 ((detached/de2f33f)
GTK+ 2.24.23 (Raleigh theme)

Package version: 312000076

=== Apple Developer Tools ===

Xcode 6.1.1 (6611)
Build 6A2008a

=== Xamarin.iOS ===

Not Installed

=== Xamarin.Android ===

Not Installed

=== Xamarin.Mac ===

Version: (Business Edition)

=== Build Information ===

Release ID: 507010017
Git revision: 0bc7d3550b6b088ac25b08dcf7bbe73bcc8658b3
Build date: 2015-02-03 19:43:29-05
Xamarin addins: f7b7d34419c9ec24501bfa7c658e80a6305613e0

=== Operating System ===

Mac OS X 10.10.2
Darwin myellocos-MacBook-Air.local 14.1.0 Darwin Kernel Version 14.1.0
Mon Dec 22 23:10:38 PST 2014
root:xnu-2782.10.72~2/RELEASE_X86_64 x86_64
Comment 1 Sadik Ali 2015-02-19 05:18:01 UTC
I have checked this issue and able to reproduce this behaviour. When I convert XamMac classic application to unified API then the conversion tool changes the framework version from 4.5 to 2.0 in .csproj file.

Ide Logs:https://gist.github.com/saurabh360/e5894efefa108d95a84a

Environment Info:

=== Xamarin Studio ===

Version 5.7.2 (build 1)
Installation UUID: 2939b8b4-8977-42bd-82d6-100275ccd9cd
	Mono 3.12.0 ((detached/de2f33f)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 312000076

=== Xamarin.Android ===

Version: (Enterprise Edition)
Android SDK: /Users/360_macmini/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		1.6   (API level 4)
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.1   (API level 16)
		4.2   (API level 17)
		4.3   (API level 18)
		4.4   (API level 19)
		5.0   (API level 21)
Java SDK: /usr
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

=== Apple Developer Tools ===

Xcode 6.1 (6602)
Build 6A1052c

=== Xamarin.iOS ===

Version: (Enterprise Edition)
Hash: 4f70ac2
Build date: 2015-02-13 19:12:24-0500

=== Xamarin.Mac ===

Version: (Enterprise Edition)

=== Build Information ===

Release ID: 507020001
Git revision: 103486e2547553077836a5ba20a973487b983830
Build date: 2015-02-13 11:56:36-05
Xamarin addins: 8dd5b934e86ef0595c022dd3930fd40e3376ab4c

=== Operating System ===

Mac OS X 10.9.4
Darwin 360-MACMINIs-Mac-mini-2.local 13.3.0 Darwin Kernel Version 13.3.0
    Tue Jun  3 21:27:35 PDT 2014
    root:xnu-2422.110.17~1/RELEASE_X86_64 x86_64
Comment 2 Chris Hamons 2015-02-19 08:49:58 UTC
This is actually correct behavior. Let me explain.

By default, Unified projects use the Mobile profile, which is a subset of .NET similar to what iOS uses. This really doesn't have a  name, so we use a xamarin 2.0 to point to this.

When you move to Unified, you'll have to move all of your dependent assemblies to either PCL or Xamarin.Mac Libraries to reference this same BCL (Base Class Library) subset.

If you really, truly need to stay with the "full" BCL profile, we do have an option to do that (unsupported). In your project preferences, under general you can pick a different target framework for Unified.
Comment 3 Michael Teper 2015-02-19 08:58:00 UTC
Chris, why is this unsupported? It is unreasonable for a desktop app to be limited to Xam.Mac & PCL. A number of NuGet packages we depend on are not PCL. I am faced with a number of really bad choices here:

- stay with Classic, which based on my recent experiences is getting no love or bug fixes
- figure out a way to go 100% PCL (given dependencies, not going to be easy)
- move dependent projects to Xam.Mac, meaning I can no longer share code with Windows, which was the entire purpose of selecting Xamarin in the first place
- move to an unsupported configuration, which, again, given my recent experiences, I am not willing to do (and certainly not given the amount of money we are paying Xamarin for support)
Comment 4 Michael Teper 2015-02-19 08:59:23 UTC
This is *not* resolved, please reopen.
Comment 5 Miguel de Icaza [MSFT] 2015-02-19 09:25:35 UTC
Clarifications: Classic is a supported platform.  

Classic and Unified are produced from the same codebase.   There is no setup where a bug is only fixed in one, but not fixed in the other [1].   We do not expect all of our customers to move to the Unified API on Mac.   There is just too much code out there and without a clear mandate from Apple to drop 32-bit only APIs nobody is in a rush to do that.

In general, while Mono has tried to match the .NET API, it is not guaranteed that everything in .NET is present, which means that you should never reuse existing binary libraries in Mono products.   You should make sure that the libraries are compiled by our compiler, with our reference assemblies.   This ensures that everything that you are calling is correct, and that any implicit conversions are performed in a way that would work with our published API or that missing APIs are reported at compile time, as opposed to runtime.

The above means that you should be able to move from Classic to Unified by having your projects recompiled with the lighter assemblies.

Our purpose to limit the assembly profile with Unified is to ensure that we can deliver bug fixes for everything that we ship.  Sadly, the full profile that comes from the Mono project has code that is either not maintained, has no plans on being updated or will plainly not work on Unix.   Our choice of limiting the API in Unified is intended to be a clear statement of which parts we are able to actively maintain and fix.

[1] Caveat: when we were fixing old and deprecated APIs we had to take extra steps to support both the old name and a new name in Unified.
Comment 6 Michael Teper 2015-02-19 10:12:28 UTC
Good morning, Miguel, thanks for jumping in.

While there has been no official announcement on the fate of the Classic API, comments like the one in this bug definitely point in a particular direction: https://bugzilla.xamarin.com/show_bug.cgi?id=10204.

Unless I am misreading the roadmap, all the new OS X API are only coming to Unified, because they are x64: http://developer.xamarin.com/releases/mac/roadmap/.

So for me, if I am interested in evolving my OS X application and keeping up with the latest and greatest from Apple, Unified is the only way to go.

You say, "... which means that you should never reuse existing binary libraries in Mono products...". While I understand your rationale, that statement runs counter to the promise of .NET and ultimately makes Xamarin a far less appealing platform. Building for Mono on Windows is a pain, and building for Xamarin.* for OSS projects is prohibitively expensive and complex on top of that. I am not going to tell you how to run your company, certainly, but as a sample size of one, I can tell you that I was (a) surprised to hear this from you and (b) it makes me question what I've gotten my company into by choosing Xamarin. It certainly wasn't in my plan to take on the task of recompiling and supporting every OSS project we use via NuGet to Mono. And if I won't, who will? Back to my earlier point, it's not exactly trivial. And on the subject of NuGet, what is the point of including NuGet support in XS if the vast majority (nearly all) of libraries should not be used?

I still don't see a good path forward, long term. Am I missing something in the four bad choices I've outlined in my earlier comment?
Comment 7 Miguel de Icaza [MSFT] 2015-02-19 11:11:32 UTC
Hello Michal,

Those are cases where we have to go out of our way to actually only fix the bug in one side of the house and not the other.   It is actually more work on our end to do that.

The change will break semantics in Classic, so we chose not do to it there.    This means that existing developers, when recompiling wont find nasty surprises when they had assumed that previous QA on the product would render the same results.

Unified gave us the opportunity to fix some design mistakes.   Since the code was not source code compatible, developers had to test that their application would work.   Hence the liberty in Unified.

You are correct that 64-bit APIs are only available in Unified, as it is not possible to surface those on Classic.  

Perhaps you can share the list of NuGets that you are using and we can provide some guidance on what is the best approach to take here.
Comment 8 Michael Teper 2015-02-19 11:39:32 UTC
We use the following, as of this morning:

Reactive Extensions

As you can see, we lean pretty heavily on the NuGet ecosystem, and would like to continue doing so in the future. Adding Xamarin Support into the decision flow (i.e. asking you whether a given package would be OK for us to use) would not be ideal for us, and probably not for you either.

As a minor UX side note, when XS shows an (X) next to my referenced library projects in the converted Unified project and says they are not compatible, it would be more helpful if it stated that to make them compatible, the projects have to be either PCL or Xamarin.Mac Unified.

Lastly, another reason a move to Unified is not currently possible for us is debated here: https://bugzilla.xamarin.com/show_bug.cgi?id=26517.
Comment 9 Miguel de Icaza [MSFT] 2015-02-19 14:22:30 UTC
Thanks for the list.

We are discussing our policy, we might have to change it.   Will keep you posted.
Comment 10 Michael Teper 2015-02-19 15:33:48 UTC
Thanks, Miguel!
Comment 11 Chris Hamons 2015-02-25 11:59:14 UTC
I just wanted to update you and let you know that we didn't forget you.

You won't see any changes in the upcoming 1.12 (which has been in alpha/beta for months now), but we are looking at possible changes in 2.0 (mid-year) that might help address this. Nothing we can share yet though.
Comment 12 Michael Teper 2015-02-25 13:51:02 UTC
Thanks for the update, Chris, I appreciate it. This means we are effectively blocked from using Unified until issues debated here are resolved. If that proves to be problematic for us before then, I'll reach out through Support.
Comment 13 Miguel de Icaza [MSFT] 2015-02-25 14:16:52 UTC

Let me complement the answer above.

What we intent to do is streamline what is already available, and better scope out what is and what is not supported and how.

What this means is that *today* you can configure your Unified project to use "Unsupported .NET 4.5 assemblies" and do the following changes:

1. Ensure that linking is not used (since linking does not work well in the world of .NET 4.5 full profiles)

2. Your executables will grow in size

3. Ensure that you only use assemblies that are supported in our list of supported assemblies (Mono ships with more assemblies that we support).

So you can effectively get this today.  What we are doing is add UI that will offer a "Supported .NET 4.5" which basically enforces points 2 and 3 and will default to do what I said in 1.
Comment 14 Michael Teper 2015-02-25 15:46:57 UTC
Ah, I see. Could you point me to the list of supported assemblies?
Comment 15 Michael Teper 2015-02-25 15:47:45 UTC
Also, the other sticking point is the inability to drop down to "native" ObjC wrappers. What's the plan there?
Comment 16 Chris Hamons 2015-02-25 16:22:07 UTC
I believe this is the list in question:


On the second point, what changed that prevented that? The removal of the messaging p/invokes and that you have to declare them yourself?
Comment 17 Michael Teper 2015-02-25 16:36:59 UTC
RE: Assembly list => cool, thanks!

RE: messaging p/invokes => could you say more? Why were they removed, and what is involved is replacing them?
Comment 18 Chris Hamons 2015-02-25 16:43:36 UTC
I don't know of any removal of functionality in that area. The only thing I can possibly think of is that you are missing the MonoMac.ObjCRuntime.Messaging class that let you call into objective-c via void_objc_msgSend and friends.

We stopped making that class public in Unified, as it was a maintenance nightmare. It was originally the internal objc_msgSends we use internally that were "accidentally" exposed to user code. It made calling obj_mesSend easy for customer code, but the problem is that the class wasn't part of our "real" API/ABI. When we changed our bindings, if we stopped using a message it would not be generated and we'd break the API. We had to go fix this by hand every time so we stopped breaking customer code. Thus, our decision to stop exposing it in Unified.

There is nothing magic about the class though. You can define your own calls into msgSend via:

		[DllImport ("/usr/lib/libobjc.dylib", EntryPoint="objc_msgSend")]
		public extern static void void_objc_msgSend (IntPtr receiver, IntPtr selector);

for example. As long as the arguments (if any) after the two IntPtrs and the return type matches the message in question, you should be golden.

If that wasn't your issue, please describe it in more detail.
Comment 19 Michael Teper 2015-02-25 16:46:18 UTC
That sounds like it, I will give it a try.
Comment 20 Michael Teper 2015-02-25 17:33:01 UTC
Yup, that *was* it, and I now understand both the the rationale for hiding those bindings and how to recreate them. Thanks again, Chris!
Comment 21 Chris Hamons 2015-02-25 18:43:55 UTC
Awesome. I'll ping you with information when we button up the thing that Miguel was talking about.

Oh, and in the future if you are blocked by things like that objc_msgSend, file a ticket at support.xamarin.com (and ask for me if necessary). As a business license holder, we try extra hard to unblock you, and support can poke us directly pretty easily.
Comment 22 Miguel de Icaza [MSFT] 2015-02-25 22:46:11 UTC

We have a proof of concept of a general purpose invoker, that is type safe and can be used for dynamically calling code.   

I could share a preview of it with you.   That said, if you are comfortable with manually calling objc_msgSend or doing manual wrappers, you do not need it.
Comment 23 Chris Hamons 2015-03-25 16:45:07 UTC
Alright, support the the thing Miguel was talking about, will land in the next Xamarin.Mac (2.0) that will hit alpha in a week or two. 

I'm going to close this bug, as that should hopefully solve you problem. Test it out when it goes out and let me know if it works for you.

Feel free to ping me at chris.hamons@xamarin.com with additional concerns on this if necessary.
Comment 24 Michael Teper 2015-03-25 20:12:07 UTC
Thanks, Chris, look forward to it!
Comment 25 Michael Teper 2015-05-12 19:04:10 UTC
So this actually isn't fixed, at all. Maybe I am doing something wrong, but today I re-attempted to move our Xamarin.Mac application to Unified and hours later ended with an epic fail.

1. Only "Xamarin.Mac Mobile Framework" uses the Xamarin.Mac nuget profile. But, as already discussed here, that profile is tied to .net 2.0 and is pretty useless. The newly minted Xamarin.Mac .NET 4.5 Framework profile uses the net45 nuget profile, making it, too, completely useless and does not solve issues raised in bug 21338.

2. Selecting the Xamarin.Mac .NET 4.5 Framework option and attempting to compile our application results in weird errors like "Extension methods require `System.Runtime.CompilerServices.ExtensionAttribute' type to be available. Are you missing an assembly reference?" Switching to Mono / .NET 4.5 eliminates the error.

3. Selecting Mono / .NET 4.5 is, too, broken, in some indecipherable way as I get gems like this: "error CS7069: Reference to type `System.Windows.Input.ICommand' claims it is defined assembly `System, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089', but it could not be found". Here's the full output:

Views/Tasks/OnlineTaskViewController.cs(88,69): error CS7069: Reference to type `System.Windows.Input.ICommand' claims it is defined assembly `System, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089', but it could not be found
        /Users/michael/repositories/Main/ElLoco/XTractor/UI/Mac/../../../../packages/reactiveui-core.6.5.0/lib/Xamarin.Mac10/ReactiveUI.dll (Location of the symbol related to previous error)
DataSources/StringContextTableViewDataSource.cs(12,20): error CS7069: Reference to type `System.Collections.Generic.IReadOnlyCollection`1<T>' claims it is defined assembly `mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089', but it could not be found
        /Users/michael/repositories/Main/ElLoco/XTractor/UI/Mac/../../../../packages/reactiveui-core.6.5.0/lib/Xamarin.Mac10/ReactiveUI.dll (Location of the symbol related to previous error)
DataSources/StringContextTableViewDataSource.cs(12,20): error CS7069: Reference to type `System.Collections.Generic.IReadOnlyList`1<T>' claims it is defined assembly `mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089', but it could not be found
        /Users/michael/repositories/Main/ElLoco/XTractor/UI/Mac/../../../../packages/reactiveui-core.6.5.0/lib/Xamarin.Mac10/ReactiveUI.dll (Location of the symbol related to previous error)
Comment 26 Chris Hamons 2015-05-13 16:01:00 UTC
Michael - I'm going to take this conversation onto desk and we can file a new bug if necessary.