Search code examples
c#macosxamarin.ioscakebuild

Xamarin iOS: error MSB4018: The "CompileITunesMetadata" task failed unexpectedly


After updating our iOS build server from Mac OS Catalina to Big Sur our GitLab pipelines (running ) are failing with some cryptic Xamarin specific error message for one specific project (meaning other Xamarin iOS projects are building successfully and passing the pipeline).

However checking out the exact same project (same commit, same everything) on a different Big Sur machine the project in question compiles with no errors. Note that even commits that passed previously are now failing the pipeline.

Here's the interesting part of the logs

"/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj" (Build target) (1) ->
(_CompileITunesMetadata target) -> 
  /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018: The "CompileITunesMetadata" task failed unexpectedly. [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018: System.ArgumentException: Path cannot be the empty string or all whitespace. [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018: Parameter name: path [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at System.IO.Directory.CreateDirectory (System.String path) [0x00016] in <92218043474744ea9d64d27064c35dcb>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Xamarin.iOS.Tasks.CompileITunesMetadataTaskBase.Execute () [0x001ed] in <5fc761670f214242b2d9c8c4b0525b32>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Xamarin.iOS.Tasks.CompileITunesMetadata.Execute () [0x0002a] in <5fc761670f214242b2d9c8c4b0525b32>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute () [0x00029] in <6f1ac64b362443459ae7e79676b4c67f>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask (Microsoft.Build.BackEnd.ITaskExecutionHost taskExecutionHost, Microsoft.Build.BackEnd.Logging.TaskLoggingContext taskLoggingContext, Microsoft.Build.BackEnd.TaskHost taskHost, Microsoft.Build.BackEnd.ItemBucket bucket, Microsoft.Build.BackEnd.TaskExecutionMode howToExecuteTask) [0x002b9] in <6f1ac64b362443459ae7e79676b4c67f>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
    63 Warning(s)
    1 Error(s)
Time Elapsed 00:01:16.38
An error occurred when executing task 'Build'.
Error: One or more errors occurred. (MSBuild: Process returned an error (exit code 1).)
    MSBuild: Process returned an error (exit code 1).
Cleaning up file based variables
00:00
ERROR: Job failed: exit status 1

Instead of adding random possibly unrelated code snippets we will add any relevant code or config files (.csproj, info.plist) on request accordingly as we are completely clueless as to what the possible causes may be.

If you experienced this or any similar problem before any help would be appreciated.

Edit adding more detailed logs

Target "_CompileITunesMetadata: (TargetId:343)" in file "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets" from project "/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj" (target "_CreateAppBundle" depends on it):
Building target "_CompileITunesMetadata" completely.
Output file "build-outputiTunesMetadata.plist" does not exist.
Using "CompileITunesMetadata" task from assembly "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/../iOS/Xamarin.iOS.Tasks.dll".
Task "CompileITunesMetadata" (TaskId:232)
  Task Parameter:AppBundleDir=build-outputClubmappAppIOS.app (TaskId:232)
  Task Parameter:OutputPath=build-outputiTunesMetadata.plist (TaskId:232)
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018: The "CompileITunesMetadata" task failed unexpectedly. [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018: System.ArgumentException: Path cannot be the empty string or all whitespace. [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018: Parameter name: path [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at System.IO.Directory.CreateDirectory (System.String path) [0x00016] in <92218043474744ea9d64d27064c35dcb>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Xamarin.iOS.Tasks.CompileITunesMetadataTaskBase.Execute () [0x001ed] in <5fc761670f214242b2d9c8c4b0525b32>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Xamarin.iOS.Tasks.CompileITunesMetadata.Execute () [0x0002a] in <5fc761670f214242b2d9c8c4b0525b32>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute () [0x00029] in <6f1ac64b362443459ae7e79676b4c67f>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(320,3): error MSB4018:   at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask (Microsoft.Build.BackEnd.ITaskExecutionHost taskExecutionHost, Microsoft.Build.BackEnd.Logging.TaskLoggingContext taskLoggingContext, Microsoft.Build.BackEnd.TaskHost taskHost, Microsoft.Build.BackEnd.ItemBucket bucket, Microsoft.Build.BackEnd.TaskExecutionMode howToExecuteTask) [0x002b9] in <6f1ac64b362443459ae7e79676b4c67f>:0  [/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj]
Done executing task "CompileITunesMetadata" -- FAILED. (TaskId:232)
Done building target "_CompileITunesMetadata" in project "ClubmappAppIOS.csproj" -- FAILED.: (TargetId:343)
Done Building Project "/Users/build/builds/Hh9r4va7/0/ClubMapp/application/ClubmappSolution/ClubmappAppIOS/ClubmappAppIOS.csproj" (Build target(s)) -- FAILED.

So it seems like msbuild is unable to find a file called build-outputiTunesMetadata.plist however the documentation states that this file is optional.

To supply the missing information to an Ad Hoc distribution, an optional iTunesMetadata.plist file can be created and included in the applications IPA file. This plist file is a specially formatted XML file (see Apple's Property List Programming Guide for more information) that contains key/value pairs defining information about a given iOS application.

Edit 2:

The exception seems to be thrown here in the Xamarin iOS msbuild code:

Directory.CreateDirectory (Path.GetDirectoryName (OutputPath.ItemSpec));

where the value of OutputPath.ItemSpec is "build-outputiTunesMetadata.plist" as can be seen in the logs. This filename is then passed to Path.GetDirectoryName() which probably returns "" (as there is no path in this string, only the file name). Then it tries to create a directory with the name "" yielding System.ArgumentException: Path cannot be the empty string or all whitespace. as a result.

Now how do we fix it? Where is the Path/Name of this build-outputiTunesMetadata.plist file specified?


Solution

  • We finally closed this bug ticket yesterday though the problem really wasn't too obvious. Back when .NET 5 was released we manually linked the msbuild.dll from Visual Studio for Mac to be used in compilation by mono. Therefore our build script used to look like this:

    MSBuild(projectFilePath, settings => 
    {
        settings.SetConfiguration(configuration)
            .SetVerbosity(Verbosity.Diagnostic)
            .WithTarget("Build")
            .WithProperty("Platform", "iPhone")
            .WithProperty("BuildIpa", "true")
            .WithProperty("OutputPath", buildResultDir + System.IO.Path.DirectorySeparatorChar)
            .WithProperty("TreatWarningsAsErrors", "false");
        settings.ToolPath = new FilePath("/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/MSBuild.dll");
    });
    

    (Note how we appended System.IO.Path.DirectorySeparatorChar after our build-output directory).

    Now for some reason this / was ignored during compilation, meaning directly merged the directory name build-output and the filenames (for example iTunesMetadata.plist).

    As the build script worked before updating Mac OS, XCode and the Visual Studio for Mac instance of the build server we removed the manually specified MSBuild.dll instance which solved the problem at hand and as mono now has build in support for .NET 5 we didn't need this workaround anyways.

    Our current build script therefore looks like this:

    MSBuild(projectFilePath, settings => 
    {
        settings.SetConfiguration(configuration)
            .WithTarget("Build")
            .WithProperty("Platform", "iPhone")
            .WithProperty("BuildIpa", "true")
            .WithProperty("OutputPath", buildResultDir + System.IO.Path.DirectorySeparatorChar)
            .WithProperty("TreatWarningsAsErrors", "false");
    });
    

    It's an interesting behavior though that it just randomly started to ignore the trailing Path.DirectorySeparatorChar :shrug: