In the steps to getting Xamarin.Android to build on Windows, we are
first going to _require_ the bundle to be downloaded from a previous
macOS build. Since `$(HostOS)` will be `Windows`, we need to download
the `Darwin` bundle specifically on Windows.
Found a place that `UnzipDirectoryChildren` was not getting passed the
`$(HostOS)` variable appropriately in
`Xamarin.Android.Build.Tasks.targets`.
And lastly, the `SystemUnzip` MSBuild task was using `/bin/mv` which
should use an equivalent Windows command instead. `cmd /C move` is a
reasonable alternative on Windows. Note that I did not run into any
`%MAX_PATH%` issues here.
The `BuildMultiDexApplication()` and `ValidateJavaVersion()` tests
were broken. `ValidateJavaVersion()` required that all the tested target
frameworks were built. In xamarin-android this was not the case.
Only v1.0 and the latest supported one are built.
So we need to modify the `ResolveSdksTask` to abort early if the
Java Version checks fail.
Similarly the `BuildMultiDexApplication()` was using a hard coded
target framework version. What we should be doing is getting
it to use the latest. But we need to cacluate that at runtime
so a new `LatestTargetFrameworkVersion()` has been added to the
Builder. This is similar to the `GetSupportedRuntimes()` as it
caclulates the highest supported `$(TargetFrameworkVersion)`.
* LLVM build fails without g++-multilib package installed
* Conditionally switch package-oss output from Zip to BZip2, on Linux
It massively simplifies the process of building .deb releases (as sources must be provided in .tar.* format, not .zip)
* Add some basic metadata for building .deb packages
Commit 759fd472 [broke the **macOS+msbuild** build][0]:
[0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-msbuild/387/
error XA0001: Unsupported or invalid $(TargetFrameworkVersion) value of 'v7.1'. Please update your Project Options.
The cause of the problem is the `<ResolveSdks/>` task: if both
`$(AndroidApiLevel)` and `$(TargetFrameworkVersion)` are set, then
`$(AndroidApiLevel)` takes precedence, and we set
`$(TargetFrameworkVersion)` to the value that corresponds to
`$(AndroidApiLevel)`.
Commit 759fd472 updated `$(AndroidFrameworkVersion)` to v8.0, so
"normal" builds (`make all`) will only build `Mono.Android.dll` for
v8.0. However, 759fd472 forgot to update `$(AndroidApiLevel)` to 26 --
the API level corresponding to v8.0 -- which resulted in a mismatch
when building e.g. `Xamarin.Android.NUnitLite.csproj`:
`$(AndroidApiLevel)` was 25, which implies/requires
`$(TargetFrameworkVersion)`=v7.1, but we never built v7.1, which
resulted in the above XA0001 error.
Fix the problem by updating `$(AndroidApiLevel)` to default to
`$(AndroidLatestApiLevel)` -- which is 26 as of 759fd472 -- to help
avoid this mismatch again.
PR builds such as [**macOS+xbuild PR Builder** build 1365][0] are
emitting an error from `mono-api-info`, which isn't surfaced as an
error (hence the builds are still green):
[0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-pr-builder/1365/consoleText
[ERROR] FATAL UNHANDLED EXCEPTION: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065'
at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x0015e] in …/xamarin-android/external/Java.Interop/external/cecil/Mono.Cecil/BaseAssemblyResolver.cs:161
This error is raised when processing
`bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/Xamarin.Android.NUnitLite.dll`
because [`$(MONO_API_INFO_LIB_DIRS)`][1] contains
`-L .../MonoAndroid/v8.0`, but the PR builds are building v7.1, *not*
v8.0, and thus `Mono.Android.dll` isn't in a directory which is found.
[1]: https://github.com/xamarin/xamarin-android-api-compatibility/blob/49b5789/Makefile#L26-L29
`$(MONO_API_INFO_LIB_DIRS)` is wrong in turn because
`make run-api-compatibility-tests` was overriding
`$(STABLE_FRAMEWORKS)` to include frameworks which the PR build
doesn't build.
Update `make run-api-compatibility-tests` so that
`$(STABLE_FRAMEWORKS)` isn't overridden. This will allow
`xamarin-android-api-compatibility` to probe the frameworks based on
what's present, and construct `$(MONO_API_INFO_LIB_DIRS)` accordingly.
Additionally, xamarin-android master builds such as [build #538][2]
were also failing in an unreported manner:
[2]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/538/consoleText
Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: '…/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v8.0/OpenTK-1.0.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x00164] in <336971fa838f4b15a2a3a9274b113045>:0
at CorCompare.AssemblyCollection.LoadAssembly (System.String assembly) [0x0002a] in <d46deda6cbab4407bacfbd3b1ee45bd0>:0
Cannot load assembly file …/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v8.0/OpenTK-1.0.dll
The cause for this is that `OpenTK-1.0.dll` is built into the
`MonoAndroid/$(AndroidLatestFrameworkVersion)` framework directory,
and `Configuration.props` was setting
`$(AndroidLatestFrameworkVersion)` to v7.1 (API-25).
Update `$(AndroidLatestFrameworkVersion)` to v8.0, and
`$(AndroidLatestApiLevel)` to 26.
- besides running in different configurations than default (Debug),
we will also use the startup times measurements in the Jenkins
plots
- also fixes a typo in `RunApkTests.targets`, where supposedly
`Condition` was used in place of `Configuration`
- modifies logcat timing file names, so that it is based on test
results filename instead of just package name. that way we can have
multiple timing results for the same test with various
configurations
Some internal workflows require the `Xamarin.Android.Sdk.json` file in
order to use the generated `.vsix`.
Copy the generated `Xamarin.Android.Sdk.json` file into the
directory that `$(VsixPath)` uses
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=57725
The generated `Version` files contain a repository name, e.g.
`Version.rev` may contain:
xamarin-android/master/ccd083c3
This isn't entirely appropriate for the commercial Xamarin.Android
product, which is "rooted in" a different git repository.
The result is that commercial Xamarin.Android `Version.rev` files will
be "non-sensical", e.g.
xamarin-android/HEAD/1a9979ed7
The above from the current `Xamarin.Android.Sdk.7.5.0.10.vsix` file,
and referencing a commit which does not exist within the
xamarin-android repo.
Introduce a new `$(XARepositoryName)` MSBuild property which contains
the name of the git repo to embed into `Version.rev`. This will
default to `xamarin-android`, but allowing it to be overridden will
allow the commercial SDK to instead emit `monodroid/HEAD/1a9979ed7`.
Fix `$(_CrossOutputDirTop)`, which is missing a closing parenthesis,
which angers MSBuild on Windows. (Why it isn't a problem on macOS...)
Update the `<HashFileContents>` task to exclude line endings.
`.gitattributes` changes the line endings for MSBuild project files,
which causes a different hash to be generated on Windows than macOS.
This means that Windows can't use a prebuilt bundle, as the generated
bundle name depends on the content hash of files which differ on
Windows; see commit 97f08f78.
Avoid this problem by reading the files into a `MemoryStream`,
ignoring `\r` and `\n` characters, then hash the `MemoryStream`
contents. This allows both macOS and Windows to produce the same
content hash values, regardless of line endings, which in turn
will allow a future Windows build to use the macOS-built bundle.
Commit 8a703c69 had the right idea, but read the
`__AndroidEnvironment__*` files from the *wrong directory*.
(This wasn't caught in the PR because, for never adequately explained
reasons, the PR *never ran on the required machine*.)
Specifically, commit 8a703c69 looks for `__AndroidEnvironment__*`
files within `{outDirForDll}/{ImportsDir}`, which would be e.g.
`obj/Debug/lp/0/jl`, which will *never* contain these files.
Previously extracted `__AndroidEnvironment__*` files need to instead
be looked for within the `outDirForDll` directory, e.g.
`obj/Debug/lp/0`.
Update the "cached" directory read logic to use the appropriate path.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58646
Rather than just blindly delete ALL the debug files in the
`$(OutputPath)` we should be a bit more selective.
So instead we add the generated files to the file
$(IntermediateOutputPath)$(CleanFile)
so that they can be cleaned up automatically using the in-build
xbuild/msbuild Clean systems.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58727
In commit 0667a2b6 we neglected to take into account that any
embedded libraries or environment files could be deleted when
the zip was extracted. Commit ea6b9b45 fixed the issue for the
Environment files. This commit will fix the issue for the .jar
files.
We also added a new test so this doesn't happen in future.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58721
The initial problem seems to stem from the fact that for the support
library components now directly include the resources. As a result
the `_GenerateJavaResourcesForComponent` target was not running. This
was because it was only running if
`$(_AdditonalAndroidResourceCachePaths)` was not empty. In this
scenario it was always empty.
As a result none of the files like `R.java` files were generated for
the support libraries. The means the final `.class` files did not
have references for the `R$drawable.foo` identifiers.
This results in a crash:
Java.Lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/appcompat/R$drawable;
Fix the problem by looking at `@(LibraryResourceDirectories)` to see
if we have any `AndroidManifest.xml` files. We should then process
these directories to ensure that the `R.java` files are created and
included compiled into the final applications.
We have a failure within
`EnvironmentTests.EnvironmentVariablesFromLibraryProjectsAreMerged`
(commit ea6b9b45): the `@(AndroidEnvironment)` from the library
project is not merged into the App `.apk`:
Expected: null
But was: "Well, hello there!"
(The arguments were in the wrong order. Oops.)
The cause for this is due to `<ResolveLibraryProjectImports/>`
attempts to avoid duplicate work; [from the build log][0]
[0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/526/consoleText
Task "ResolveLibraryProjectImports"
Assemblies:
.../xamarin-android/bin/TestDebug//LibraryResources.dll
Skipped resource lookup for .../xamarin-android/bin/TestDebug/LibraryResources.dll: extracted files are up to date
ResolvedEnvironmentFiles:
*Because* `LibraryResources.dll` was skipped, the
`@(AndroidEnvironment)` entries from `LibraryResources.dll` were also
skipped! Doh!
Update the `<ResolveLibraryProjectImports/>` task so that when
resource extraction for an assembly is skipped, we remember to add the
already-extracted `@(AndroidEnvironment)` values.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58303
Background: It is possible for a Java type to have
"aliasing bindings": two or more managed types which claim to bind
the same Java type:
// C#
namespace Android.Runtime {
[Register ("java/util/HashMap", DoNotRegisterAcw=true)]
partial class JavaDictionary {
}
}
namespace Java.Util {
[Register ("java/util/HashMap", DoNotRegisterAcw=true)]
partial class HashMap {
}
}
These can't be realistically forbidden.
Enter a new-to-bind Java type:
// Java
public class Bxc58383 extends java.util.HashMap implements java.util.Map {
}
In order to bind the above `Bxc58383` type, `generator` needs to
determine the appropriate binding type to use for `java.util.HashMap`.
`generator`'s approach to supporting aliasing types is (largely) to
ignore the problem (almost) entirely: There Can Be Only One™ mapping
from a Java type to a managed type, so `generator` needs to pick one.
It does so by using the *last* definition encountered in the assembly.
Consequently, for the above set of C# declarations, when `generator`
needs to find the managed type which binds `java.util.HashMap`,
`Java.Util.HashMap` will be chosen, as it is the last declared type.
Unfortunately, "real life" is a bit more complicated:
`Mono.Android.dll` is made up of *thousands* of files, and the order
of types within an assembly is a compiler implementation detail.
As such...the current `Mono.Android.dll` has `JavaDictionary` defined
*after* `HashMap`:
# output truncated for relevance
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
1270: Java.Util.Dictionary (flist=12611, mlist=29569, flags=0x100081, extends=0x20b8)
1287: Java.Util.HashMap (flist=12662, mlist=29806, flags=0x100001, extends=0x1388)
3992: Android.Runtime.JavaDictionary (flist=32135, mlist=85344, flags=0x100001, extends=0x20b8)
Because `JavaDictionary` is defined *after* `HashMap`, and both of
those types have `[Register]` attributes which declare that they bind
the *same* Java type, the result is that the binding of `Bxc58383` is
horrifically broken:
// C#
partial class Bxc58383 : global::Android.Runtime.JavaDictionary, global::Java.Util.IMap {
}
Unfortunately, `JavaDictionary` doesn't itself implement `IMap`, so:
error CS0535: 'Bxc58383' does not implement interface member 'IMap.ContainsKey(Object)'
along with 10 other related errors.
Update the `src/Mono.Android` build process so that `JavaDictionary`
and related types will be defined within `Mono.Android.dll` *before*
all the generated types. This allows `HashMap` to be defined last,
allowing `Bxc58383` to be bound without error:
# output truncated
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
3703: Android.Runtime.JavaDictionary (flist=34089, mlist=78134, flags=0x100001, extends=0x4e08)
4170: Java.Util.Dictionary (flist=39685, mlist=91737, flags=0x100081, extends=0x4e08)
4187: Java.Util.HashMap (flist=39736, mlist=91974, flags=0x100001, extends=0x40d8)
The xamarin-android-pr-builder Jenkins job is configured to create and
upload the `Xamarin.Android.Sdk*.vsix` files for PR jobs.
By default -- unless the `$(VsixPath)` MSBuild property is overridden
-- the resulting filename will include the name of the branch that
triggered the build.
PR branch names will include `/`, e.g. `pr/729/merge`.
This was properly considered in commit a08cd80a by replacing `/` and
`\` with `-` in the branch name, resulting in e.g. `pr-729-merge`.
Unfortunately commit 611bb66e broke this, by replacing the use of the
corrected `$(_Branch)` value with `$(XAVersionBranch`, which could
contain anything.
The result is that a PR build will create the .vsix file:
Copying file from "bin/Debug/Xamarin.Android.Sdk.vsix" to "../../bin/BuildDebug/Xamarin.Android.Sdk-OSS-7.4.99.80_pr/729/merge_ca6f84f.vsix".
but Jenkins won't actually upload the file, because it's only looking
for files matching the glob:
xamarin-android/bin/Build*/Xamarin.Android.Sdk*.vsix
and the embedded `/` within the filename doesn't match.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58693
The Android Designer is not working as desired when using a
`monodroid`-generated `Xamarin.Android.Sdk.*.vsix` file, stating:
Renderer >> WARNING: No Xamarin.Android support for custom controls detected. Disabling.
This message actually means that `libmono-android.debug.dll` can't be
found. On Windows, the designer expects `libmono-android.debug.dll` --
along with `libmonosgen-2.0.dll` -- to be installed into the
`$MSBuild/Xamarin/Android` directory.
Unfortunately, this wasn't the case; it was instead installed as:
$MSBuild/Xamarin/Android/lib/host-mxe-Win64/libmono-android.debug.dll
$MSBuild/Xamarin/Android/lib/host-win/libmono-android.debug.dll
Update `create-vsix.targets` so that the
`Xamarin/Android/lib/lib/host-mxe-Win64/*.*` files are installed into
the `$MSBuild/Xamarin/Android` directory, so that the Android Designer
can find these files.
Additionally, further cleanup the `.vsix` contents:
* Don't include `*.dylib` files. Those are for use on macOS.
* Don't include `libZipSharp`-related files in the
`$ReferenceAssemblies` directory. `libZipSharp.dll` is not a
mobile API -- and it wasn't being installed, anyway -- and it
makes no sense to install `libZipSharp.dll.config` there.
This fixes an error we are seeing in the unit test
warning: error APT0000: string 'auth_client_needs_enabling_title' has no default translation.
It looks like there are a number of strings which are required to
have a default value (even if its blank).
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=58448
Based on feedback from the VS team we now know that library
projects are NEVER built as part of a DesignTimeBuild :(.
Furthermore, if ANY error occurs during the DesignTimeBuild
VS throws a wobbly and does not initialise the project
correctly. The suggestion is to use `ContinueOnError` to
ignore the errors and allow the build to complete.
Context: #181 (in comments)
In several places throughout the build, we are running a command such
as `<Exec Command="touch -m -t `git log -1 --format=%25cd
--date=format-local:%25Y%25m%25d%25H%25M.%25S` Makefile" />`, which
will not work on Windows.
The solution is to create an MSBuild task in xa-prep-tasks named
`GitCommitTime` that will work cross-platform. `GitCommitTime` returns
a string value that can be passed to the `Touch` MSBuild task.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58673
The `@(AndroidEnvironment)` Build action is *supposed to be* usable on
Library projects. When used within a Library project, the
`@(AndroidEnvironment)` files are embedded into the assembly, and
during the App project build they are extracted and merged into the
`environment` file within the `.apk`.
Unfortunately, this behavior was potentially broken in commit
86888322, as if the Library assembly also contains the
`__AndroidLibraryProjects__.zip` embedded resource (e.g. the Library
project has a `@(AndroidResource)` Build action), the extraction of
the `__AndroidLibraryProjects__.zip` resource will inadvertently
remove the previously extracted `@(AndroidEnvironment)` files.
Oops.
Alter the paths provided to `Files.ExtractAll()` -- which was
directly responsible for deleting the environment files -- so that it
won't delete the environment files.
Update the `tests/locales` on-device unit tests to make use of a
Library-provided `@(AndroidEnvironment)`, and add a unit test which
reads the environment variable and asserts that the environment
variable has the expected value.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57279
The DesignTimeBuilds are causing a bit of a problem.
Because they are being run as soon as the project is loaded, it
resulted in `_UpdateAndroidResGen` thinking that the
resources are up to date. This results in the following
$ find . -iname R.java | xargs grep EntryActivityStartButton
./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/com/microsoft/intune/mam/R.java: public static final int EntryActivityStartButton=0x7f070000;
./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/microsoftintunemamsampleandroid/microsoftintunemamsampleandroid/R.java: public static final int EntryActivityStartButton=0x7f070000;
./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/android/support/v4/R.java: public static int EntryActivityStartButton=0x7f0c0050;
./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/android/support/v7/appcompat/R.java: public static int EntryActivityStartButton=0x7f0c0050;
./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/com/microsoft/intune/mam/R.java: public static final int EntryActivityStartButton=0x7f0c0050;
./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/microsoftintunemamsampleandroid/microsoftintunemamsampleandroid/R.java: public static final int EntryActivityStartButton=0x7f0c0050;
Note that the `EntryActivityStartButton` value is different, they
should all be the same. This is because the `_UpdateAndroidResGen`
target was NOT running. As a result of this, when the app runs a
`NullReferenceException` could be thrown when the wrong resource id
value is inadvertently used with e.g. `Activity.FindViewById<T>(int)`:
// C#
var button = FindViewById<Button>(Resource.Id.button);
// `button` is actually null, as `Resource.id.button` is wrong
button.Click += delegate { /* ... */ };
// throws `NullReferenceException`, as `button` is null
Fortunately commit 1cd582ec adds `$(DesignTimeBuild)` to the list
of properties in the `@(_PropertyCacheItems)` ItemGroup. So we can
now use the `$(_AndroidBuildPropertiesCache)` property to detect
when we are moving from a DesignTimeBuild into a normal Build.
This means the resources are then generated correctly.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58134
We did a ton of stuff to get multidex working correctly on Windows
in commit 6829b7d1. However it seems that if there are spaces in the
path on macOS, we get similar problems.
The solution is to add single quotes around the list of `.jar` files
when calling `MainDexListBuilder`. That seems pretty logical.
But... it breaks it on Windows (sigh). Because on Windows if we add
the single quotes, it stops working.
So we have to conditionally add the single quotes around the list
of jar files. Note this only applies when we call the `MainDexListBuilder`.
The single quotes seem to work ok when calling proguard..
Weird.
This commit also adds a unit test for this. However we needed to be
able to change the names of the Configurations "Debug", "Release".
So contructor arguments have been added to allow them to be overridden.
These will default to "Debug" and "Release" so that existing tests will
work as expected.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=51507
If a user has an older verison of Java installed they currently get
this kind of helpful error message.
Unsupported major.minor version 52.0
While for the experienced user this might mean "Ah I need Java 1.8".
For the new users this is confusing.
This commit adds a new property in the Xamarin.Android.Common.props
called
$(MinimumRequiredJavaVersion)
This will define the Minimum required version of Java we need.
It can be overridden on the command line or in the project is needed.
If this mimimum version is NOT met, we will error out. While it
might be nicers to issue a warning, this will eventually end up with
the above error anyway. So we might as well tell the user exactly what
is wrong.
It turned out that there had been a build failure that had been ignored
on the mac jenkins builders:
obj/Debug/android-24/mcw/Java.Nio.Channels.FileChannel.cs(10,213): error CS0738: 'FileChannel' does not implement interface member 'ISeekableByteChannel.Position(long)'. 'FileChannel.Position(long)' cannot implement 'ISeekableByteChannel.Position(long)' bec
ause it does not have the matching return type of 'ISeekableByteChannel'.
obj/Debug/android-24/mcw/Java.Nio.Channels.FileChannel.cs(10,213): error CS0738: 'FileChannel' does not implement interface member 'ISeekableByteChannel.Truncate(long)'. 'FileChannel.Truncate(long)' cannot implement 'ISeekableByteChannel.Truncate(long)' bec
ause it does not have the matching return type of 'ISeekableByteChannel'
On Windows, `Array.Copy()` will throw an `ArgumentException` for various Git
MSBuild tasks. Turns out the call is using the wrong variable: the
string instead of the array. I am not sure why this works on macOS, I
suspect Mono isn't validating input the same way as Windows and it
_happens_ to work.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58405
When using `Android.OS.Bundle` to retrieve a collection for a specific
key one can either use the untyped `Get` method or one of the
generic `Get*ArrayList` methods to retrieve the list. In the first
case we will get back an `IList` instance, in the second case we'll
get an `IList<T>` instance. However, if one calls `Get` first and then
one of the generic methods next, for the same key, the result will be
a thrown `InvalidCastException` because we attempt to cast the `IList`
obtained from `Get` to `IList<T>` needed by the generic `Get*ArrayList`
method. This happens because the same native handle is used in both cases
and the first call to `Get` causes `Java.Lang.Object` to cache the `IList`
instance so that the second call to `Get*ArrayList` gets the cached object
instead of a new, properly typed, one.
The solution is to extend `Java.Lang.Object.PeekObject` to allow specifying
the desired type of the object corresponding to the native handle and, if
the requirement isn't met, evict the entry from the cache returning `null`
to the caller, thus letting it do the right thing by creating an instance
of a class with correct type.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57342
The investigation in the bug suggests that we are picking up a
reference assembly rather than a the actual implementation.
This is to do with the way netstandard nuget packages work, they
include both `ref` and `lib` folders.
In this case `ref` was being included in the package rather than
`lib`. This commit alters the `_ResolveAssemblies` to use
@(ReferenceCopyLocalPaths)
This ItemGroup is populated with the correct items.
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=56690
There is an issue in the current way we merge manifest document
`android:name` values. We do NOT process the `.foo` style name
values into `{packagename}.foo` . The component team currently
do this manually. It really should be done in our toolchain,
since users will probably hit this.
This commit adds a new step when merging in the library manifest
elements to fix up those values. It also adds a unit test to
check that we not only fix up those values for library projects
but also fix up the [`${applicationId}` place holder][1].
[Android documentation on this topic.][2]
All of the attributes which allow the replacement of a `.` with the
manifest package name have been included in this PR.
[1]: https://bugzilla.xamarin.com/show_bug.cgi?id=56690
[2]: https://developer.android.com/guide/topics/manifest/manifest-intro.html
The test was using the global cache to store the downloaded files.
As a result if we get multiple tests/commits building at the
same time we end up deleting files half way through a test run.
So lets make use of a local cache for the test by using the
`XAMARIN_CACHEPATH` environment variable.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57645
- fixed by this commit:
commit ee94279affccc16396cf97aac281e287515c866f
Author: Radek Doulik <rodo@xamarin.com>
Date: Fri Jul 28 16:28:12 2017 +0200
[linker] added workaround for invalid type forwards
- fixes#57645
- ignore invalid forwards of nested types of exported forwarded
types, which were added by a bug in csc. description by Marek Safar
from https://bugzilla.xamarin.com/show_bug.cgi?id=57645#c13
Native csc (pre-Roslyn version) when encountered typeforwarded
type it added automatically all its nested types including
private/protected/internal ones. This bug was fixed in Roslyn
csc but there are still many assemblies compiled with native csc
(pre VS2015) which can have typeforwarded typeref to a type which
is not available because it's not included in public API.
- ignoring these forwarders here should be harmless, because if these
types were used somewhere in the application, the linker would fail
in the mark step, when trying to resolve the typereference to them
- also added throwing the LoadException in case of missing non-nested
forwarded exported types, instead of just crashing with
System.NullReferenceException
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=56075
`//application/@android:debuggable` should not be `true` set when
packaging apps in the Release `$(Configuration)`.
Looks like there was a change to either the IDE or the template
for VS2017. Rather than leaving DebugType blank or not setting it
in the new project it gets a value of 'None'. As a result our code
which decides if this is a debug build, which only checks for ''
fails.
This commit adds a check for "None" and adds the appropriate unit tests.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=30909
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=51293
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=55473
Bump to xamarin-android-api-compatibility/master/6fe9b17f.
Add `Documentation/HowToAddNewApiLevel.md`, to describe the process
for binding new API levels, including enumification.
Enumify API-26.
Update `build-tools/enumification-helpers` to support the latest
droiddoc `packages.html` format.
API-26 changed `Activity.findViewById(int)` to be a generic method.
Remove the `<typeParameters/>` element and "fix" the return type so
that we don't break API compatibility, as `generator` doesn't
currently do anything sane here. (Specifically, all generic
paramaters are currently bound as `Java.Lang.Object`, *even if* the
type parameter has a constraint which provides a more specific type!)
Fix binding of `Java.Nio.FileChannel` so it can be actually bound,
related `SeekableByteChannel` support fixes.
Remove `//implements[@name='AutoCloseable']` and
`//implements[@name='Destryable']`, as they add Java `default`
interface methods which can't be sanely supported at this time.
Update `api-merge` to change `default` interface methods to
non-`default` methods when merging with an older API level which
contained the non-`default` interface method. This preserves backward
compatibility with existing assemblies and source code. Remove the
associated workarounds.
Bump xamarin-android-api-compatibility to check against the
latest-and-greatest API-26 binding.
Commit 97f08f78 "broke" the `javadoc2mdoc.csproj` build by causing it
to use was using the wrong `$(OutputPath)` value, as
`Configuration.props` wasn't `<Import/>`ed, and thus
`$(XAInstallPrefix)` was undefined.
Consequently, instead of `javadoc-to-mdoc.exe` being built into
`bin/$(Configuration)/lib/xamarin.android/xbuild/Xamarin/Android`,
as was desired, it was instead built into
`tools/javadoc2mdoc/xbuild/Xamarin/Android`.
Add the appropriate `<Import/>` so `javadoc-to-mdoc.exe` is placed
into the correct directory.
I'm not entirely sure what posessed me to use
`Environment.GetCommandLineArgs()` to determine the location of
`setup-windows.exe`, from which the installation prefix is derived.
It seemed like a good idea at the time?
Regardless, the problem with using `Environment.GetCommandLineArgs()`
in this fashion is that you can't execute the utility without
providing the full path name:
> cd C:\xa-sdk\oss-xamarin.android_v7.4.99.60_Darwin-x86_64_master_4f3d604\bin\Debug\bin
> .\setup-windows.exe
setup-windows.exe: This program must be run from the `bin` directory.
This is decidedly dumb.
Update the logic to instead use
`typeof(SetupWindows).Assembly.Location`. which will behave in a more
reasonable fashion.
Additionally, update `UsingJenkinsBuildArtifacts.md` so that the
mentioned macOS+Windows versions actually contain `setup-windows.exe`,
instead of hand-waving things away.
Finally, fix `Xamarin.Android.sln` so that Visual Studio for Mac
doesn't show an "Invalid configuration mapping" error status on the
`setup-windows` project.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58169
We have a bit of a problem with the way we deal with embedding
resources (i.e AndroidResource) into an Android dll.
The process usually goes as follows
1) Collect all the resources into an intermediate directory
`%(IntermediateOutputPath)__libray_project_imports__`
2) Create a zip file which contains all of those files
3) Embed that zip into the assembly when we compile.
This seems logical until you look at it from a repeat build
point of view. The senario is that a user changes some C# code
in the android dll. The build process currently does steps
1,2 for ALL changes. So we create a new zip and add that to
the dll. The result of which is as far as the application build
process is concerned its a new zip.. with new files. So we end up
running `_AddLibraryProjectsEmbeddedResourceToProject` and then
in turn `_UpdateAndroidResgen` which then in turn will probably
result in an apk build!
All of that happens even though we NEVER touched the resources, we only
touched the C# code.
So in order to fix this we need to look at things slightly differently.
Instead of creating a new zip each time we build, we should incrementally
update/refresh the one we have in the intermediate directory already.
This means not only just updating files but also REMOVING deleted files
from the existing zip file.
By doing this we can maintain the `ModifiedDate` values in the zip, which
can be used later in the build process to decide if thing were changed or
not.
So to implement this we need to change a few things. Firstly the task
`RemoveUnknownFiles` has been updated to output a new `RemovedFiles`
property. This is a ITaskItem which contains a list of the files that
were removed from the build. Next up `CreateManagedLibraryResourceArchive`
is modified to make use of this new data via the `RemovedAndroidResourceFiles`
property. We use this to delete files from the intermediate directory and
zip file which have been removed from the project.
We also update `CreateManagedLibraryResourceArchive` to make use of the
existing zip rather than creating a new one each time. As well as updating
the `Files.ExtractAll` to allow it to refresh files and remove item from the
zip which we do not expect.
The result of these changes means that changing C# code will result in the
existing zip from the previous build being used for resources. If we do
change a resource then only that item in the zip is refreshed.
These changes then filter down to the `ResolveLibraryProjectImports` task
which is responsible for maintaining the `__library_projects__` directory.
We update this task to make use of the new information available to us in
the zip file to ensure that we only update files which have been changed.
We also only update the .stamp file if we have changed files.
The last piece of the puzzle is to change the `_UpdateAndroidResgen` target
to NOT use the `@(ReferencePath);@(ReferenceDependencyPaths)` ItemGroups
as its inputs. If we leave this as is even if we update the C# code the target
will still run because the dll is newer than the `$(_AndroidResgenFlagFile)`.
So we alter this to use the various stamp files we produce to show the
resources were updated. This means that this task will run only when we have
a change.
A new unit test has been added to test out this entire process and to ensure that
the targets and things that should be updated and removed are.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57281
One of the problems we have with downloading content is the DesignTimeBuilds.
We CANNOT allow a DesignTimeBuild to download stuff from the internet.
It will lock up the IDE for however long it takes to get the data
and the user will have no indication as to what is going on.
That said... in order to get intellisense working we need to make
sure that a default Xamarin.Forms project will at least build in
DesignTime mode.
So we have a problem. We cannot download stuff, but we need it to build.
Fortunately commit 4f10438c allowed the
`<GetAdditionalResourcesFromAssemblies/>` Task to look in the
android-sdk/extras folder to get its required resources. So we can alter the
Task to allow that part to happen, this will extract the data to the correct
location. But we will still make sure that we do not download any additional
data from the internet.
So providing the m2repository bits are installed in the android-sdk/extras
these changes will allow those to be extracted in a DesignTimeBuild.
The idea is those extras should be installed as part of the main installer,
which will allow the default project to build. Obviously if those extras
are not installed the build will still fail. But as already stated
that cannot be avoided.
We also added `$(DesignTimeBuild)` to the property cache files so we can
ensure that when we do switch to a main build we run
`GetAdditionalResourcesFromAssemblies` again.
I really didn't want to do this. I wanted the Xamarin.Android SDK on
Windows to be usable side-by-side, so that multiple
`oss-xamarin.android*.zip` files could be extracted, and developers
could switch between them by overriding MSBuild properties.
This is what was documented in commit 87ca2737, by overriding the
`$(TargetFrameworkRootPath)` MSBuild property.
There's just one "minor" problem with that approach: it only works if
the project that is being built, and *all* project dependencies, are
Xamarin.Android projects. If *any* other kind of dependency is brought
in, this approach will no longer work, as the `GetReferenceAssemblies`
target -- which looks for assemblies *rooted within
`$(TargetFrameworkRootPath)`* -- won't be able to find them.
Unfortunately, *everything of interest* doesn't fit within this
restriction. A Xamarin.Forms app, or any other app using PCL
assemblies, quickly runs afoul of it:
error MSB3644: The reference assemblies for framework ".NETPortable,Version=v4.5,Profile=Profile259" were not found.
Consequently, the instructions from commit 87ca2737 are borderline
worthless. There is only one way to actually build such projects, and
that's to install Xamarin.Android *system-wide*, so that MSBuild's
`GetReferenceAssemblies` target can find everything it needs.
:-(
Thus, we need an "installer." I was hoping for a simple `.cmd` file,
but that stymied me. Then I hoped for a PowerShell script, but
installation requires access to the `%VSINSTALLDIR%` environment
variable, which is only exported from
Visual Studio Developer Command Prompts, and all the solutions I found
to import the VS command prompt environment info into PowerShell
looked decidedly ugly.
Which brings us to a minimal effort command-line installer:
`setup-windows.exe`. This utility backs up existing installs, then
creates symbolic links within the system-wide directories, pointing
them into the extracted `oss-xamarin.android*.zip` contents which
contains `setup-windows.exe`.
`setup-windows.exe /uninstall` is also provided, to put directories
back the way they were found.
`Documentation/UsingJenkinsBuildArtifacts.md` has been updated
accordingly.
- measure JNIEnv.Initialize end
- added timing definitions file parameter to the ProcessLogcatTiming
task. It contains data series labels and regex patterns to match
logcat lines with timestamp, separated by '=' character. see
build-tools/scripts/TimingDefinitions.txt as an example. it can
also contains comments, on the lines starting with '#' character
if the pattern contains match named message, then the logger uses
this match value instead of whole matched line (without timestamp)
Context: https://github.com/xamarin/xamarin-android/pull/253#discussion_r82862993
The *intention* is that Jenkins-produced `oss-xamarin.android*.zip`
artifacts be usable on Windows, so that side-by-side testing can be
performed without replacing the system installation. Usage is in
[UsingJenkinsBuildArtifacts.md](Documentation/UsingJenkinsBuildArtifacts).
This isn't *entirely* the case. It was *apparently* the case at the
time of commit 87ca2737, but things have bitrotten since. For
example, following the 87ca2737 instructions would currently result
in an XA0020 `Could not find monodroid` error, because
`class-parse.exe` wasn't where Windows expects it to be (it was in
`lib/mandroid`, not `lib/xbuild/Xamarin/Android`).
This needs to be fixed.
Additionally, PR #253 mentions that, for filesystem organization, it
would be useful if the macOS/Linux directory structure --
`$prefix/bin`, `$prefix/lib/mandroid`,
`$prefix/lib/xbuild/Xamarin/Android`, `$prefix/lib/xbuild-frameworks`
-- more closely resembled the Windows directory structure of
`$MSBuild` and `$ReferenceAssemblies` (as seen in `.vsix` files).
This would turn macOS/Linux into using `$xa_prefix/xbuild` and
`$xa_prefix/xbuild-frameworks` directories.
`$prefix/bin` would only contain `xabuild`. What is currently in
`$prefix/lib/mandroid` would be merged with
`$xa_prefix/xbuild/Xamarin/Android`.
`$xa_prefix` would `$prefix/lib/xamarin.android`.
This would turn the current macOS structure:
$prefix/bin/xabuild
$prefix/bin/generator
$prefix/bin/cross-arm
$prefix/lib/mandroid/generator.exe
$prefix/lib/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll
$prefix/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets
Into:
$prefix/bin/xabuild
$prefix/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll
$prefix/lib/xamarin.android/xbuild/Xamarin/Android/generator.exe
$prefix/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets
$prefix/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/cross-arm
Other notes:
* The `bundle-*.zip` filename has been has been changed to include a
*hash* of the contents of various files, in particular
`build-tools\mono-runtimes.*`. This was instigated via a
conversation with @kumpera about making the filename more
"idiot-proof": `mono-runtimes.props` contains *compiler flags*,
and if any of those change, then *logically* the bundle should
differ as well, as the mono runtimes may differ in significant
ways. In theory, the `-vXX` version should be used to track this,
but this is a manual change, easy to overlook. The new `-hHASH`
part of the filename should be more automagic.
The new `<HashFileContents/>` task in `xa-prep-tasks.dll` is
responsible for creating the hash value.
* `Configuration.Java.Interop.Override.props` was moved into
`build-tools/scripts`, because that would cleanup the root
directory a bit.
* OS-specific binaries are now placed into
`$prefix/lib/xamarin.android/xbuild/Xamarin/Android/$(HostOS)`.
On a theoretical plus side, this means that the same build
directory can contain OS-specific binaries for multiple operating
systems. (I don't know if anyone shares a build tree between e.g.
macOS and Linux, but if anyone *does*...)
Unfortunately this requires a workaround for an `xbuild` bug:
`%(_LlvmRuntime.InstallPath)` and
`%(_MonoCrossRuntime.InstallPath)` *cannot* use MSBuild
properties, e.g. `<InstallPath>$(HostOS)/</InstallPath>` doesn't
work as desired; it's instead treated literally.
Special-case `%(InstallPath)` until we fully migrate to MSBuild.
* `$(MonoAndroidToolsDirectory)` should be considered *dead*, along
with `$(MonoAndroidBinDirectory)`, as these should now *always*
be the same directory as where `Xamarin.Android.Build.Tasks.dll`
is located, or a `$(HostOS)` sub-directory.
* `Xamarin.ProjectTools.csproj` needed to be updated to ensure that
the build order was correct.
* Remove all `[Obsolete]` and unreferenced members from
`Xamarin.Android.Build.Utilities.dll`. There's too much in there,
and it makes my head hurt trying to understand the
interrelationships between it all. If it's not used, it's gone.
* The changes to `src/monodroid/jni/Android.mk` are...weird. The
removal of `-I$(topdir)/libmonodroid/zip`/etc. is to reduce use of
non-existent paths, as `$(topdir)` isn't defined, so that's
*actually* `-I/libmonodroid/zip`, which is nonsensical. So far,
so good. What's *odd* is the addition of `$(LOCAL_PATH)` to
`$(LOCAL_C_INCLUDES)`: This is needed so that
`external/mono/support/zlib-helper.c` exports `CreateZStream` and
related symbols, otherwise we get a unit test failure in
`GzipStreamTest.Compression` due to an
`EntryPointNotFoundException`, because `CreateZStream` isn't
exported/public.
What's odd here is that I don't understand what caused this
behavior to change. Previous builds exported `CreateZStream`,
otherwise the tests would fail, and I don't understand how any of
the other changes in this PR would be at fault, though that's
certainly the most plausible explanation.
Regardless, `-Ijni` *first* (due to adding `$(LOCAL_PATH)` to
`$(LOCAL_C_INCLUDES)`) is the desired behavior, so that
`jni/config.h` is included, thus ensuring that `MONO_API` has the
required definition when building `zlib-helper.c`.