Closed damphyr closed 6 months ago
This is a problem with the msbuild tasks for the Android build ( I say that, because in every other context the method works: Project has Azure/Azure Functions, ASP.NET Core and Xamarin code).
The BaseOutputPath and BaseIntermediatePath are not yet set when certain tasks run (if you use an underpowered VM you will notice that the directories for the build (obj\Release\90 etc.) are created before the nuget restore.
The Directory.Build.props hook is explicitly there to provide values for properties early on and as a way to share values across projects (https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019) but the Xamarin.Android tasks are somehow running before it is loaded.
The workaround is to explicitly set the values in the project but this defeats the purpose of using Directory.Builds.pros and having everything in one place.
I can't get this to work for a .NET framework Console app: ConsoleAppDirectoryBuild.zip
Let me know if I'm doing something wrong there.
I also wouldn't recommend setting $(BaseIntermediateOutputPath)
to the same value as $(BaseOutputPath)
, I would think that would break all kinds of things...
Maybe this would be better:
<BaseOutputPath>$(MSBuildThisFileDirectory)\out\build\$(MSBuildProjectName)</BaseOutputPath>
<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)\out\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
I think this actually an issue trying to override these two specific properties with non-SDK style projects, and it's nothing to do with Xamarin.Android. Let me know otherwise, thanks!
This is specific to a Xamarin.Android project. Every other project I created works as expected (although I haven't tried it with an iOS project yet).
What I did was create a new Xamarin.Android project and choose the first option (so a SingleView App)
As for the values of BaseInterrmediateOutputPath - obj/ is added by IntermediateOutputPath (even in the default). It is sufficient to differentiate by project. The default value for both base paths is actually the same (the project directory).
I've attached the project that reproduces the behaviour - Solution and project are in the src/ folder, expected behaviour is to have an out/ folder with everything next to src/.
Does a regular .NET framework project work for you?
We extend their MSBuild targets, so if it doesn’t work there—that is where the problem is.
Now I understood what you meant. Yes, a normal .NET Framework app works as expected. Again, used the wizard for a console app and just changed the OutputPath value in the .csproj
If as you are saying all you do is extend the tasks then I would assume the values are overwritten instead of not read at the right time.
It looks like in this PR...
It just ovewrites the value: https://github.com/xamarin/xamarin-android/blob/0b79ab6653a4364f837d513453567485c535c611/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.DefaultOutputPaths.targets#L3
This would be an easy first contribution if you didn't want to wait on us to fix this! cc me if you send a PR, thanks!
Not that easy unfortunately - that assignment is protected with a conditional on the value being empty. So I am back on the assumption that Xamarin.Android.DefaultOutputPaths.targets is called too early.
I'm successfully moving all output of a Xamarin.Android app project to a customized path with the following:
<Project>
<PropertyGroup>
<OutputPath>$(SolutionDir)artifacts/build/bin/$(Platform)/$(Configuration)/$(TargetFramework)/$(MSBuildProjectName)/</OutputPath>
<BaseIntermediateOutputPath>$(SolutionDir)artifacts/build/obj/base/$(MSBuildProjectName)/</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(SolutionDir)artifacts/build/obj/$(Platform)/$(Configuration)/$(TargetFramework)/$(MSBuildProjectName)/</IntermediateOutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
</Project>
In the same solution this also works with .NET Standard 2.1 class library projects and a .NET Core 3.0 one.
@bddckr Just to make 100% sure: You are doing it using a Directory.Build.props file for the settings and not within the .csproj file, right?
Yes, exactly that! The csproj files have no output related override in them.
Yes, exactly that! The csproj files have no output related override in them.
Could you use the XamAndroidOoB.zip and add
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
to the file there and see if it works as expected?
I see the issue now.
(AppendTargetFrameworkToOutputPath
doesn't matter here as far as I was able to confirm.)
Doing some logging in a Directory.Build.targets
file (note .targets
):
<Project InitialTargets="ValidateProjectProperties">
<Target Name="ValidateProjectProperties">
<Warning Text="BaseOutputPath: $(BaseOutputPath)" />
<Warning Text="BaseIntermediateOutputPath: $(BaseIntermediateOutputPath)" />
<Warning Text="OutputPath: $(OutputPath)" />
<Warning Text="IntermediateOutputPath: $(IntermediateOutputPath)" />
</Target>
</Project>
I can see that BaseOutputPath
and BaseIntermediateOutputPath
are empty when referenced in the .csproj
file.
If I remove the properties OutputPath
and IntermediateOutputPath
from the csproj, then MSBuild complains about OutputPath
being empty and IntermediateOutputPath
has a (default?) value of obj\Release\90
.
One workaround is therefore what I did, which is specifying the non-base properties in the Directory.Build.props
file, too:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BaseOutputPath>$(MSBuildThisFileDirectory)..\out\build\$(MSBuildProjectName)\</BaseOutputPath>
<BaseIntermediateOutputPath>$(BaseOutputPath)</BaseIntermediateOutputPath>
<OutputPath>$(BaseOutputPath)$(AssemblyName)\bin\$(Configuration)</OutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(AssemblyName)\obj\$(Configuration)</IntermediateOutputPath>
</PropertyGroup>
</Project>
(Note: I fixed the trailing slashes to be consistently defined on each property and removed the slash at the usage site of them, but this doesn't change the outcome at all - I tested it.)
Adding a class library to the same project without my workaround and yes indeed I can confirm an (SDK-style) csproj has no issue with BaseOutputPath
& BaseIntermediateOutputPath
only being in the Directory.Build.props
. Both properties are not empty when used in the csproj file, thus don't give the issue.
I didn't test whether this is the case for old csproj style projects in general or specific to Xamarin projects.
Something is normally setting the output properties derived from the base ones, but in this case it's not happening.
It appears to me that these paths are not getting set as expected for UWP projects, either.
In a side-by-side comparison of building a pretty much "stock" Xamarin app template, there are issues even when explicitly specifying each of the following:
.NET Standard Library Directories created without Directory.Build.props
Directories created with workaround Directory.Build.props
Xamarin.Android Project Directories created without Directory.Build.props
Directories created with workaround Directory.Build.props
UWP Directories created without Directory.Build.props
Directories created with workaround Directory.Build.props
With support for Classic Xamarin.Android ended May 1st, 2024, this issue is likely no longer relevant.
If this still persists in .NET 8+, please open a new issue with updated information based on net8.0-android
or greater. Please include a link to this issue for context.
Steps to Reproduce
as Directory.Build.props next to the solution (this sets the property values at an early point for msbuild and is needed for nuget restores)
Expected Behavior
All build generated files are under the\out\ directory.
Actual Behavior
Android build is in c:\$(AssemblyName)\bin NuGet packages etc. are under\out\
Version Information
Microsoft Visual Studio Professional 2019 Version 16.1.3 VisualStudio.16.Release/16.1.3+29009.5 Microsoft .NET Framework Version 4.8.03752
Installed Version: Professional
ADL Tools Service Provider 1.0 This package contains services used by Data Lake tools
Application Insights Tools for Visual Studio Package 9.1.00429.1 Application Insights Tools for Visual Studio
ASP.NET and Web Tools 2019 16.1.429.50124 ASP.NET and Web Tools 2019
ASP.NET Web Frameworks and Tools 2019 16.1.429.50124 For additional information, visit https://www.asp.net/
Azure App Service Tools v3.0.0 16.1.429.50124 Azure App Service Tools v3.0.0
Azure Data Lake Node 1.0 This package contains the Data Lake integration nodes for Server Explorer.
Azure Data Lake Tools for Visual Studio 2.3.9000.0 Microsoft Azure Data Lake Tools for Visual Studio
Azure Functions and Web Jobs Tools 16.1.429.50124 Azure Functions and Web Jobs Tools
Azure Stream Analytics Tools for Visual Studio 2.3.9000.0 Microsoft Azure Stream Analytics Tools for Visual Studio
C# Tools 3.1.1-beta4-19281-06+58a4b1e79aea28115e66b06f850c83a3f1fcb6d3 C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.
Common Azure Tools 1.10 Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.
Extensibility Message Bus 1.1.77 (master@24013d5) Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.
Fabric.DiagnosticEvents 1.0 Fabric Diagnostic Events
IntelliCode Extension 1.0 IntelliCode Visual Studio Extension Detailed Info
Microsoft Azure HDInsight Azure Node 2.3.9000.0 HDInsight Node under Azure Node
Microsoft Azure Hive Query Language Service 2.3.9000.0 Language service for Hive query
Microsoft Azure Service Fabric Tools for Visual Studio 2.5 Microsoft Azure Service Fabric Tools for Visual Studio
Microsoft Azure Stream Analytics Language Service 2.3.9000.0 Language service for Azure Stream Analytics
Microsoft Azure Stream Analytics Node 1.0 Azure Stream Analytics Node under Azure Node
Microsoft Azure Tools 2.9 Microsoft Azure Tools for Microsoft Visual Studio 0x10 - v2.9.20419.2
Microsoft Continuous Delivery Tools for Visual Studio 0.4 Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.
Microsoft JVM Debugger 1.0 Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines
Microsoft Library Manager 1.0 Install client-side libraries easily to any web project
Microsoft MI-Based Debugger 1.0 Provides support for connecting Visual Studio to MI compatible debuggers
Microsoft Visual Studio Tools for Containers 1.1 Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.
Mono Debugging for Visual Studio 16.1.1 (2473f22) Support for debugging Mono processes with Visual Studio.
Multilingual App Toolkit 4.0 Multilingual App Toolkit helps you localize your Windows Store app by providing file management, pseudo and machine translation, translation editor, and build integration. http://aka.ms/matinstall
Node.js Tools 1.5.10424.1 Commit Hash:c3ce0ae0b29c0b3a755ffc12f8a685fe7ddd3600 Adds support for developing and debugging Node.js apps in Visual Studio
NuGet Package Manager 5.1.0 NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/
ProjectServicesPackage Extension 1.0 ProjectServicesPackage Visual Studio Extension Detailed Info
ResourcePackage Extension 1.0 ResourcePackage Visual Studio Extension Detailed Info
ResourcePackage Extension 1.0 ResourcePackage Visual Studio Extension Detailed Info
SQL Server Data Tools 16.0.61904.23160 Microsoft SQL Server Data Tools
ToolWindowHostedEditor 1.0 Hosting json editor into a tool window
TypeScript Tools 16.0.10506.2004 TypeScript Tools for Microsoft Visual Studio
Visual Basic Tools 3.1.1-beta4-19281-06+58a4b1e79aea28115e66b06f850c83a3f1fcb6d3 Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.
Visual F# Tools 10.4 for F# 4.6 16.1.0-beta.19253.3+42526fe359672a05fd562dc16a91a43d0fe047a7 Microsoft Visual F# Tools 10.4 for F# 4.6
Visual Studio Code Debug Adapter Host Package 1.0 Interop layer for hosting Visual Studio Code debug adapters in Visual Studio
Visual Studio Tools for Containers 1.0 Visual Studio Tools for Containers
Visual Studio Tools for Kubernetes 1.0 Visual Studio Tools for Kubernetes
VisualStudio.Mac 1.0 Mac Extension for Visual Studio
Xamarin 16.1.0.543 (d16-1@34a619991) Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Xamarin Designer 16.1.0.418 (remotes/origin/d16-1@5b958bb10) Visual Studio extension to enable Xamarin Designer tools in Visual Studio.
Xamarin Templates 16.2.112 (4db4af4) Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.
Xamarin.Android SDK 9.3.0.22 (HEAD/8e7764fdf) Xamarin.Android Reference Assemblies and MSBuild support. Mono: mono/mono/2018-08@3cb36842fc4 Java.Interop: xamarin/java.interop/d16-1@5ddc3e3 LibZipSharp: grendello/LibZipSharp/d16-1@44de300 LibZip: nih-at/libzip/rel-1-5-1@b95cf3f ProGuard: xamarin/proguard/master@905836d SQLite: xamarin/sqlite/3.27.1@8212a2d Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-1@acabd26
Xamarin.iOS and Xamarin.Mac SDK 12.10.0.153 (750a879) Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.