Xamarin.Android porting strategy

74 views
Skip to first unread message

ja...@apx-labs.com

unread,
Jan 14, 2015, 10:24:06 AM1/14/15
to castle-pro...@googlegroups.com
I've been working lately on getting Moq to work on Xamarin.Android, which means getting Castle.Core to work on Xamarin.Android as well. My goal is to get my changes accepted upstream for both Castle and Moq, so I'd looking for guidance and feedback on how to organize my changes to make them acceptable.

TL;DR - Would it be acceptable to put Castle.Core's source files in a new Shared Code project (.shproj), and then reference that project in both Castle.Core and a new Castle.Core.Android project?

So far, I have Castle and Moq both building for Xamarin.Android, and Moq passes all but 2 of its unit tests now. To get to that point, however, I had to hack up Castle.Core's solution and project files to the point that they only build for Xamarin.Android.

I would use $(Configuration) or $(Platform) Condition checks to make a single .csproj work with both .NET and Xamarin.Android profiles, if that were possible. Unfortunately, the Xamarin.Android .csproj must be separate, or else Xamarin gets confused about what kind of project it is.

Since Castle.Core is not a candidate to become a PCL, my usual approach to fix this would be to create a Shared Project. It would contain all of the source files currently in Castle.Core, and then Castle.Core.csproj and Castle.Core.Android.csproj would reference that project. Adding a source file to the Shared Project would then automatically be included in both projects. A similar approach would be used for Castle.Core.Tests. This approach is easy to understand and maintain. It's only downside is that it requires at least Visual Studio 2013 Update 2 or Xamarin Studio 5.0 or later.

The alternative is ugly and unpleasant to maintain. In Castle.Core.Android.csproj, make a <Link> to every source file from Castle.Core that should be compiled in Castle.Core.Android as well. This is painful because every time a file is added/removed from Castle.Core, the link must also be added/removed in Castle.Core.Android.

Is there an alternative that I've missed?

Also, is there anything I need to account for in Settings.proj, buildscripts/Build.proj, or buildscripts/Castle.Common.Targets?

Thanks,
James


hammett

unread,
Jan 14, 2015, 3:42:35 PM1/14/15
to castle-pro...@googlegroups.com
I think that's reasonable, since it's the only way for people to
benefit using those directly or indirectly.

> Since Castle.Core is not a candidate to become a PCL

I've been somewhat away from .net so I'm not up to speed on why it's
not a candidate. Is it the API surface it relies on not available on
the portable API subset?
> --
> You received this message because you are subscribed to the Google Groups
> "Castle Project Development List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to castle-project-d...@googlegroups.com.
> To post to this group, send email to castle-pro...@googlegroups.com.
> Visit this group at http://groups.google.com/group/castle-project-devel.
> For more options, visit https://groups.google.com/d/optout.



--
Cheers,
hammett
http://www.d-collab.com/
http://www.hammettblog.com/

Jonathon Rossi

unread,
Jan 14, 2015, 11:12:46 PM1/14/15
to Castle Project Development
Personally I'd prefer we didn't introduce Shared Code projects into Castle Core, our current MSBuild project files and the .targets file and others running in there makes it complicated enough, and Shared Code projects just introduce more projects. I've also found that XS doesn't like all the conditional MSBuild checks we've got in there currently, so this is likely to make things worse.

I've seen quite a few ways that you can do wildcards for files in MSBuild where VS won't revert it back to a full file list. James, do you think having a separate Castle.Core-Android.csproj and Castle.Core.Tests-Android.csproj (a bit like our Castle.Core.Tests-SL.csproj) would do the trick? If we went this way it would mean not changes to the existing projects, and the Xamarin project can stand on its own.

Hammett, yes it's the PCL subset (you pick the combination of platforms). PCLs can't have any conditional compilation, as they are meant to be "platform independent" to the extent you make them portable.
Jono

ja...@apx-labs.com

unread,
Jan 15, 2015, 11:23:11 AM1/15/15
to castle-pro...@googlegroups.com
System.Reflection.Emit is not part of any PCL profile. Also, the currently defined PCL profiles assume that Xamarin.iOS and Xamarin.Android have the same capabilities, but Xamarin.iOS definitely does NOT support Reflection.Emit. So, even if there were a PCL profile that had Reflection, it wouldn't be an option here.

ja...@apx-labs.com

unread,
Jan 15, 2015, 11:59:23 AM1/15/15
to castle-pro...@googlegroups.com
I am suggesting separate Castle.Core-Android.csproj and Castle.Core.Tests-Android.csproj files, but NOT a separate Castle.Core-Android.sln. (Why is there a Castle.Core-SL.sln file anyway? Silverlight is built in Castle.Core.sln as well...) I am just trying to avoid manually updating the Android project files every time a file is added or removed from the regular project files. I know from past experience that Xamarin Studio chokes on <Link> entries with wildcards, so that won't work. It's perfectly happy with wildcards in <Compile> entries, but that won't help us here.

I understand the reluctance to further complicate the project files. A Shared Project in addition to all of the conditional checks, Settings.proj, and buildscripts/Castle.Common.Targets files would be messy. What if some of those conditionals and additional build files were unnecessary? Would that make room for a Shared project?

For example, the MONO310 configurations can be removed altogether. Desktop Mono (as opposed to Xamarin) is compatible with .NET, and there's nothing stopping Mono's runtime from using the assemblies built with the NET45 configuration, so why pretend that it needs a different DLL? Issues w/ Mono's compiler (as in DynamicProxy/ProxyGenerator.cs) can be handled using the built-in preprocessor define __MonoCS__ instead of needing to define MONO in the .csproj. As for all of the conditional compilation checks for MONO with the comment "Until support for other platforms is verified", isn't that what Unit Tests are for? And wouldn't a failure there be a bug with Mono, not a bug with Castle?

~James

Reading through those additional project files, it makes me wonder whether they are all really necessary.

> To post to this group, send email to castle-pro...@googlegroups.com.
> Visit this group at http://groups.google.com/group/castle-project-devel.
> For more options, visit https://groups.google.com/d/optout.




--
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-devel+unsub...@googlegroups.com.

To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

Jonathon Rossi

unread,
Jan 15, 2015, 11:13:13 PM1/15/15
to Castle Project Development
Hey James,

That Silverlight solution and project file are quite old, but IIRC you need a Silverlight project type to be able to run the project under the debugger as an XBAP. We might be able to remove them, ignore them unless they get in the way trying to add Android support.

I've documented my efforts with getting things going with Mono over the last month, I really haven't spent much time on it, I've been meaning to get back to it to see if I can sort the blocking problem out. I know people are using Castle Core on Mono, but getting support in our build scripts is what I'm trying to do there. If we could sort out that blocking problem I agree a bunch of stuff could be removed from those build files. I'd appreciate if you could take a read though this issue I just logged.

Just so it is on the table, we aren't pretending Mono should be a different DLL, the last time we actually officially supported Mono was the Mono 2.6 days. Since then Mono has definitely got heaps better but there has been no work on the Castle side to clean up any of that. As mentioned in #79, currently the MONO310 configuration doesn't define MONO, I renamed it to try to get things going like NET45.

I'm not the author of the MSBuild targets and proj files we've got for our set up, but they were a lot easier to maintain than the NAnt set up we had before it when there weren't so many platforms, however with more platforms being added and none removed things have become a little messy on that front.

Okay back to the actual issue at hand, Android. I've thought about it a bit more and I'm happy to accept a PR to add a Shared Code project (well two of them) as long as all the .cs files don't move, whether the current .csproj needs to move to another directory, or the current .csproj and the .shproj go in the same source directory I'm not too torn, same directory will probably make the least change.

Jono

To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-d...@googlegroups.com.

To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

ja...@apx-labs.com

unread,
Jan 16, 2015, 4:23:07 PM1/16/15
to castle-pro...@googlegroups.com
Jono,

I just read through the issue you linked to. I'll look at adding NLog to the Android build so that I can see whether that error occurs on Xamarin as well.
I think it is possible to create the .shproj files without moving any .cs files, as requested.

About the test cases:

