简体   繁体   English

Xamarin.Forms项目无法在Azure Pipelines中生成

[英]Xamarin.Forms project fails to build in Azure Pipelines

I have a Xamarin.Forms project for Android that I can build/test/deploy/package without any errors locally and the App runs fine on my phone. 我有一个适用于Android的Xamarin.Forms项目,可以在本地构建/测试/部署/打包程序而不会出现任何错误,并且该应用程序可以在手机上正常运行。 Perfect! 完善!

Now I wanted to start using Azure DevOps Pipelines for CI, created a Xamarin Pipeline with the Wizard, started the Pipeline and it fails with a compilation error: 现在,我想开始使用Azure DevOps Pipelines for CI,使用向导创建Xamarin Pipeline,启动Pipeline,它失败并出现编译错误:

  /Users/vsts/agent/2.155.1/work/1/s/MyProject/MyService.cs(41,64): error CS1503: Argument 1: cannot convert from 'char' to 'string' [/Users/vsts/agent/2.155.1/work/1/s/MyProject/MyProject.Android.csproj]

Why does it build locally but not in the Pipeline? 为什么要在本地构建而不在管道中构建? The referenced code in the error message is the following function: 错误消息中引用的代码是以下功能:

var x = string.Join(',', nextStations);  // nextStations is IEnumerable<string>

I found out that the string.Join(char, IEnumerable<T>) function is only available in the .NET Core Framework but not in other versions like .NET for Xamarin.Android 7.1 - there is only a string.Join(string, IEnumerable<T>) function. 我发现string.Join(char, IEnumerable<T>)函数仅在.NET Core Framework中可用,而在其他版本(如Xamarin.Android 7.1的.NET)中不可用 -只有string.Join(string, IEnumerable<T>)函数。

Of course, I could now change all of my code to not using those functions only available in .net Core. 当然,我现在可以将所有代码更改为不使用仅.net Core中可用的那些函数。 Actually I tried this, but then the Azure Build failed because one of my referenced NuGet Packages is also using such a .Net Core-only string function so that linking the application failed in the Pipeline. 实际上,我尝试过此操作,但是随后Azure Build失败了,因为我引用的NuGet程序包之一也使用了此类.Net Core-only字符串函数,因此在管道中链接应用程序失败。 So this is not a solution. 因此,这不是解决方案。

So it seems that for whatever reason the Azure Pipeline tries to build my project against a different Framework. 因此,无论出于何种原因,Azure管道似乎都尝试根据其他框架构建我的项目。 Why? 为什么? Is there a way to configure this? 有没有一种配置方式? Or is it a bug in Azure DevOps? 还是Azure DevOps中的错误? Even when I take the msbuild command from the Pipelines log and execute it locally against my project, it runs without any errors. 即使当我从“管道”日志中获取msbuild命令并针对我的项目在本地执行该命令时,该命令也不会出现任何错误。 So why not in the pipeline? 那么为什么不准备推出呢?

msbuild /Users/vsts/agent/2.155.1/work/1/s/MyProject/MyProject.Android.csproj /t:PackageForAndroid /p:OutputPath=/Users/vsts/agent/2.155.1/work/1/b/Release /p:Configuration=Release

I guess this is the same problem as asked here: How to fix 'Error processing method: 'System.Void Prism.Navigation.PageNavigationService' error in Azure Pipelines But that question doesn't have a real answer (switching to Debug doesn't solve it here) and I found out more details, ie the different Framework versions. 我猜这与这里的问题相同: 如何修复Azure Pipelines中的“错误处理方法:'System.Void Prism.Navigation.PageNavigationService”错误,但该问题没有真正的答案(切换到Debug不会在这里解决),我发现了更多细节,即不同的Framework版本。

So any idea how to make the Pipeline build the project? 那么有什么想法如何使Pipeline构建项目吗?

Visual Studio 2019, Xamarin.Forms 4.2.0.778463, Android Target Framework v9.0 Visual Studio 2019,Xamarin.Forms 4.2.0.778463,Android目标框架v9.0

My azure-pipelines.yml file for reference: 我的azure-pipelines.yml文件供参考:

trigger:
- master

pool:
  vmImage: 'macos-latest'

variables:
  buildConfiguration: 'Release'
  outputDirectory: '$(build.binariesDirectory)/$(buildConfiguration)'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '**/*.sln'

- task: XamarinAndroid@1
  inputs:
    projectFile: '**/*droid*.csproj'
    outputDirectory: '$(outputDirectory)'
    configuration: '$(buildConfiguration)'

I'm not sure why it's building on your local machine, but if I had to guess it would be probably because you have some cached version of this code that was working fine at some point. 我不确定为什么要在您的本地计算机上构建它,但是如果我不得不猜测这可能是因为您有一些此版本的代码的缓存版本在某些时候运行良好。

Nevertheless, if you look at the docs for the string.Join() method (for NETStandard), you will see that there's no overload that takes char as the first parameter. 但是,如果您查看string.Join()方法(对于NETStandard)的文档 ,您将看到没有将char作为第一个参数的重载。 All of them take string . 他们全都带string Therefore what you need to do is to use double quotes "<your_string_separator>" , instead of singles ones '<your_char_separator>' . 因此,您需要使用双引号"<your_string_separator>"而不是单引号'<your_char_separator>'

I believe that your faulty line should look like this 我相信您的错误线路应如下所示

var x = string.Join(",", nextStations); // Notice that double quotes "", instead of single ones ``

EDIT : Apologies, I haven't read your entire question and I just realised that you're actually mentioning that you've checked string.Join() for the .NET Core. 编辑 :抱歉,我没有阅读您的整个问题,我只是意识到您实际上是在提到您已经检查了.NET Core的string.Join() However, this is the confusing part and you might have not realised this, the compatibility part of the .NET Core with Mono (Xamarin framework) is done via the NETStandard (see docs ) 但是,这是令人困惑的部分,您可能尚未意识到这一点,.NET Core与Mono的兼容性部分(Xamarin框架)是通过NETStandard完成的(请参阅docs

Compatible: .NET Core is compatible with .NET Framework, Xamarin and Mono, via .NET Standard. 兼容:.NET Core通过.NET Standard与.NET Framework,Xamarin和Mono兼容。

EDIT2 : More links EDIT2 :更多链接

Mono Compatibility in a nutshell -> https://www.mono-project.com/docs/about-mono/compatibility/ 简而言之,Mono兼容性-> https://www.mono-project.com/docs/about-mono/compatibility/

In depth post about the difference between Mono and .NET Core -> https://stackoverflow.com/a/39740592/510627 关于Mono和.NET Core之间差异的深入介绍-> https://stackoverflow.com/a/39740592/510627

I had the same issue a week ago and I found this . 一周前我遇到了同样的问题,我发现了这个问题 Cheking my pipeline logs I found the hosted MacOS was using mono version 5.12 so I added a step prior XamarinAndroid task where I set a newer version, this is my azure-pipelines.yaml file: 仔细检查我的管道日志,我发现托管的MacOS使用的是Mono版本5.12,因此我在XamarinAndroid任务之前添加了一个步骤,在其中设置了新版本,这是我的azure-pipelines.yaml文件:

trigger:
- master

pool:
  vmImage: 'macos-latest'

variables:
  buildConfiguration: 'Release'
  outputDirectory: '$(build.binariesDirectory)/$(buildConfiguration)'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '**/*.sln'
- task: Bash@3
  inputs:
    targetType: 'inline'
    script: |
      echo 'Selecting Mono version...'
      sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_18_1
- task: XamarinAndroid@1
  inputs:
    projectFile: '**/*Droid*.csproj'
    outputDirectory: '$(outputDirectory)'
    configuration: '$(buildConfiguration)'
- task: CopyFiles@2
  inputs:
    SourceFolder: '$(build.binariesDirectory)/$(buildConfiguration)'
    Contents: '*.apk'
    TargetFolder: '$(build.artifactstagingdirectory)'
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

You can find more information here and the versions of tooling here 您可以在此处找到更多信息以及此处的工具版本

Regards! 问候!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM