Skip to content

Conversation

@jonpryor
Copy link
Contributor

Rebuilding API-O (571546a) results in a build failure:

# First build is fine:
$ make framework-assemblies API_LEVELS=26 CONFIGURATIONS=Debug

# Second+ builds are not:
$ make framework-assemblies API_LEVELS=26 CONFIGURATIONS=Debug
...
obj/Debug/android-26/mcw/Android.Content.IComponentCallbacks.cs(23,17): error CS0101: The namespace 'Android.Content' already contains a definition for 'IComponentCallbacksInvoker'
...
	 170582 Error(s)

The cause of the build error is that
Android.Content.IComponentCallbacks.cs -- among many other files --
is specified twice (!):

  • obj/Debug/android-26/mcw//Android.Content.IComponentCallbacks.cs
  • full/path/to/…/xamarin-android/src/Mono.Android/obj/Debug/android-26/mcw//Android.Content.IComponentCallbacks.cs

This in turn is related to 98880bd: There are two "environments" in
which Mono.Android.csproj is built:

  • A "clean" environment
  • A previously built environment

In the clean environment, Mono.Android.projitems -- created by
generator.exe in the _GenerateBinding target -- does not exist.
Consequently, after generator.exe is run, all of the generated
$(IntermediateOutputPath)\**\*.cs files are added to @(Compile) so
that the compiler will "see" all of the generated files and things
will build.

In the previously built environment, Mono.Android.projitems does
exist, and is <Import/>ed. The _GenerateBinding target is
skipped, "preventing" the @(Compile) group from being updated to
contain the generated files -- which is desirable, because those files
are already listed in Mono.Android.projitems, and including them
would result in "duplicating" the files provided to the compiler.

Note that the _GenerateBinding target depends on the
_GenerateApiDescription target, so that when
_GenerateApiDescription creates an api.xml file, then
_GenerateBinding will re-execute.

This is where API-O rebuilds go wrong:

  1. This is a previously built environment, so
    Mono.Android.projitems (1) exists, and (2) is <Import/>ed.
  2. The _GenerateApiDescription always executes (!).
  3. (2) results in _GenerateBinding always executing, causing the
    @(Compile) group to be updated, resulting filenames being
    provided to the compiler twice.

(2) is where things go bad:

Target _GenerateApiDescription needs to be built as input file 'Profiles/api-26.xml.in' does not exist.

Specifically, _GenerateApiDescription listed as an Input the file
Profiles\api-$(AndroidApiLevel).xml.in. However, commit 571546a
named the API-O binding Profiles\api-O.xml.in, meaning
Profiles\api-26.xml.in does not exist, and won't exist (until
API-26 is actually released as "stable" by Google, at some unknown
point in the future).

Which is why API-O rebuilds fail. :-)

The fix? Don't use $(AndroidApiLevel), use $(AndroidPlatformId).
For API-O, $(AndroidPlatformId) will have the value "O", allowing
Profiles\api-O.xml.in to be found, preventing
_GenerateApiDescription from unnecessarily executing.


This scenario does raise a potential (unresolved) workflow problem:
when:

  1. Mono.Android.csproj is built, and
  2. Profiles\api-*.xml.in is modified, and
  3. Mono.Android.csproj is built again,

then everything will break in the same manner as described here:
Mono.Android.projitems will exist, thus adding generated files to
@(Compile), then the _GenerateApiDescription & _GenerateBinding
targets will execute, re-adding files to @(Compile), and things will
break.

A subsequent rebuild will "fix" the error, so long as a
Profiles\api-*.xml.in file isn't modified, but this will be annoying
to anyone who encounters it.

*Rebuilding* API-O (571546a) results in a build failure:

	# First build is fine:
	$ make framework-assemblies API_LEVELS=26 CONFIGURATIONS=Debug

	# Second+ builds are not:
	$ make framework-assemblies API_LEVELS=26 CONFIGURATIONS=Debug
	...
	obj/Debug/android-26/mcw/Android.Content.IComponentCallbacks.cs(23,17): error CS0101: The namespace 'Android.Content' already contains a definition for 'IComponentCallbacksInvoker'
	...
		 170582 Error(s)

The cause of the build error is that
`Android.Content.IComponentCallbacks.cs` -- among many other files --
*is* specified twice (!):

* obj/Debug/android-26/mcw//Android.Content.IComponentCallbacks.cs
* full/path/to/…/xamarin-android/src/Mono.Android/obj/Debug/android-26/mcw//Android.Content.IComponentCallbacks.cs

This in turn is related to 98880bd: There are two "environments" in
which `Mono.Android.csproj` is built:

