Bug 56976 - F# is missing __ANDROID__ define (regression)
Summary: F# is missing __ANDROID__ define (regression)
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 7.3 (15.2)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: 15.3
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2017-05-30 20:34 UTC by Frank A. Krueger
Modified: 2017-06-15 10:36 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: Yes
Last known good build: 15.1


Attachments
Project demonstrates the bug (30.34 KB, application/zip)
2017-05-30 21:43 UTC, Frank A. Krueger
Details


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:
Status:
RESOLVED FIXED

Description Frank A. Krueger 2017-05-30 20:34:03 UTC
In Xamarin Studio the __IOS__ define was always predefined by the tooling.

Now with Visual Studio for Mac, these defines are no longer predefined. This seems like a regression.

As a workaround, the defines can be manually added.




=== Visual Studio Enterprise 2017 for Mac (Preview) ===

Version 7.1 Preview (7.1 build 583)
Installation UUID: a0dbb582-a27c-41e5-b0a4-d2a06465b5db
Runtime:
	Mono 5.2.0.104 (2017-04/4a0006f) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 502000104

=== NuGet ===

Version: 4.0.0.2323

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet
SDK: /usr/local/share/dotnet/sdk/1.0.4/Sdks
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.5.4
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Xamarin.Android ===

Version: 7.1.0.43 (Visual Studio Enterprise)
Android SDK: /Users/fak/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		6.0 (API level 23)
		7.0 (API level 24)
		7.1 (API level 25)

SDK Tools Version: 25.2.5
SDK Platform Tools Version: 25.0.3
SDK Build Tools Version: 25.0.1

Java SDK: /usr
java version "1.8.0_20-ea"
Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b23)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b22, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Inspector ===

Version: 1.3.0-alpha1
Hash: 0855e01
Branch: master
Build date: Thu, 11 May 2017 04:16:13 GMT

=== Apple Developer Tools ===

Xcode 8.3.2 (12175)
Build 8E2002

=== Xamarin.iOS ===

Version: 10.11.0.126 (Visual Studio Enterprise)
Hash: 7571635e
Branch: master
Build date: 2017-05-09 16:04:54-0400

=== Xamarin.Mac ===

Version: 3.5.0.126 (Visual Studio Enterprise)

=== Build Information ===

Release ID: 701000583
Git revision: 445a7f09feca58babb966e0c66a6b299d0bd450c
Build date: 2017-05-12 16:05:38-04
Xamarin addins: f9b72ca5f6ca5d9476d8f58353ada2afd56c549b
Build lane: monodevelop-lion-d15-3-preview

=== Operating System ===

Mac OS X 10.12.4
Darwin 16.5.0 Darwin Kernel Version 16.5.0
    Fri Mar  3 16:52:33 PST 2017
    root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64

=== Enabled user installed addins ===

AddinMaker 1.3.7
Manifest.addin 0.0.0.0








=== Xamarin Studio Enterprise ===

Version 6.3 (build 864)
Installation UUID: 033a3a98-f63f-44a3-8bd3-bb3b731f3639
Runtime:
	Mono 5.2.0.104 (2017-04/4a0006f) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 502000104

=== NuGet ===

Version: 3.5.0.0

=== Xamarin.Profiler ===

Version: 1.5.4
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 8.3.2 (12175)
Build 8E2002

=== Xamarin.iOS ===

Version: 10.11.0.126 (Visual Studio Enterprise)
Hash: 7571635e
Branch: master
Build date: 2017-05-09 16:04:54-0400

=== Xamarin.Android ===

Version: 7.1.0.43 (Visual Studio Enterprise)
Android SDK: /Users/fak/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		6.0 (API level 23)
		7.0 (API level 24)
		7.1 (API level 25)

SDK Tools Version: 25.2.5
SDK Platform Tools Version: 25.0.3
SDK Build Tools Version: 25.0.1

Java SDK: /usr
java version "1.8.0_20-ea"
Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b23)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b22, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin.Mac ===

Version: 3.5.0.126 (Visual Studio Enterprise)

=== Xamarin Inspector ===

