[Xamarin.Android.Build.Tasks] Use @(AndroidDefineConstants) - #635
Conversation
|
Aside: while this adds a test, the test is effectively meaningless, because the test framework uses @dellis1972: Is there some way to force building with Additionally, it looks like the |
4d0d3b8 to
13a08e5
Compare
|
@jonpryor there is an environment variable we can set to force the use of msbuild
|
| public override bool Execute () | ||
| { | ||
| var sb = new StringBuilder (); | ||
| var constants = new List<ITaskItem>(); |
| ", | ||
| }); | ||
| using (var b = CreateApkBuilder ("temp/" + nameof (FSharpAppHasAndroidDefine))) { | ||
| Assert.IsTrue (b.Build (proj), "Build should have succeeded."); |
There was a problem hiding this comment.
can we remove this ? The output will be emitted automatically if it fails.
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.
13a08e5 to
59cebb5
Compare
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.
Changes: dotnet/java-interop@ce8dc40...377c4c7 Fixes: dotnet/java-interop#631 * dotnet/java-interop@377c4c7: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (dotnet#637) * dotnet/java-interop@857b9a9: [Java.Interop.Export] Begin supporting methods with 14+ params (dotnet#635) * dotnet/java-interop@9876e31: [Java.Interop.BootstrapTasks] Convert to SDK style project (dotnet#609) * dotnet/java-interop@cbb50af: [generator-Tests] Use Roslyn for .NET Core Support (dotnet#638) * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (dotnet#632) * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (dotnet#634)
Changes: dotnet/java-interop@ce8dc40...377c4c7 Fixes: dotnet/java-interop#631 * dotnet/java-interop@377c4c7: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (dotnet#637) * dotnet/java-interop@857b9a9: [Java.Interop.Export] Begin supporting methods with 14+ params (dotnet#635) * dotnet/java-interop@9876e31: [Java.Interop.BootstrapTasks] Convert to SDK style project (dotnet#609) * dotnet/java-interop@cbb50af: [generator-Tests] Use Roslyn for .NET Core Support (dotnet#638) * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (dotnet#632) * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (dotnet#634)
Changes: dotnet/java-interop@ce8dc40...377c4c7 Fixes: dotnet/java-interop#631 * dotnet/java-interop@377c4c7: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (#637) * dotnet/java-interop@857b9a9: [Java.Interop.Export] Begin supporting methods with 14+ params (#635) * dotnet/java-interop@9876e31: [Java.Interop.BootstrapTasks] Convert to SDK style project (#609) * dotnet/java-interop@cbb50af: [generator-Tests] Use Roslyn for .NET Core Support (#638) * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (#632) * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (#634)
Changes: dotnet/java-interop@6608c59...e599781 Fixes: dotnet/java-interop#631 * dotnet/java-interop@e599781: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (#637) * dotnet/java-interop@b7aec95: [Java.Interop.Export] Begin supporting methods with 14+ params (#635) * dotnet/java-interop@eb6202b: [Java.Interop.BootstrapTasks] Convert to SDK style project (#609) * dotnet/java-interop@e078618: [generator-Tests] Use Roslyn for .NET Core Support (#638) * dotnet/java-interop@8e5310b: [generator] Use custom delegates instead of Func/Action. (#632) * dotnet/java-interop@f20f853: [Java.Interop.sln] Commit updated automatically generated guids. (#634)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=56976
A "funny" thing happened in the migration from
xbuildtomsbuild:F# compilation behavior changed.
This makes nearly no sense at all; it's the confluence of:
fsc.exedeosn't support specifying multiple symbols in a singlefsc.exe --define. Specifically, unlikecsc/mcs, thefollowing command line does not define the symbols
AandB;it is instead, effectively, ignored:
The
<GetAndroidDefineConstants/>task generated a;-separatedstring value.
xbuilddiffers frommsbuildin;-splitting behavior.The
<GetAndroidDefineConstants/>task is used to determineadditional 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: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 anITaskItem[], which isprovided to the
<Fsc/>tasks'Fsc.DefineConstantsproperty. Thisin turn allows the
<Fsc/>task to generate a sequence of--defineoptions, one per symbol:
Unfortunately, this behavior is an
xbuildbug, in thatmsbuilddoesn't behave this way. Instead,
msbuilddoesn't split the$(AndroidDefineConstants)property on;to create anITaskItem[]; instead, it creates a single element which contains the$(AndroidDefineConstants)value as-is. This causes the<Fsc/>taskto generate a command-line like:
If this were
csc, that would be fine, but it's notcsc, and it'snot fine.
The result is that code that requires that e.g.
__ANDROID__bedefined no longer works as expected, becuase
__ANDROID__isn'tdefined when building with
msbuild.The fix? If we need an
ITaskItem[], we should create one, not createa string and assume that
msbuildwill split on;. Change theGetAndroidDefineConstants.AndroidDefineConstantsproperty from beinga
stringinto anITaskItem[], where each element of the array is aseparate symbol which should be defined. This allows the desired
values to be sent to the
Fsc.DefineConstantsproperty, allowingcompilation to work as desired.