Please sign in to comment.
[Xamarin.Android.Build.Tasks] Use @(AndroidDefineConstants) (#635)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=56976 A "funny" thing happened in the migration from `xbuild` to `msbuild`: F# compilation behavior changed. This makes nearly no sense at all; it's the confluence of: 1. `fsc.exe` deosn't support specifying multiple symbols in a single `fsc.exe --define`. Specifically, *unlike* `csc`/`mcs`, the following command line does *not* define the symbols `A` and `B`; it is instead, effectively, *ignored*: fsc.exe "--define=A;B" 2. The `<GetAndroidDefineConstants/>` task generated a `;`-separated string value. 3. `xbuild` differs from `msbuild` in `;`-splitting behavior. The `<GetAndroidDefineConstants/>` task is used to determine additional conditional compilation symbols based on the API level. For example, if an app sets `$(TargetFrameworkVersion)`=v2.3 (API-10), then `<GetAndroidDefineConstants/>` will create the MSBuild property `$(AndroidDefineConstants)` with the value: __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__ This is provided as a courtesy to developers so that they can easily conditionally include or exclude code based on the `$(TargetFrameworkVersion) value. When using `xbuild`, this works: the `$(AndroidDefineConstants)` property is split on the `;` to create an `ITaskItem`, which is provided to the `<Fsc/>` tasks' `Fsc.DefineConstants` property. This in turn allows the `<Fsc/>` task to generate a sequence of `--define` options, one per symbol: fsc.exe --define=__XAMARIN_ANDROID_v1_0__ --define=__MOBILE__ --define=__ANDROID__ ... Unfortunately, this behavior is an `xbuild` bug, in that `msbuild` *doesn't* behave this way. Instead, `msbuild` doesn't split the `$(AndroidDefineConstants)` property on `;` to create an `ITaskItem`; instead, it creates a single element which contains the `$(AndroidDefineConstants)` value as-is. This causes the `<Fsc/>` task to generate a command-line like: fsc.exe "--define=__XAMARIN_ANDROID_v1_0__;__MOBILE__;__ANDROID__;..." ... If this were `csc`, that would be *fine*, but it's not `csc`, and it's not fine. The result is that code that requires that e.g. `__ANDROID__` be defined no longer works as expected, becuase `__ANDROID__` *isn't* defined when building with `msbuild`. The fix? If we need an `ITaskItem`, we should create one, not create a string and assume that `msbuild` will split on `;`. Change the `GetAndroidDefineConstants.AndroidDefineConstants` property from being a `string` into an `ITaskItem`, where each element of the array is a separate symbol which should be defined. This allows the desired values to be sent to the `Fsc.DefineConstants` property, allowing compilation to work as desired.
- Loading branch information...
Showing with 39 additions and 11 deletions.