AArnott / Library.Template

A template for a NuGet package with tests, stylecop, fxcop, versioning, and Azure Pipelines build ready to go.
MIT License
131 stars 26 forks source link

Repo Root path for BaseOutputPath fails on IOS and MacCatalyst projects #115

Closed SteveBush closed 3 years ago

SteveBush commented 3 years ago

I'm developing a MAUI project based on a modified version of the Library.Template. The project includes a shared library, MAUI app (IOS, MacCatalyst, Android), and a set of unit tests. I have modified the all of projects to use so I can have different targeted frameworks for the library, unit tests, and MAUI App.

Everything works great except the IOS and MacCatalyst builds which cannot handle a fully qualified path for BaseOutputPath. If I comment out the following lines in the repo root Directory.Build.props, it builds fine locally. However, the bin and obj directories are now per project.

    <BaseIntermediateOutputPath>$(RepoRootPath)obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
    <BaseOutputPath Condition=" '$(BaseOutputPath)' == '' ">$(RepoRootPath)bin\$(MSBuildProjectName)\</BaseOutputPath>
    <PackageOutputPath>$(RepoRootPath)bin\Packages\$(Configuration)\</PackageOutputPath>

When I build, I get the following error:

Error   MSB4184 The expression "[MSBuild]::MakeRelative(D:\GitHub\NetworkVisor\Build.Test\src\NetworkVisor.Core.Devices.Test\D:\GitHub\NetworkVisor\Build.Test\bin\NetworkVisor.Core.Devices.Test\Debug\net6.0-maccatalyst\maccatalyst-x64\publish\, D:\GitHub\NetworkVisor\Build.Test\src\NetworkVisor.Core.Devices.Test\..\..\bin\NetworkVisor.Core.Devices.Test\Debug\net6.0-maccatalyst\maccatalyst-x64\NetworkVisor.Core.Devices.Test.app\\Contents\MonoBundle\)" cannot be evaluated. The given path's format is not supported.   NetworkVisor.Core.Devices.Test  C:\Program Files\dotnet\packs\Microsoft.MacCatalyst.Sdk\15.0.100-preview.7.230\targets\Xamarin.Shared.Sdk.targets   1   

I believe the offending code is in C:\Program Files\dotnet\packs\Microsoft.MacCatalyst.Sdk\15.0.100-preview.7.230\targets\Xamarin.Shared.Sdk.targets:

The calls to $([MSBuild]::MakeRelative($(MSBuildProjectDirectory)\$(PublishDir) assumes $(PublishDir) is a relative path (bin). I cannot figure out how to get around this assumption and support IOS and MacCatalyst builds with root level obj and bin folders.

    <!-- Look in the NativeReference items for frameworks that need to be added to the app bundle, and add all those frameworks to ResolvedFileToPublish (as separate files) -->
    <Target Name="_ComputeFrameworkFilesToPublish" DependsOnTargets="_ExpandNativeReferences;_ComputeVariables">
        <ItemGroup>
            <!-- Expand each framework (which are directories) into all the files in the framework -->
            <!-- Support a 'CopyToAppBundle' metadata that can be set to 'false' to avoid copying a framework to the app bundle -->
            <_FrameworkFilesToPublish Include="%(_FrameworkNativeReference.RootDir)%(_FrameworkNativeReference.Directory)/**/*" Condition="'%(_FrameworkNativeReference.Kind)' == 'Framework' And '%(_FrameworkNativeReference.CopyToAppBundle)' != 'false'">
                <_FrameworkIdentity>%(RootDir)%(Directory)</_FrameworkIdentity>
                <_FrameworkPath>$([MSBuild]::MakeRelative($(MSBuildProjectDirectory)\$(PublishDir),$(_AppBundleFrameworksDir)))\%(Filename).framework</_FrameworkPath>
                <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
            </_FrameworkFilesToPublish>

            <!-- Compute the relative path of each file in the framework relative to the framework directory -->
            <_FrameworkFilesToPublish Update="@(_FrameworkFilesToPublish)">
                <_FrameworkRelativePath>$([System.String]::Copy('%(Identity)').Substring($([System.String]::Copy('%(_FrameworkIdentity)').Length)))</_FrameworkRelativePath>
            </_FrameworkFilesToPublish>

            <!-- Add all the framework files to ResolvedFileToPublish -->
            <ResolvedFileToPublish Include="@(_FrameworkFilesToPublish)">
                <RelativePath>%(_FrameworkFilesToPublish._FrameworkPath)\%(_FrameworkFilesToPublish._FrameworkRelativePath)</RelativePath>
                <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
            </ResolvedFileToPublish>
        </ItemGroup>
    </Target>

Any advice on whether this is a Xamarin framework bug or something I need to code around in my project. The only solution I've found to work is to turn off root bin and obj publishing for the entire solution. I've tried to disable this for only net6.0-ios and net6.0-maccatalyst builds but this didn't work.

Thanks.

SteveBush commented 3 years ago

Closing. This is fixed in RC2 of Xamarin.IOS.