Skip to content

[xabuild] Support using msbuild from mono 4.8+ - #637

Merged
dellis1972 merged 1 commit into
dotnet:masterfrom
jonpryor:jonp-xabuild-msbuild
Jun 15, 2017
Merged

[xabuild] Support using msbuild from mono 4.8+#637
dellis1972 merged 1 commit into
dotnet:masterfrom
jonpryor:jonp-xabuild-msbuild

Conversation

@jonpryor

@jonpryor jonpryor commented Jun 7, 2017

Copy link
Copy Markdown
Contributor

tools/scripts/xabuild is an MSBuild wrapper to easily build
Xamarin.Android apps from the command-line, using the Xamarin.Android
binaries built in-tree; see e20863e.

xabuild originally invoked xbuild; commit 6805d20 extended that
to support building with msbuild by setting the MSBUILD
environment variable:

    MSBUILD=msbuild .../tools/scripts/xabuild SomeProject.csproj

This use worked with Mono 4.4 and 4.6, but broke -- unnoticed -- in
Mono 4.8 and later. When attempting to use msbuild in more recent
mono versions, the build will fail, cryptically:

    xamarin-android/bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets(1007,2):
    error MSB3191: Unable to create directory "/Debug/". Access to the path "/Debug/" is denied.

The directory /Debug/ is mentioned because the
$(BaseIntermediateOutputPath) MSBuild property is not being set.
Normally we'd be creating e.g. obj/Debug, but without
$(BaseIntermediateOutputPath), this becomes /Debug, and everything
breaks.

$(BaseIntermediateOutputPath) isn't set, in turn, because
Microsoft.Common.props isn't being imported.
Microsoft.Common.props isn't being imported because xabuild
overrides the $MSBuildExtensionsPath environment variable, and
MSBuild is trying to import
$(MSBuildExtensionsPath)\...\Microsoft.Common.props, which doesn't
exist when we've overridden $MSBuildExtensionsPath to use our
in-tree build location.

A fix for this could be not overriding $MSBuildExtensionsPath
when using msbuild. There is one problem with this, though: not
overriding $MSBuildExtensionsPath means that the .targets files in
e.g. bin/Debug/lib/xbuild/Xamarin/Android will not be used.
Instead, the system files are used, which is undesirable.

Unfortunatley, this means we need to continue overriding
$MSBuildExtensionsPath, while allowing e.g.
$(MSBuildExtensionsPath)\...\Microsoft.Common.props to be found.
Square this circle by symlinking everything in the system
$MSBuildExtensionsPath directory into our $prefix/lib/xbuild.

Symlinking all these files raises another issue: we don't want all
of these symlinks, or their targets, to be added to the
oss-xamarin.android*.zip files. Support this by creating a
$prefix/lib/xbuild/.__sys_links.txt file, which contains zip -x
patterns (hence the /* suffix for directories), one per line, and
update the make package-oss target to look for and exclude the
contents of these files so that we don't "pollute" the
oss-xamarin.android*.zip file with unnecessary contents.

Finally, some cleanups:

  • Only set $XBUILD_FRAMEWORK_FOLDERS_PATH when using xbuild.

  • Additionally, specify $(TargetFrameworkRootPath) on msbuild,
    as that actually works.

  • Always specify $(MonoAndroidBinDirectory) and
    $(MonoAndroidToolsDirectory), as this mirrors the
    Windows usage instructions.

  • Don't require that $ANDROID_NDK_PATH and $ANDROID_SDK_PATH be
    set prior to executing xabuild, or that we be running in-tree
    (to use Paths.targets). The NDK, in particular, isn't always
    required, so forcing that it be set is annoying.

    The build process will error out appropriately if required
    directories cannot be found.

@jonpryor

jonpryor commented Jun 7, 2017

Copy link
Copy Markdown
Contributor Author

Question: one problem with this PR is it basically "hardcodes" 15.0. Is there a better way to symlink files? There are 49 files in e.g. /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/xbuild (Mono 5.2); perhaps we should just symlink all of them?

@radical

radical commented Jun 7, 2017

Copy link
Copy Markdown
Member

perhaps we should just symlink all of them?
Yeah, I think we should do that for now.

@grendello

Copy link
Copy Markdown
Contributor

As suggested on slack, we can use

$ echo 'Console.WriteLine (System.IO.Path.GetFullPath (System.IO.Path.GetDirectoryName (typeof (int).Assembly.Location) + "/../../../"))'|csharp
/home/grendel/devel/mono/mono-master/

Which actually runs the default mono and doesn't rely on symlinks or versions. Not pretty, but effective IMO

@jonpryor

jonpryor commented Jun 7, 2017

Copy link
Copy Markdown
Contributor Author

@grendello wrote:

Which actually runs the default mono and doesn't rely on symlinks

I don't see how it doesn't rely on symlinks. The reason for the symlinks is so that our "in-tree $MSBuildExtensionsPath environment mirrors mono's environment," without needing to copy/otherwise sync them together.

Mono's $prefix is only interesting in that it allows us to create the symlink.

@grendello

Copy link
Copy Markdown
Contributor

It doesn't rely on symlinks in the sense that there isn't a requirement for them to exist before the $prefix detection code is executed.

@jonpryor
jonpryor force-pushed the jonp-xabuild-msbuild branch from b4bf5ea to eca6d9b Compare June 14, 2017 20:28
@jonpryor

Copy link
Copy Markdown
Contributor Author

PR updated to entirely remove any requirement for symlinks.

The "problem" with msbuild is that the $MSBuildExtensionsPath environment variable is set. However, it is not required to set it in order to use our in-tree contents. We can instead set $(TargetFrameworkRootPath).

@jonpryor

Copy link
Copy Markdown
Contributor Author

...and eca6d9b is wrong. Well, half right.

MSBUILD=msbuild tools/scripts/xabuild /t:SignAndroidPackage /v:diag samples/HelloWorld/*.csproj > b.txt

no longer dies while attempting to create the directory /Debug. So that's a plus.

Additionally, it is trying to use the appropriate assemblies:

      Resolved file path is "/…/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll". (TaskId:22)

However, the targets files are not used:

Target "_ComputeAndroidAssetsPaths: (TargetId:30)" in file "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.targets" from project "/…/work/xamarin-android/samples/HelloWorld/HelloWorld.csproj" (target "UpdateAndroidAssets" depends on it):

Doh!

@jonpryor
jonpryor force-pushed the jonp-xabuild-msbuild branch from eca6d9b to ffd6376 Compare June 15, 2017 00:51
@jonpryor

Copy link
Copy Markdown
Contributor Author

Commit ffd6376 allows the in-tree .targets files to be used, as desired. This is done by symlinking all the things, plus some additional "bookkeeping" so that we don't include the symlinks in the oss-xamarin.android*.zip file.

TODO: what happens with the .vsix?

@jonpryor

Copy link
Copy Markdown
Contributor Author

TODO: what happens with the .vsix?

I had mistakenly believed that Jenkins would hit the make create-vsix path, but it doesn't.

Trying locally, it fails:

error VSSDK1025: Could not add the file "../../bin/Debug/lib/xbuild/Microsoft.NuGet.Build.Tasks.dll" to the zip package "bin/Debug/Xamarin.Android.Sdk.vsix".

...which isn't a good sign.

`tools/scripts/xabuild` is an MSBuild wrapper to build Xamarin.Android
apps from the command-line, using the built in-tree binaries;
see commit e20863e.

`xabuild` originally invoked `xbuild`; commit 6805d20 extended that
to support building with `msbuild` by setting the `MSBUILD`
environment variable:

	MSBUILD=msbuild .../tools/scripts/xabuild SomeProject.csproj

This use worked with Mono 4.4 and 4.6, but broke -- unnoticed -- when
running under Mono 4.8 and later. When attempting to use `msbuild`
from Mono 4.8 and later, the build will fail, cryptically:

	xamarin-android/bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets(1007,2):
	error MSB3191: Unable to create directory "/Debug/". Access to the path "/Debug/" is denied.

The directory `/Debug/` is mentioned because the
`$(BaseIntermediateOutputPath)` MSBuild property is not being set.
*Normally* we'd be creating e.g. `obj/Debug`, but without
`$(BaseIntermediateOutputPath)`, this becomes `/Debug`, and everything
breaks.

`$(BaseIntermediateOutputPath)` isn't set, in turn, because
`Microsoft.Common.props` isn't being imported.
`Microsoft.Common.props` isn't being imported because `xabuild`
overrides the `$MSBuildExtensionsPath` environment variable, and
MSBuild is trying to import
`$(MSBuildExtensionsPath)\...\Microsoft.Common.props`, which doesn't
exist when we've overridden `$MSBuildExtensionsPath` to use our
in-tree build location.

*A* fix for this *could* be *not overriding `$MSBuildExtensionsPath`*
when using `msbuild`. There is one problem with this, though: not
overriding `$MSBuildExtensionsPath` means that the `.targets` files in
e.g. `bin/Debug/lib/xbuild/Xamarin/Android` *will not be used*.
Instead, the *system* files are used, which is undesirable.

Unfortunatley, this means we need to continue overriding
`$MSBuildExtensionsPath`, *while* allowing e.g.
`$(MSBuildExtensionsPath)\...\Microsoft.Common.props` to be found.
Square this circle by *symlinking* everything in the *system*
`$MSBuildExtensionsPath` directory into our `$prefix/lib/xbuild`.

Symlinking all these files raises *another* issue: we *don't* want all
of these symlinks, *or their targets*, to be added to the
`oss-xamarin.android*.zip` and `Xamarin.Android*.vsix` files. Support
this by creating a `$prefix/lib/xbuild/.__sys_links.txt` file, which
contains `zip -x` patterns (hence the `/*` suffix for directories),
one per line, and update the `make package-oss` target to look for and
exclude the contents of these files so that we don't "pollute" the
`oss-xamarin.android*.zip` file with unnecessary contents.

Similarly, update the `create-vsix` project so that instead of
including `$(LibDir)xbuild\**\*.*`, it instead only includes the
contents of `$(LibDir)\xbuild\Novell\**\*.*` and
`$(LibDir)\xbuild\Xamarin\**\*.*`.

Finally, some cleanups:

  * Only set `$XBUILD_FRAMEWORK_FOLDERS_PATH` when using `xbuild`.

  * Additionally, specify `$(TargetFrameworkRootPath)` on `msbuild`,
    as that MSBuild property can actually be overridden w/ `msbuild`.

  * Always specify `$(MonoAndroidBinDirectory)` and
    `$(MonoAndroidToolsDirectory)`, as this mirrors the
    Windows usage instructions.

  * Don't *require* that `$ANDROID_NDK_PATH` and `$ANDROID_SDK_PATH` be
    set prior to executing `xabuild`, *or* that we be running in-tree
    (to use `Paths.targets`). The NDK, in particular, isn't always
    required, so requiring that it be set is annoying.

    The build process will error out appropriately if required
    directories cannot be found.
@jonpryor
jonpryor force-pushed the jonp-xabuild-msbuild branch from ffd6376 to 8b8fa5c Compare June 15, 2017 12:42
@jonpryor

Copy link
Copy Markdown
Contributor Author

.vsix creation should be fixed in 8b8fa5c.

@dellis1972
dellis1972 merged commit aa1db83 into dotnet:master Jun 15, 2017
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request May 1, 2020
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)
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request May 1, 2020
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)
jonpryor added a commit that referenced this pull request May 2, 2020
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)
jonpryor added a commit that referenced this pull request May 6, 2020
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)
@github-actions github-actions Bot locked and limited conversation to collaborators Feb 2, 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.

5 participants