Version: 1.3.0-alpha1
Hash: 0855e01
Branch: master
Build date: Thu, 11 May 2017 04:16:13 GMT

=== Build Information ===

Release ID: 603000864
Git revision: 6c2f6737278ccc3e81e12276d49c0d92f975f189
Build date: 2017-04-24 11:26:01-04
Xamarin addins: d8d46e577d8507c35260ce9d73df3c33415bb214
Build lane: monodevelop-lion-d15-1

=== Operating System ===

Mac OS X 10.12.4
Darwin muon.local 16.5.0 Darwin Kernel Version 16.5.0
    Fri Mar  3 16:52:33 PST 2017
    root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64

=== Enabled user installed addins ===

Continuous Coding 2.0.5
Addin Maker 1.3.2
Manifest.addin 0.0.0.0
Comment 1 James Montemagno [MSFT] 2017-05-30 21:25:41 UTC
Frank originally stated it was __IOS__, but I was experiencing __ANDROID__ not being there, so it could be both, but Android 100% for sure.
Comment 2 Frank A. Krueger 2017-05-30 21:43:11 UTC
Created attachment 22564 [details]
Project demonstrates the bug
Comment 3 Jonathan Pryor 2017-06-06 20:05:21 UTC
This is *bizarre*. But what else do we expect?

TL;DR: This appears to be an `msbuild` bug.

Step Zero: Modify Attachment #22564 [details] so that it *always* sets button.Text. This simplifies grep'ing. ;-)

>         button.Click.Add (fun args -> 
>             button.Text <- sprintf "%d clicks!" count
> #if __ANDROID__
>             button.Text <- sprintf "Android %d clicks!" count
> #endif
>             count <- count + 1
>         )

Next, build with `xbuild`, `msbuild`, and Visual Studio for Mac. *All* of them show the similar things:

1. The `<GetAndroidDefineConstants/>` task is invoked:

> Task "GetAndroidDefineConstants"
>   Task Parameter:AndroidApiLevel=23
>   Task Parameter:ProductVersion=v1.0
>   Output Property: AndroidDefineConstants=__XAMARIN_ANDROID_v1_0__%3b__MOBILE__%3b__ANDROID__%3b__ANDROID_1__%3b__ANDROID_2__%3b__ANDROID_3__%3b__ANDROID_4__%3b__ANDROID_5__%3b__ANDROID_6__%3b__ANDROID_7__%3b__ANDROID_8__%3b__ANDROID_9__%3b__ANDROID_10__%3b__ANDROID_11__%3b__ANDROID_12__%3b__ANDROID_13__%3b__ANDROID_14__%3b__ANDROID_15__%3b__ANDROID_16__%3b__ANDROID_17__%3b__ANDROID_18__%3b__ANDROID_19__%3b__ANDROID_20__%3b__ANDROID_21__%3b__ANDROID_22__%3b__ANDROID_23__
> Done executing task "GetAndroidDefineConstants".

`%3b` is `;`, so if we squint *just right* we see `__ANDROID__` in there.

2. These values are passed to `fsc.exe`. This is the `msbuild` & Visual Studio for Mac invocation:

>  /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/fsharp/fsc.exe -o:obj/Debug/Bug56976.dll
>  -g
>  --debug:full
>  --noframework
>  --define:DEBUG
>  --define:__XAMARIN_ANDROID_v1_0__;__MOBILE__;__ANDROID__;__ANDROID_1__;__ANDROID_2__;__ANDROID_3__;__ANDROID_4__;__ANDROID_5__;__ANDROID_6__;__ANDROID_7__;__ANDROID_8__;__ANDROID_9__;__ANDROID_10__;__ANDROID_11__;__ANDROID_12__;__ANDROID_13__;__ANDROID_14__;__ANDROID_15__;__ANDROID_16__;__ANDROID_17__;__ANDROID_18__;__ANDROID_19__;__ANDROID_20__;__ANDROID_21__;__ANDROID_22__;__ANDROID_23__
>  --optimize-
>  --tailcalls-
> ...

Again, notice that __ANDROID__ is in there.

Once significant difference: the `xbuild` invocation places each `--define` as a separate option:

> Using task Fsc from Microsoft.FSharp.Build.Fsc, FSharp.Build, Version=4.4.1.0, Culture=neutral, PublicKeyToken=f536804aa0eb945b
> Tool /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/fsharp/fsc.exe execution started with arguments:  -o:obj/Debug/Bug56976.dll
> -g
> --debug:full
> --noframework
> --define:DEBUG
> --define:__XAMARIN_ANDROID_v1_0__
> --define:__MOBILE__
> --define:__ANDROID__
> --define:__ANDROID_1__
> --define:__ANDROID_2__
> --define:__ANDROID_3__
> --define:__ANDROID_4__
> --define:__ANDROID_5__
> --define:__ANDROID_6__
> --define:__ANDROID_7__
> --define:__ANDROID_8__
> --define:__ANDROID_9__
> --define:__ANDROID_10__
> --define:__ANDROID_11__
> --define:__ANDROID_12__
> --define:__ANDROID_13__
> --define:__ANDROID_14__
> --define:__ANDROID_15__
> --define:__ANDROID_16__
> --define:__ANDROID_17__
> --define:__ANDROID_18__
> --define:__ANDROID_19__
> --define:__ANDROID_20__
> --define:__ANDROID_21__
> --define:__ANDROID_22__
> --define:__ANDROID_23__
> --optimize-
> --tailcalls-
> -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/System.dll


Regardless, from the Xamarin.Android side of things, we're doing what we should be doing.

However, let us turn to the resulting IL. Unfortunately, neither `ikdasm` nor `monodis` work for me, so we'll turn to `hexdump -C`! Further note that strings in assemblies are UTF-16, not UTF-8, so... (insert silent screaming...)

If we look at the dump of the xbuild-generated assembly, things are what we'd expect (-ish):

> $ hexdump -C bin/Debug/Bug56976.dll
> ...
> 000011e0  54 65 78 74 00 61 72 67  73 00 00 00 00 15 25 00  |Text.args.....%.|
> 000011f0  64 00 20 00 63 00 6c 00  69 00 63 00 6b 00 73 00  |d. .c.l.i.c.k.s.|
> 00001200  21 00 00 25 41 00 6e 00  64 00 72 00 6f 00 69 00  |!..%A.n.d.r.o.i.|
> 00001210  64 00 20 00 25 00 64 00  20 00 63 00 6c 00 69 00  |d. .%.d. .c.l.i.|

Here we can see the `%d clicks` and `Android %d clicks` messages from my altered OnCreate() method. This is shows that `#if __ANDROID__` is working as expected.

If we instead look at the dump of the msbuild-generated assembly, *we're missing the #Android block!*

> $ hexdump -C bin.xb/Debug/Bug56976.dll
> ...
> 000011b0  00 73 65 74 5f 54 65 78  74 00 61 72 67 73 00 00  |.set_Text.args..|
> 000011c0  00 15 25 00 64 00 20 00  63 00 6c 00 69 00 63 00  |..%.d. .c.l.i.c.|
> 000011d0  6b 00 73 00 21 00 00 00  d3 05 37 59 2d d7 ff 5d  |k.s.!.....7Y-..]|


The Visual Studio for Mac output is similarly wrong:

> $ hexdump -C bin.xb/Debug/Bug56976.dll
> ...
> 000011a0  6f 72 6d 61 74 60 34 00  54 65 78 74 56 69 65 77  |ormat`4.TextView|
> 000011b0  00 73 65 74 5f 54 65 78  74 00 61 72 67 73 00 00  |.set_Text.args..|
> 000011c0  00 15 25 00 64 00 20 00  63 00 6c 00 69 00 63 00  |..%.d. .c.l.i.c.|
Comment 4 Jonathan Pryor 2017-06-06 20:13:31 UTC
Expanding upon Comment #3, perhaps the "actual" problem is the use of "joined" vs. "separate" `fsc --define` options?

To verify, we'll do as xbuild does, to generate `Separate-Defines.dll`:

> mono /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/fsharp/fsc.exe 				-g \
>   -o:Separate-Defines.dll \
>   --debug:full \
>   --noframework \
>   --define:DEBUG \
>   --define:__ANDROID__ \
>   --define:__ANDROID_23__ \
>   --optimize- \
>   --tailcalls- \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v6.0/Mono.Android.dll \
>   -r:packages/FSharp.Core.4.0.0.1/lib/portable-net45+monoandroid10+monotouch10+xamarinios10/FSharp.Core.dll \
>   -r:packages/Xamarin.Android.FSharp.ResourceProvider.1.0.0.13/lib/Xamarin.Android.FSharp.ResourceProvider.Runtime.dll \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/Java.Interop.dll \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/Facades/System.Runtime.dll \
>   --target:library \
>   --warnaserror:76 \
>   --fullpaths \
>   --flaterrors \
>   --highentropyva- \
>   Properties/AssemblyInfo.fs \
>   MainActivity.fs

As expected, this results in the correct IL:

> $ hexdump -C Separate-Defines.dll
> ...
> 00001170  78 74 56 69 65 77 00 73  65 74 5f 54 65 78 74 00  |xtView.set_Text.|
> 00001180  61 72 67 73 00 00 00 00  00 15 25 00 64 00 20 00  |args......%.d. .|
> 00001190  63 00 6c 00 69 00 63 00  6b 00 73 00 21 00 00 25  |c.l.i.c.k.s.!..%|
> 000011a0  41 00 6e 00 64 00 72 00  6f 00 69 00 64 00 20 00  |A.n.d.r.o.i.d. .|
> 000011b0  25 00 64 00 20 00 63 00  6c 00 69 00 63 00 6b 00  |%.d. .c.l.i.c.k.|


What about msbuild-style joined defines?

> mono /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/fsharp/fsc.exe 				-g \
>   -o:Joined-Defines.dll \
>   --debug:full \
>   --noframework \
>   "--define:DEBUG;__ANDROID__;__ANDROID_23__" \
>   --optimize- \
>   --tailcalls- \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v6.0/Mono.Android.dll \
>   -r:packages/FSharp.Core.4.0.0.1/lib/portable-net45+monoandroid10+monotouch10+xamarinios10/FSharp.Core.dll \
>   -r:packages/Xamarin.Android.FSharp.ResourceProvider.1.0.0.13/lib/Xamarin.Android.FSharp.ResourceProvider.Runtime.dll \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/Java.Interop.dll \
>   -r:/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/Facades/System.Runtime.dll \
>   --target:library \
>   --warnaserror:76 \
>   --fullpaths \
>   --flaterrors \
>   --highentropyva- \
>   Properties/AssemblyInfo.fs \
>   MainActivity.fs

As feared, this results in #Android *not* being defined:

> $ hexdump -C Joined-Defines.dll | less
> ...
> 00001140  00 73 65 74 5f 54 65 78  74 00 61 72 67 73 00 00  |.set_Text.args..|
> 00001150  00 15 25 00 64 00 20 00  63 00 6c 00 69 00 63 00  |..%.d. .c.l.i.c.|
> 00001160  6b 00 73 00 21 00 00 00  11 0c 37 59 f8 9d 78 0a  |k.s.!.....7Y..x.|
Comment 5 Jonathan Pryor 2017-06-06 20:33:58 UTC
After internal discussions, this does appear to be a Xamarin.Android bug, brought about by the use of MSBuild.

Specifically, the problem is that the `<GetAndroidDefineConstants/>` task generates a string:

https://github.com/xamarin/xamarin-android/blob/59ec488/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidDefineConstants.cs#L19

MSBuild is preserving the `;` within the AndroidDefineConstants string as a literal `;`, and is thus not splitting on `;` when passing the value to the `Fsc.DefineConstants` property (which is an ITaskItem[] member). This is why MSBuild output uses the `--define:FOO;BAR;...` syntax, which doesn't work.

The `GetAndroidDefineConstants.AndroidDefineConstants` property should instead be an `ITaskItem[]`, one member per #define.
Comment 6 dean.ellis 2017-06-07 11:12:30 UTC
PR up https://github.com/xamarin/xamarin-android/pull/634