VSTS Xamarin.iOS构建任务使用/ p定义多个常量:DefineConstants

时间:2018-04-11 12:13:51

标签: c# xamarin msbuild azure-devops conditional-compilation

我在VSTS中使用Xamarin.iOS构建任务来构建我的解决方案。 我想定义常量ENABLE_ANALYTICSENV_DEV

不幸的是,我无法弄清楚在Arguments输入字段中输入什么内容才能使其成功运行。我正在使用Hosted macOS Preview构建代理和msbuild (Visual Studio for Mac)构建工具。

我试过了:

/p:DefineConstants=ENABLE_ANALYTICS;ENV_DEV

  

MSBUILD:错误MSB1006:属性无效。

     

开关:ENV_DEV

/p:DefineConstants="ENABLE_ANALYTICS;ENV_DEV"

  

MSBUILD:错误MSB1006:属性无效。

     

开关:ENV_DEV

/p:DefineConstants='ENABLE_ANALYTICS;ENV_DEV'

  

MSBUILD:错误MSB1006:属性无效。

     

开关:ENV_DEV'

/p:DefineConstants=""ENABLE_ANALYTICS;ENV_DEV""

  

MSBUILD:错误MSB1006:属性无效。

     

开关:ENV_DEV

'/p:DefineConstants=""ENABLE_ANALYTICS;ENV_DEV"'

  

MSBUILD:错误MSB1008:只能指定一个项目。

     

切换:' / p:DefineConstants = ENABLE_ANALYTICS; ENV_DEV'

3 个答案:

答案 0 :(得分:0)

我认为你需要逃避分号:

/p:DefineConstants=ENABLE_ANALYTICS\;ENV_DEV

答案 1 :(得分:0)

我遇到了类似的问题,并且通过两次添加常量解决了它

/p:DefineConstants=ENABLE_ANALYTICS /p:DefineConstants=ENV_DEV

答案 2 :(得分:0)

问题的根本原因是构建脚本删除了所有双引号,除非它们被转义。转义算法似乎不是很简单。 That is the function doing that

for (var i=0; i < argString.length; i++) {
    var c = argString.charAt(i);

        if (c === '"') {
            if (!escaped) {
                inQuotes = !inQuotes;
            }
            else {
                append(c);
            }
            continue;
        }
                
        if (c === "\\" && inQuotes) {
            escaped = true;
            continue;
        }

        if (c === ' ' && !inQuotes) {
            if (arg.length > 0) {
            args.push(arg);
            arg = '';
        }
        continue;
    }
    append(c);
}

所以要在结果字符串中保留双引号,它应该如下所示:

/p:DefineConstants="\"A;B\"

当它用于 XamariniOS 任务时:

- task: XamariniOS@2
  inputs:
    ...
    args: '/p:DefineConstants="\"A;B\"'

作为奖励,这里有一个管道脚本示例,允许您通过“运行管道”UI 选择要包含的常量

run pipeline ui

parameters:
- name: ENABLE_DEBUG_ERROR_MESSAGES
  displayName: 'Enable debug error messages'
  type: boolean
  default: true
- name: ENABLE_MOCK_API_OPTION
  displayName: 'Enable mock API option'
  type: boolean
  default: true

trigger:
- develop

variables:
- ${{ each p in parameters }}:
  - name: "DEFINECONSTANT_${{p.key}}"
    value: ${{ p.value }}

pool:
  vmImage: 'macos-latest'

steps:
- pwsh: |
    $constantVars = Get-ChildItem -Path Env:\ | Where-Object Name -like "DEFINECONSTANT_ENABLE_*"
    $constantList = "/p:DefineConstants=`"\`""
    $constantVars | ForEach-Object {
      if ($_.Value -eq 'True') {
        $constantList += "$($_.Name.Replace('DEFINECONSTANT_', ''));"
      }
    }
    $constantList += "\`""
    Write-Host $constantList
    echo "##vso[task.setvariable variable=define]$constantList"

- bash: echo 'My pipeline variable is $(define)'

- task: XamariniOS@2
  inputs:
    solutionFile: 'YOUR_SOLUTION.sln'
    configuration: 'Release'
    packageApp: false
    buildForSimulator: true
    runNugetRestore: false
    args: '$(define)'

附言感谢 @WaitingForGuacamole 在 this post 中编写上述脚本的帮助。