1. Xamarin.Android uses NUnitLite, which does not have support for some of the old "classic" assertions of NUnit. This means that some unit tests now use the modern "constraint" assertion API. For example, wherever a unit test says Assert.IsInstanceOf<T>(obj), I've changed it to read Assert.That(obj, Is.InstanceOf<T>()).
2. Mono does have a version of the PEVerify tool, but its syntax is different and I haven't proven that it tests the same things as Visual Studio's tool. If I figure it out, I'll use a runtime check in the BasePEVerifyTestCase.cs to make the correct call.
3. Of the 1330 unit tests currently enabled in my Android build, 96 are failing. Many of those Xml test failures, which were #ifdef'd out in the SILVERLIGHT and MONO configurations before. Many other failures are frequently related to the unit tests assuming that they are running on a Windows machine with write access to the current working directory, and I can hopefully fix those.

~James
> To post to this group, send email to castle-pro...@googlegroups.com.
> Visit this group at http://groups.google.com/group/castle-project-devel.
> For more options, visit https://groups.google.com/d/optout.




--
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-devel+unsubscrib...@googlegroups.com.
To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

--
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-devel+unsub...@googlegroups.com.
To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

Jonathon Rossi

unread,
Jan 18, 2015, 9:46:46 PM1/18/15
to Castle Project Development
I didn't get that error with NLog in Xamarin Studio or xbuild on OSX building for a normal net 4.5 profile.

If you want to send a pull request through changing the NUnit assertions to the newer API and/or fixing the Windows assumptions in the unit tests I can merge them before other changes to we don't end up with a massive pull request.

I'm happy for the PEVerify assertions to not be executed, we haven't been running them at all until now, so one step at a time is the best way.

To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-d...@googlegroups.com.

To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

ja...@apx-labs.com

unread,
Jan 30, 2015, 4:56:59 PM1/30/15
to castle-pro...@googlegroups.com
How important is it to preserve support for Silverlight 4.0 or older versions of .NET?

I'm naturally trying to make sure that I don't break the Desktop or Silverlight builds of Castle as a result of introducing Shared Projects to the solution. Therefore, I'm testing my changes in my Windows 7 VM with Visual Studio 2013 Update 4. I'm running into particular trouble keeping the Silverlight 4.0 and .NET 3.5 configurations working, because VS 2013 does not like all of the Conditional <Import> tags and DLL references.

Silverlight itself is deprecated, and Silverlight 5.0 has been out for over 3 years. 5.0 runs on all versions of Windows going back to Windows XP, so there's no need for an app to target Silverlight 4.0. Similarly, .NET 4.0 is almost 5 years old at this point. 4.0 also runs on all versions of Windows going back to Windows XP, so there's no need for an app to target earlier versions of the framework. When does Castle stop maintaining support for platforms that are beyond EOL?

Jonathon Rossi

unread,
Feb 2, 2015, 12:40:01 AM2/2/15
to Castle Project Development
I'm happy for you to drop Silverlight 4.0 support if you can't get it working, agreed that there is no need to support it anymore because of the very low usage. However .NET 3.5 is another story, Castle Core has quite a lot of users and with Microsoft still supporting .NET 3.5.1 on many operating systems (including Win8.1) my vote is strongly to keep support for it. I don't think I'd accept a PR that dropped .NET 3.5 support.

Just a quick look at Moq, FakeItEasy and RhinoMocks, and FakeItEasy at least clearly wants to continue supporting .NET 3.5.1:

When you said that Visual Studio 2013.4 is having problems with Shared Projects, did you mean just for those two platforms you wanted to remove support for? i.e. it works for .NET4+.

To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-d...@googlegroups.com.

To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

Jonathon Rossi

unread,
Feb 2, 2015, 12:54:53 AM2/2/15
to Castle Project Development
NSubstitute and JustMockLite also still support .NET 3.5.
--
Jono

ja...@apx-labs.com

unread,
Feb 2, 2015, 11:00:21 AM2/2/15
to castle-pro...@googlegroups.com
Jono,

I'll only remove Silverlight 4.0 then, and I'll ensure that all of the .NET builds function exactly as they do now. The issue is not Shared Projects - it's lines like the following in csproj files:

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight\v4.0\Microsoft.Silverlight.CSharp.targets" Condition="$(MSBuildTargets) == 'Silverlight 4.0'" />
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight\v5.0\Microsoft.Silverlight.CSharp.targets" Condition="$(MSBuildTargets) == 'Silverlight 5.0'" />

If VS2013 sees these lines, it thinks the Silverlight part of the project needs to be upgraded, and makes many changes to the csproj, including replacing those lines with the following:

  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight\v5.0\Microsoft.Silverlight.CSharp.targets" Condition="$(MSBuildTargets) == 'Silverlight 5.0'" />

Naturally, I remove the second, redundant line, but then it's still very finicky to make sure that the first line there still parses without errors when the configuration _isn't_ targeting of the two Silverlight versions, but also still picks the correct version when it _is_ targeting Silverlight.

~James

Jono

ja...@apx-labs.com

unread,
Mar 24, 2015, 10:48:55 AM3/24/15
to castle-pro...@googlegroups.com
Jono,

I'm still working on this in my spare time. I've been trying to get as many unit tests to pass as possible, including ones that were previously altered or ignored on Mono.

I've got BasePEVerifyTestCase.cs using Mono's peverify instead of .NET's peverify.exe when the test detects that it's running on Mono. It turns out that Mono's peverify is significantly more strict that .NET's peverify.exe. The DLLs that Castle.Core generates when running under Mono pass with .NET's peverify.exe, so I'm not worried that there's a problem with Castle running on Mono. When I test with Mono's peverify, all of those tests fail with the following error:

Error: Invalid CustomAttribute content row 0 Value field 0x00000166
Error: CustomAttribute: Invalid constructor
Error count: 2

The "field" hex value varies on some tests, but otherwise the error message is the same. Since it's talking about row 0 (the module?), is this error referring to CacheMappingsAttribute?

Also, is peverify.exe there as a sanity check, or is it part of the unit tests to catch something specific, like type safety? If it's there to test something specific, I might be able to imagine another way to test for that.

~James

On Monday, February 2, 2015 at 12:54:53 AM UTC-5, Jonathon Rossi wrote:
Jono

Jonathon Rossi

unread,
Mar 29, 2015, 11:23:01 PM3/29/15
to Castle Project Development
To be honest I've got no idea what the error means. From the mono code it doesn't look like the row 0 means the module, but I'm not knowledgable about the internal structures of the mono runtime.
https://github.com/mono/mono/blob/adb9681393a8dfec2ca9c2e8c5a4ed72d663878d/mono/metadata/metadata-verify.c#L2958

Do you think these verify errors could be related to the compilation errors I was getting with Mono on Linux that I couldn't work out. The "Missing method .ctor in assembly" ones:

You could call having peverify there a sanity check, but IL code generation is finicky, so the unit tests might pass but be invalid IL, it is definitely a must at least on Windows.

As I mentioned earlier I'd be happy to accept smaller pull requests that push us further to supporting mono, you could leave the peverify checks out on mono for now.

To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-d...@googlegroups.com.

To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-devel.
For more options, visit https://groups.google.com/d/optout.



--
Jono

ja...@apx-labs.com

unread,
Nov 3, 2015, 2:19:33 PM11/3/15
to Castle Project Development List
Jono,

I'm re-doing my porting efforts here based on the latest master, and structuring them in a way that facilitates smaller pull requests. I submitted the first of these to remove Silverlight 4.0 support. My plans for subsequent pull requests after that are:

  1. Migrate Castle.Core and Castle.Core.Tests to Shared Projects, and create new Castle.Core-Desktop, Castle.Core-SL, Castle.Core.Tests-Desktop, and Castle.Core.Tests-SL projects. This will simplify the .csproj files considerably, and make the next PR possible:
  2. Add Castle.Core-Android and Castle.Core.Tests-Android projects. This PR will also update the NUnit tests to use Constraints instead of the classic model, so that NUnitLite on Android can run them.
Does that sound reasonable?

From what I know about the direction the Mono project is going, a lot of the Mono or Xamarin.Android conditionals that are currently necessary will eventually go away. They are bringing more and more of Microsoft's open-sourced .NET code into Mono. When the XML classes are synced up, I expect that all of the current XML unit tests that fail on Mono and Xamarin.Android will pass.

~James
Reply all
Reply to author
Forward
0 new messages