* A "clean" environment
* A previously built environment

In the clean environment, `Mono.Android.projitems` -- created by
`generator.exe` in the `_GenerateBinding` target -- does not exist.
Consequently, after `generator.exe` is run, all of the generated
`$(IntermediateOutputPath)\**\*.cs` files are added to `@(Compile)` so
that the compiler will "see" all of the generated files and things
will build.

In the previously built environment, `Mono.Android.projitems` *does*
exist, and is `<Import/>`ed. The `_GenerateBinding` target is
*skipped*, "preventing" the `@(Compile)` group from being updated to
contain the generated files -- which is desirable, because those files
are already listed in `Mono.Android.projitems`, and including them
would result in "duplicating" the files provided to the compiler.

Note that the `_GenerateBinding` target depends on the
`_GenerateApiDescription` target, so that when
`_GenerateApiDescription` creates an `api.xml` file, then
`_GenerateBinding` will *re-execute*.

This is where API-O rebuilds go wrong:

 1. This is a previously built environment, so
    `Mono.Android.projitems` (1) exists, and (2) is `<Import/>`ed.
 2. The `_GenerateApiDescription` always executes (!).
 3. (2) results in `_GenerateBinding` always executing, causing the
    `@(Compile)` group to be updated, resulting filenames being
    provided to the compiler *twice*.

(2) is where things go bad:

	Target _GenerateApiDescription needs to be built as input file 'Profiles/api-26.xml.in' does not exist.

Specifically, `_GenerateApiDescription` listed as an `Input` the file
`Profiles\api-$(AndroidApiLevel).xml.in`. However, commit 571546a
named the API-O binding `Profiles\api-O.xml.in`, meaning
`Profiles\api-26.xml.in` does not exist, *and won't exist* (until
API-26 is actually released as "stable" by Google, at some unknown
point in the future).

Which is why API-O rebuilds fail. :-)

The fix? Don't use `$(AndroidApiLevel)`, use `$(AndroidPlatformId)`.
For API-O, `$(AndroidPlatformId)` will have the value "O", allowing
`Profiles\api-O.xml.in` to be found, preventing
`_GenerateApiDescription` from unnecessarily executing.

---

This scenario *does* raise a potential (unresolved) workflow problem:
when:

 1. `Mono.Android.csproj` is built, and
 2. `Profiles\api-*.xml.in` is modified, and
 3. `Mono.Android.csproj` is built again,

then everything will break in the same manner as described here:
`Mono.Android.projitems` will exist, thus adding generated files to
`@(Compile)`, then the `_GenerateApiDescription` & `_GenerateBinding`
targets will execute, re-adding files to `@(Compile)`, and things will
break.

A subsequent rebuild will "fix" the error, so long as a
`Profiles\api-*.xml.in` file isn't modified, but this will be annoying
to anyone who encounters it.
@jonpryor jonpryor merged commit eb08bb4 into dotnet:master May 1, 2017
jonpryor pushed a commit that referenced this pull request Feb 22, 2020
Changes: dotnet/java-interop@b81cfbb...4f47ec8

Fixes: dotnet/java-interop#572

Context: dotnet/project-system#1821
Context: dotnet/java-interop#509

  * dotnet/java-interop@4f47ec8: [generator] Make DIM invoking plumbing private (#581)
  * dotnet/java-interop@2a0f863: [Java.Interop.sln] Let VS update the project type guids. (#579)
  * dotnet/java-interop@9a01c9b: [Java.Interop.Tools.Cecil] remove System.Linq in IsSubclassOf (#577)
  * dotnet/java-interop@cd33da6: [generator] Bind protected nested types (#578)
  * dotnet/java-interop@fa10e98 :[generator] Do bind package-private nested types (#575)
jonpryor pushed a commit that referenced this pull request Feb 24, 2020
Changes: dotnet/java-interop@e92f341...178e849

Fixes: dotnet/java-interop#572

Context: dotnet/project-system#1821
Context: dotnet/java-interop#509

  * dotnet/java-interop@178e849: [generator] Make DIM invoking plumbing private (#581)
  * dotnet/java-interop@b7b10bc: [Java.Interop.sln] Let VS update the project type guids. (#579)
  * dotnet/java-interop@3c590a4: [Java.Interop.Tools.Cecil] remove System.Linq in IsSubclassOf (#577)
  * dotnet/java-interop@d1bbed7: [generator] Bind protected nested types (#578)
  * dotnet/java-interop@5db30a8: [generator] Do bind package-private nested types (#575)
@github-actions github-actions bot locked and limited conversation to collaborators Feb 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants